-
Notifications
You must be signed in to change notification settings - Fork 4
/
mesh.go
103 lines (90 loc) · 2.21 KB
/
mesh.go
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
package main
import (
"fmt"
"path"
)
type UV struct {
U, V float32
}
type Face struct {
VertexIndices [3]int
NormalIndices [3]int
UVs [3]UV
Texture *Texture
}
type Mesh struct {
Name string
Vertices []Vec4
VertexNormals []Vec4
FaceNormals []Vec4
BoundingBox [8]Vec4
Faces []Face
}
func boundingBox(vertices []Vec4) [8]Vec4 {
minX, minY, minZ := vertices[0].X, vertices[0].Y, vertices[0].Z
maxX, maxY, maxZ := minX, minY, minZ
for _, v := range vertices {
minX = min(minX, v.X)
minY = min(minY, v.Y)
minZ = min(minZ, v.Z)
maxX = max(maxX, v.X)
maxY = max(maxY, v.Y)
maxZ = max(maxZ, v.Z)
}
return [8]Vec4{
{minX, minY, minZ, 1},
{minX, minY, maxZ, 1},
{minX, maxY, minZ, 1},
{minX, maxY, maxZ, 1},
{maxX, minY, minZ, 1},
{maxX, minY, maxZ, 1},
{maxX, maxY, minZ, 1},
{maxX, maxY, maxZ, 1},
}
}
func NewMesh(vertices []Vec4, vertexNormals []Vec4, faces []Face) *Mesh {
faceNormals := make([]Vec4, len(faces))
for i := range faces {
v0 := vertices[faces[i].VertexIndices[0]].ToVec3()
v1 := vertices[faces[i].VertexIndices[1]].ToVec3()
v2 := vertices[faces[i].VertexIndices[2]].ToVec3()
faceNormals[i] = v1.Sub(v0).CrossProduct(v2.Sub(v0)).Normalize().ToVec4()
}
return &Mesh{
Faces: faces,
Vertices: vertices,
VertexNormals: vertexNormals,
FaceNormals: faceNormals,
BoundingBox: boundingBox(vertices),
}
}
type Object struct {
*Mesh
Rotation Vec3
Translation Vec3
Scale Vec3
TransformedVertices []Vec4
WorldVertexNormals []Vec4
WorldFaceNormals []Vec4
}
func NewObject(mesh *Mesh) *Object {
return &Object{
Mesh: mesh,
Scale: Vec3{1, 1, 1},
TransformedVertices: make([]Vec4, len(mesh.Vertices)),
WorldFaceNormals: make([]Vec4, len(mesh.FaceNormals)),
WorldVertexNormals: make([]Vec4, len(mesh.VertexNormals)),
}
}
func LoadMeshFile(filename string, singleMesh bool) (meshes []*Mesh, err error) {
switch ext := path.Ext(filename); ext {
case ".obj":
meshes, err = LoadObjFile(filename, singleMesh)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported mesh format: %s", ext)
}
return meshes, nil
}