-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmesh.go
More file actions
101 lines (89 loc) · 3.07 KB
/
mesh.go
File metadata and controls
101 lines (89 loc) · 3.07 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
package MeshTypes
import (
"fmt"
)
type Mesh struct {
Triangles []Triangle
}
func (obj *Mesh) AddTriangle(triangle Triangle) {
obj.Triangles = append(obj.Triangles, triangle)
}
func (obj *Mesh) Copy() Mesh {
triangles := make([]Triangle, len(obj.Triangles))
copy(triangles, obj.Triangles)
return Mesh{Triangles: triangles}
}
func (obj *Mesh) Add(mesh ...*Mesh) *Mesh {
for _, element := range mesh {
if element != nil {
obj.Triangles = append(obj.Triangles, element.Triangles...)
}
}
return obj
}
func (obj *Mesh) RotateAndTranslate(translationMatrix Matrix) {
for triangle_id := range obj.Triangles {
obj.Triangles[triangle_id].V0.Position = translationMatrix.MulPosition(obj.Triangles[triangle_id].V0.Position)
obj.Triangles[triangle_id].V1.Position = translationMatrix.MulPosition(obj.Triangles[triangle_id].V1.Position)
obj.Triangles[triangle_id].V2.Position = translationMatrix.MulPosition(obj.Triangles[triangle_id].V2.Position)
if obj.Triangles[triangle_id].V0.Normal != nil {
n0 := translationMatrix.MulDirection(*obj.Triangles[triangle_id].V0.Normal)
obj.Triangles[triangle_id].V0.Normal = &n0
}
if obj.Triangles[triangle_id].V1.Normal != nil {
n1 := translationMatrix.MulDirection(*obj.Triangles[triangle_id].V1.Normal)
obj.Triangles[triangle_id].V1.Normal = &n1
}
if obj.Triangles[triangle_id].V2.Normal != nil {
n2 := translationMatrix.MulDirection(*obj.Triangles[triangle_id].V2.Normal)
obj.Triangles[triangle_id].V2.Normal = &n2
}
}
}
func (obj *Mesh) CalculateBoundingBox() Vector {
// init with first triangle to prohibit 0 values being min or max
if len(obj.Triangles) == 0 {
return Vector{}
}
min := obj.Triangles[0].V0.Position
max := obj.Triangles[0].V0.Position
for _, triangle := range obj.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)
}
return Vector{
X: max.X - min.X,
Y: max.Y - min.Y,
Z: max.Z - min.Z,
}
}
func (obj *Mesh) Scale(scaling Vector) error {
scaledVectors := make(map[Vertex]struct{})
for triangle_id, triangle := range obj.Triangles {
if _, exists := scaledVectors[triangle.V0]; !exists {
obj.Triangles[triangle_id].V0.Position = triangle.V0.Position.Mult(scaling)
scaledVectors[obj.Triangles[triangle_id].V0] = struct{}{}
}
if _, exists := scaledVectors[triangle.V1]; !exists {
obj.Triangles[triangle_id].V1.Position = triangle.V1.Position.Mult(scaling)
scaledVectors[obj.Triangles[triangle_id].V1] = struct{}{}
}
if _, exists := scaledVectors[triangle.V2]; !exists {
obj.Triangles[triangle_id].V2.Position = triangle.V2.Position.Mult(scaling)
scaledVectors[obj.Triangles[triangle_id].V2] = struct{}{}
}
}
return nil
}
func (obj *Mesh) ScaleToDimensions(desiredSize *Vector) error {
actual := obj.CalculateBoundingBox()
if actual.X == 0 && actual.Y == 0 && actual.Z == 0 {
return fmt.Errorf("invalid Mesh with 0 dimension")
}
scaling := desiredSize.Div(actual)
return obj.Scale(scaling)
}