-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtransform.go
153 lines (123 loc) · 3.62 KB
/
transform.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package three
import (
"github.com/go-gl/mathgl/mgl32"
)
// Transform stores information about the position, rotation and scale
// of an 3D object.
type Transform struct {
position mgl32.Vec3
rotation mgl32.Vec3
quaternion mgl32.Quat
scale mgl32.Vec3
Up mgl32.Vec3
Right mgl32.Vec3
Forward mgl32.Vec3
matrix mgl32.Mat4
}
// NewTransform creates a new Transform struct with defaults.
// The given multiplier can be used to invert the matrix, e.g. camera matrix
// This value should be 1 or -1 (inverted).
//
// Position: 0,0,0
// Rotation: 0,0,0
// Scale: 1,1,1
//
// Up: 0,1,0
// Right: 1,0,0
// Forward: 0,0,-1
func NewTransform() *Transform {
return &Transform{
position: mgl32.Vec3{0, 0, 0},
rotation: mgl32.Vec3{0, 0, 0},
quaternion: mgl32.QuatIdent(),
scale: mgl32.Vec3{1, 1, 1},
Up: mgl32.Vec3{0, 1, 0},
Right: mgl32.Vec3{1, 0, 0},
Forward: mgl32.Vec3{0, 0, -1},
matrix: mgl32.Ident4(),
}
}
// SetPosition sets the position of the 3D object
// and updates it's matrix accordingly.
func (t *Transform) SetPosition(x, y, z float32) {
t.position = mgl32.Vec3{x, y, z}
t.matrix[12] = x
t.matrix[13] = y
t.matrix[14] = z
}
// TranslateX moves the object along the x axis by the given units.
// The model matrix is updated accordingly.
func (t *Transform) TranslateX(x float32) {
t.position[0] += x
t.matrix[12] = t.position[0]
}
// TranslateY moves the object along the y axis by the given units.
// The model matrix is updated accordingly.
func (t *Transform) TranslateY(y float32) {
t.position[1] += y
t.matrix[13] = t.position[1]
}
// TranslateZ moves the object along the z axis by the given units.
// The model matrix is updated accordingly.
func (t *Transform) TranslateZ(z float32) {
t.position[2] += z
t.matrix[14] = t.position[2]
}
// Translate moves the object by the given vector.
// The model matrix is updated accordingly.
func (t *Transform) Translate(v mgl32.Vec3) {
t.position = t.position.Add(v)
t.matrix[12] = t.position[0]
t.matrix[13] = t.position[1]
t.matrix[14] = t.position[2]
}
// Scale sets the scale factor of the 3D object to the given values
// and updates it's matrix accordingly.
func (t *Transform) Scale(x, y, z float32) {
t.scale = mgl32.Vec3{x, y, z}
t.matrix[0] = x
t.matrix[5] = y
t.matrix[10] = z
}
// RotateX rotates the 3D object by the given angle (in radians) around the x axis.
// The model matrix is updated accordingly.
func (t *Transform) RotateX(angle float32) {
t.rotation[0] += angle
v1 := mgl32.Vec3{1, 0, 0}
t.rotateOnAxis(v1, angle)
}
// RotateY rotates the 3D object by the given angle (in radians) around the x axis.
// The model matrix is updated accordingly.
func (t *Transform) RotateY(angle float32) {
t.rotation[1] += angle
v1 := mgl32.Vec3{0, 1, 0}
t.rotateOnAxis(v1, angle)
}
// RotateZ rotates the 3D object by the given angle (in radians) around the x axis.
// The model matrix is updated accordingly.
func (t *Transform) RotateZ(angle float32) {
t.rotation[2] += angle
v1 := mgl32.Vec3{0, 0, 1}
t.rotateOnAxis(v1, angle)
}
func (t *Transform) rotateOnAxis(axis mgl32.Vec3, angle float32) {
q1 := mgl32.QuatRotate(angle, axis)
t.quaternion = t.quaternion.Mul(q1)
t.matrix = t.matrix.Mul4(q1.Mat4())
}
// LookAt changes the transformation of the 3D object
// to face the target's position. The model matrix
// will be updated accordingly.
//
// Note: This transformation makes use of the up vector.
func (t *Transform) LookAt(x, y, z float32) {
target := mgl32.Vec3{x, y, z}
t.matrix = mgl32.LookAtV(
t.position,
target,
t.Up,
).Inv()
}
func (t *Transform) modelMatrix() mgl32.Mat4 {
return t.matrix
}