-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodel_manipulation.go
More file actions
106 lines (87 loc) · 3.33 KB
/
model_manipulation.go
File metadata and controls
106 lines (87 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package rasterizer
import (
"math"
"github.com/Patch2PDF/GDTF-Mesh-Reader/v2/pkg/MeshTypes"
MVRTypes "github.com/Patch2PDF/MVR-Parser/pkg/types"
)
type StageModel = MVRTypes.StageModel
func rotateAndTranslateStageModel(stageModel *StageModel, matrix MeshTypes.Matrix) {
for scene_object_id := range stageModel.SceneObjectModels {
scene_object := &stageModel.SceneObjectModels[scene_object_id]
for part_id := range scene_object.MeshModel {
(&scene_object.MeshModel[part_id].Mesh).RotateAndTranslate(matrix)
}
for geometry_id := range scene_object.Geometries {
(&scene_object.Geometries[geometry_id]).RotateAndTranslate(matrix)
}
}
for fixture_id := range stageModel.FixtureModels {
fixture := &stageModel.FixtureModels[fixture_id]
for part_id := range fixture.MeshModel {
(&fixture.MeshModel[part_id].Mesh).RotateAndTranslate(matrix)
}
for geometry_id := range fixture.Geometries {
(&fixture.Geometries[geometry_id]).RotateAndTranslate(matrix)
}
}
}
func updateMeshMinAndMax(mesh MeshTypes.Mesh, min *MeshTypes.Vector, max *MeshTypes.Vector) {
for _, triangle := range mesh.Triangles {
*min = triangle.V0.Position.Min(*min)
*max = triangle.V0.Position.Max(*max)
*min = triangle.V1.Position.Min(*min)
*max = triangle.V1.Position.Max(*max)
*min = triangle.V2.Position.Min(*min)
*max = triangle.V2.Position.Max(*max)
}
}
func calculateStageModelMinAndMax(stageModel *StageModel) (min MeshTypes.Vector, max MeshTypes.Vector) {
min = MeshTypes.Vector{X: math.Inf(1), Y: math.Inf(1), Z: math.Inf(1)}
max = MeshTypes.Vector{X: math.Inf(-1), Y: math.Inf(-1), Z: math.Inf(-1)}
for _, scene_object := range stageModel.SceneObjectModels {
for _, part := range scene_object.MeshModel {
updateMeshMinAndMax(part.Mesh, &min, &max)
}
for _, geometry := range scene_object.Geometries {
updateMeshMinAndMax(geometry, &min, &max)
}
}
for _, fixture := range stageModel.FixtureModels {
for _, part := range fixture.MeshModel {
updateMeshMinAndMax(part.Mesh, &min, &max)
}
for _, geometry := range fixture.Geometries {
updateMeshMinAndMax(geometry, &min, &max)
}
}
return min, max
}
func normalizeAndRotateStageModel(canvas *Canvas, stageModel *StageModel, rotationMatrix MeshTypes.Matrix) {
// rotate
rotateAndTranslateStageModel(stageModel, rotationMatrix)
// get bounding box
min, max := calculateStageModelMinAndMax(stageModel)
// offset calculation for centering
sum := min.Add(max)
offset := sum.DivScalar(-2)
centeringMatrix := MeshTypes.IdentityMatrix()
centeringMatrix.X03 = centeringMatrix.X03 + offset.X
centeringMatrix.X13 = centeringMatrix.X13 + offset.Y
centeringMatrix.X23 = centeringMatrix.X23 + offset.Z
theoretical_min := centeringMatrix.MulPosition(min)
theoretical_max := centeringMatrix.MulPosition(max)
width := float64(canvas.width - 1)
height := float64(canvas.height - 1)
// normalizing to canvas dimensions
// NOTE: stagemodel coordinate system is z for up and x for right position
visualWidth := theoretical_max.X - theoretical_min.X
visualHeight := math.Abs(theoretical_max.Z - theoretical_min.Z)
scale := width / visualWidth
if scale*visualHeight > height {
scale = height / visualHeight
}
centeringMatrix = centeringMatrix.MulScalar(scale)
centeringMatrix.X03 += width / 2
centeringMatrix.X23 -= height / 2
rotateAndTranslateStageModel(stageModel, centeringMatrix)
}