mirror of
https://github.com/bloeys/gglm.git
synced 2025-12-29 13:38:20 +00:00
Start quaternions and transform matrix
This commit is contained in:
7
gglm/constants.go
Executable file
7
gglm/constants.go
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
package gglm
|
||||||
|
|
||||||
|
const (
|
||||||
|
Pi float32 = 3.14159265359
|
||||||
|
Deg2Rad float32 = Pi / 180
|
||||||
|
Rad2Deg float32 = 180 / Pi
|
||||||
|
)
|
||||||
63
gglm/quat.go
Executable file
63
gglm/quat.go
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
package gglm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Swizzle4 = &Quat{}
|
||||||
|
var _ fmt.Stringer = &Quat{}
|
||||||
|
|
||||||
|
type Quat struct {
|
||||||
|
Vec4
|
||||||
|
}
|
||||||
|
|
||||||
|
//Euler takes rotations in radians and produces a rotation that
|
||||||
|
//rotates around the z-axis, y-axis and lastly x-axis.
|
||||||
|
func NewQuatEuler(v *Vec3) *Quat {
|
||||||
|
|
||||||
|
//Some other common terminology: x=roll, y=pitch, z=yaw
|
||||||
|
sinX, cosX := Sincos32(v.Data[0] * 0.5)
|
||||||
|
sinY, cosY := Sincos32(v.Data[1] * 0.5)
|
||||||
|
sinZ, cosZ := Sincos32(v.Data[2] * 0.5)
|
||||||
|
|
||||||
|
//This produces a z->y->x multiply order, but its written as XYZ.
|
||||||
|
//This is due to XYZ meaning independent rotation matrices, so Z is applied
|
||||||
|
//first, then Y matrix and lastly X.
|
||||||
|
//See this for more info: https://github.com/godotengine/godot/issues/6816#issuecomment-254592170
|
||||||
|
//
|
||||||
|
//Note: On most conversion tools putting the multiply order (e.g. ZYX for us) is required.
|
||||||
|
return &Quat{
|
||||||
|
Vec4: Vec4{
|
||||||
|
Data: [4]float32{
|
||||||
|
sinX*cosY*cosZ - cosX*sinY*sinZ,
|
||||||
|
cosX*sinY*cosZ + sinX*cosY*sinZ,
|
||||||
|
cosX*cosY*sinZ - sinX*sinY*cosZ,
|
||||||
|
cosX*cosY*cosZ + sinX*sinY*sinZ,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//AngleAxis rotates rotRad radians around the *normalized* vector rotAxisNorm
|
||||||
|
func NewQuatAngleAxis(rotRad float32, rotAxisNorm *Vec3) *Quat {
|
||||||
|
|
||||||
|
s, c := Sincos32(rotRad * 0.5)
|
||||||
|
return &Quat{
|
||||||
|
Vec4: Vec4{
|
||||||
|
Data: [4]float32{
|
||||||
|
rotAxisNorm.Data[0] * s,
|
||||||
|
rotAxisNorm.Data[1] * s,
|
||||||
|
rotAxisNorm.Data[2] * s,
|
||||||
|
c,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuatId() *Quat {
|
||||||
|
return &Quat{
|
||||||
|
Vec4: Vec4{
|
||||||
|
Data: [4]float32{0, 0, 0, 1},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,3 +14,16 @@ func EqF32(f1, f2 float32) bool {
|
|||||||
func EqF32Epsilon(f1, f2, eps float32) bool {
|
func EqF32Epsilon(f1, f2, eps float32) bool {
|
||||||
return math.Abs(float64(f1-f2)) <= float64(eps)
|
return math.Abs(float64(f1-f2)) <= float64(eps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Sin32(x float32) float32 {
|
||||||
|
return float32(math.Sin(float64(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Cos32(x float32) float32 {
|
||||||
|
return float32(math.Cos(float64(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sincos32(x float32) (sinx, cosx float32) {
|
||||||
|
a, b := math.Sincos(float64(x))
|
||||||
|
return float32(a), float32(b)
|
||||||
|
}
|
||||||
|
|||||||
67
gglm/transform.go
Executable file
67
gglm/transform.go
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
package gglm
|
||||||
|
|
||||||
|
//TMat is the 4x4 transformation matrix
|
||||||
|
// type TMat struct {
|
||||||
|
// Mat4
|
||||||
|
// }
|
||||||
|
|
||||||
|
func GenTranslationMat(v *Vec3) *Mat4 {
|
||||||
|
return &Mat4{
|
||||||
|
Data: [16]float32{
|
||||||
|
1, 0, 0, v.Data[0],
|
||||||
|
0, 1, 0, v.Data[1],
|
||||||
|
0, 0, 1, v.Data[2],
|
||||||
|
0, 0, 0, 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenScaleMat(v *Vec3) *Mat4 {
|
||||||
|
return &Mat4{
|
||||||
|
Data: [16]float32{
|
||||||
|
v.Data[0], 0, 0, 0,
|
||||||
|
0, v.Data[1], 0, 0,
|
||||||
|
0, 0, v.Data[2], 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenRotationMat(q *Quat) *Mat4 {
|
||||||
|
|
||||||
|
xy := q.Data[0] * q.Data[1]
|
||||||
|
xz := q.Data[0] * q.Data[2]
|
||||||
|
xw := q.Data[0] * q.Data[3]
|
||||||
|
|
||||||
|
yz := q.Data[1] * q.Data[2]
|
||||||
|
yw := q.Data[1] * q.Data[3]
|
||||||
|
|
||||||
|
zw := q.Data[2] * q.Data[3]
|
||||||
|
|
||||||
|
xx := q.Data[0] * q.Data[0]
|
||||||
|
yy := q.Data[1] * q.Data[1]
|
||||||
|
zz := q.Data[2] * q.Data[2]
|
||||||
|
ww := q.Data[3] * q.Data[3]
|
||||||
|
|
||||||
|
return &Mat4{
|
||||||
|
Data: [16]float32{
|
||||||
|
xx + yy - zz - ww, 2 * (yz - xw), 2 * (xz + yw), 0,
|
||||||
|
2 * (xw + yz), xx - yy + zz - ww, 2 * (zw - xy), 0,
|
||||||
|
2 * (yw - xz), 2 * (xy + zw), xx - yy - zz + ww, 0,
|
||||||
|
0, 0, 0, 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func NewTMatId() *TMat {
|
||||||
|
// return &TMat{
|
||||||
|
// Mat4: Mat4{
|
||||||
|
// Data: [16]float32{
|
||||||
|
// 1, 0, 0, 0,
|
||||||
|
// 0, 1, 0, 0,
|
||||||
|
// 0, 0, 1, 0,
|
||||||
|
// 0, 0, 0, 1,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// }
|
||||||
15
gglm/vec3.go
15
gglm/vec3.go
@ -105,11 +105,24 @@ func (v *Vec3) Set(x, y, z float32) {
|
|||||||
v.Data[2] = z
|
v.Data[2] = z
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec3) Normalize() {
|
//Normalize normalizes this vector and returns it (doesn't copy)
|
||||||
|
func (v *Vec3) Normalize() *Vec3 {
|
||||||
mag := float32(math.Sqrt(float64(v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z())))
|
mag := float32(math.Sqrt(float64(v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z())))
|
||||||
v.Data[0] /= mag
|
v.Data[0] /= mag
|
||||||
v.Data[1] /= mag
|
v.Data[1] /= mag
|
||||||
v.Data[2] /= mag
|
v.Data[2] /= mag
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) AsRad() *Vec3 {
|
||||||
|
return &Vec3{
|
||||||
|
Data: [3]float32{
|
||||||
|
v.Data[0] * Deg2Rad,
|
||||||
|
v.Data[1] * Deg2Rad,
|
||||||
|
v.Data[2] * Deg2Rad,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//AddVec3 v3 = v1 + v2
|
//AddVec3 v3 = v1 + v2
|
||||||
|
|||||||
14
main.go
14
main.go
@ -118,12 +118,22 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec3A := gglm.Vec3{Data: [3]float32{1, 2, 3}}
|
vec3A := gglm.Vec3{Data: [3]float32{1, 2, 3}}
|
||||||
lol := gglm.MulMat3Vec3(&mat3A, &vec3A)
|
mm3v3 := gglm.MulMat3Vec3(&mat3A, &vec3A)
|
||||||
println(lol.String())
|
println(mm3v3.String())
|
||||||
|
|
||||||
//ReflectVec2
|
//ReflectVec2
|
||||||
vec2B := &gglm.Vec2{Data: [2]float32{4, 5}}
|
vec2B := &gglm.Vec2{Data: [2]float32{4, 5}}
|
||||||
normA := &gglm.Vec2{Data: [2]float32{0, 1}}
|
normA := &gglm.Vec2{Data: [2]float32{0, 1}}
|
||||||
rVec2A := gglm.ReflectVec2(vec2B, normA)
|
rVec2A := gglm.ReflectVec2(vec2B, normA)
|
||||||
println(rVec2A.String())
|
println(rVec2A.String())
|
||||||
|
|
||||||
|
//Quaternion
|
||||||
|
vRot := &gglm.Vec3{Data: [3]float32{60, 30, 20}}
|
||||||
|
q := gglm.NewQuatEuler(vRot.AsRad())
|
||||||
|
println("\n" + vRot.AsRad().String())
|
||||||
|
println(q.String(), "\n", q.Mag())
|
||||||
|
|
||||||
|
q = gglm.NewQuatAngleAxis(60*gglm.Deg2Rad, vRot.Normalize())
|
||||||
|
println("\n" + vRot.Normalize().String())
|
||||||
|
println(q.String())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user