mirror of
https://github.com/bloeys/gglm.git
synced 2025-12-29 13:38:20 +00:00
NewXYZ funcs for Quat+github workflows
This commit is contained in:
21
.github/workflows/test-gglm.yml
vendored
Executable file
21
.github/workflows/test-gglm.yml
vendored
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
name: test-gglm
|
||||||
|
|
||||||
|
on:
|
||||||
|
create:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-gglm:
|
||||||
|
runs-on: [windows-latest, macos-latest, ubuntu-latest]
|
||||||
|
steps:
|
||||||
|
- name: Install golang
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: ">=1.17"
|
||||||
|
|
||||||
|
- name: Clone gglm
|
||||||
|
run: git clone https://github.com/bloeys/gglm
|
||||||
|
|
||||||
|
- name: Test gglm
|
||||||
|
working-directory: nmage
|
||||||
|
run: cd gglm && go test ./... -v
|
||||||
68
gglm/quat.go
68
gglm/quat.go
@ -47,36 +47,15 @@ func (q *Quat) Axis() Vec3 {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Euler takes rotations in radians and produces a rotation that
|
// NewQuatEulerVec takes rotations in radians and produces a rotation that
|
||||||
// rotates around the z-axis, y-axis and lastly x-axis.
|
// rotates around the z-axis, y-axis and lastly x-axis.
|
||||||
func NewQuatEuler(v *Vec3) Quat {
|
func NewQuatEulerVec(v *Vec3) Quat {
|
||||||
|
return NewQuatEuler(v.X(), v.Y(), v.Z())
|
||||||
//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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Euler takes rotations in radians and produces a rotation that
|
// NewQuatEuler takes rotations in radians and produces a rotation that
|
||||||
// rotates around the z-axis, y-axis and lastly x-axis.
|
// rotates around the z-axis, y-axis and lastly x-axis.
|
||||||
func NewQuatEulerXYZ(x, y, z float32) Quat {
|
func NewQuatEuler(x, y, z float32) Quat {
|
||||||
|
|
||||||
//Some other common terminology: x=roll, y=pitch, z=yaw
|
//Some other common terminology: x=roll, y=pitch, z=yaw
|
||||||
sinX, cosX := Sincos32(x * 0.5)
|
sinX, cosX := Sincos32(x * 0.5)
|
||||||
@ -101,16 +80,21 @@ func NewQuatEulerXYZ(x, y, z float32) Quat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewQuatAngleAxisVec produces a quaternion thats rotates rotRad radians around the *normalized* vector rotAxisNorm
|
||||||
|
func NewQuatAngleAxisVec(rotRad float32, rotAxisNorm *Vec3) Quat {
|
||||||
|
return NewQuatAngleAxis(rotRad, rotAxisNorm.X(), rotAxisNorm.Y(), rotAxisNorm.Z())
|
||||||
|
}
|
||||||
|
|
||||||
// NewQuatAngleAxis produces a quaternion thats rotates rotRad radians around the *normalized* vector rotAxisNorm
|
// NewQuatAngleAxis produces a quaternion thats rotates rotRad radians around the *normalized* vector rotAxisNorm
|
||||||
func NewQuatAngleAxis(rotRad float32, rotAxisNorm *Vec3) Quat {
|
func NewQuatAngleAxis(rotRad float32, rotAxisNormX, rotAxisNormY, rotAxisNormZ float32) Quat {
|
||||||
|
|
||||||
s, c := Sincos32(rotRad * 0.5)
|
s, c := Sincos32(rotRad * 0.5)
|
||||||
return Quat{
|
return Quat{
|
||||||
Vec4: Vec4{
|
Vec4: Vec4{
|
||||||
Data: [4]float32{
|
Data: [4]float32{
|
||||||
rotAxisNorm.Data[0] * s,
|
rotAxisNormX * s,
|
||||||
rotAxisNorm.Data[1] * s,
|
rotAxisNormY * s,
|
||||||
rotAxisNorm.Data[2] * s,
|
rotAxisNormZ * s,
|
||||||
c,
|
c,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -124,3 +108,27 @@ func NewQuatId() Quat {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewQuat(x, y, z, w float32) Quat {
|
||||||
|
return Quat{
|
||||||
|
Vec4: Vec4{
|
||||||
|
Data: [4]float32{x, y, z, w},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuatArr(arr [4]float32) Quat {
|
||||||
|
return Quat{
|
||||||
|
Vec4: Vec4{
|
||||||
|
Data: arr,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuatVec(v *Vec4) Quat {
|
||||||
|
return Quat{
|
||||||
|
Vec4: Vec4{
|
||||||
|
Data: v.Data,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -10,14 +10,14 @@ func TestNewQuatEuler(t *testing.T) {
|
|||||||
|
|
||||||
degs := gglm.NewVec3(180, 180, 180)
|
degs := gglm.NewVec3(180, 180, 180)
|
||||||
degs.Data = degs.AsRad().Data
|
degs.Data = degs.AsRad().Data
|
||||||
q := gglm.NewQuatEuler(°s)
|
q := gglm.NewQuatEulerVec(°s)
|
||||||
ans := &gglm.Quat{Vec4: gglm.NewVec4(0, 0, 0, 1)}
|
ans := &gglm.Quat{Vec4: gglm.NewVec4(0, 0, 0, 1)}
|
||||||
|
|
||||||
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
|
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
|
||||||
t.Errorf("Got: %v; Expected: %v", q.String(), ans.String())
|
t.Errorf("Got: %v; Expected: %v", q.String(), ans.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
q = gglm.NewQuatEulerXYZ(180*gglm.Deg2Rad, 180*gglm.Deg2Rad, 180*gglm.Deg2Rad)
|
q = gglm.NewQuatEuler(180*gglm.Deg2Rad, 180*gglm.Deg2Rad, 180*gglm.Deg2Rad)
|
||||||
|
|
||||||
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
|
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
|
||||||
t.Errorf("Got: %v; Expected: %v", q.String(), ans.String())
|
t.Errorf("Got: %v; Expected: %v", q.String(), ans.String())
|
||||||
@ -27,7 +27,7 @@ func TestNewQuatEuler(t *testing.T) {
|
|||||||
func TestNewQuatAngleAxis(t *testing.T) {
|
func TestNewQuatAngleAxis(t *testing.T) {
|
||||||
|
|
||||||
rotAxis := gglm.NewVec3(0, 1, 0)
|
rotAxis := gglm.NewVec3(0, 1, 0)
|
||||||
q := gglm.NewQuatAngleAxis(180*gglm.Deg2Rad, &rotAxis)
|
q := gglm.NewQuatAngleAxisVec(180*gglm.Deg2Rad, &rotAxis)
|
||||||
ans := &gglm.Quat{Vec4: gglm.NewVec4(0, 1, 0, 0)}
|
ans := &gglm.Quat{Vec4: gglm.NewVec4(0, 1, 0, 0)}
|
||||||
|
|
||||||
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
|
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
|
||||||
@ -38,7 +38,7 @@ func TestNewQuatAngleAxis(t *testing.T) {
|
|||||||
func TestQuatAngle(t *testing.T) {
|
func TestQuatAngle(t *testing.T) {
|
||||||
|
|
||||||
rotAxis := gglm.NewVec3(0, 1, 0)
|
rotAxis := gglm.NewVec3(0, 1, 0)
|
||||||
quat := gglm.NewQuatAngleAxis(180*gglm.Deg2Rad, &rotAxis)
|
quat := gglm.NewQuatAngleAxisVec(180*gglm.Deg2Rad, &rotAxis)
|
||||||
a := quat.Angle()
|
a := quat.Angle()
|
||||||
var ans float32 = 180.0 * gglm.Deg2Rad
|
var ans float32 = 180.0 * gglm.Deg2Rad
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func TestQuatAngle(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rotAxis = gglm.NewVec3(1, 1, 0)
|
rotAxis = gglm.NewVec3(1, 1, 0)
|
||||||
quat = gglm.NewQuatAngleAxis(90*gglm.Deg2Rad, rotAxis.Normalize())
|
quat = gglm.NewQuatAngleAxisVec(90*gglm.Deg2Rad, rotAxis.Normalize())
|
||||||
a = quat.Angle()
|
a = quat.Angle()
|
||||||
ans = 90 * gglm.Deg2Rad
|
ans = 90 * gglm.Deg2Rad
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ func TestQuatAngle(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rotAxis = gglm.NewVec3(1, 1, 0)
|
rotAxis = gglm.NewVec3(1, 1, 0)
|
||||||
quat = gglm.NewQuatAngleAxis(125*gglm.Deg2Rad, rotAxis.Normalize())
|
quat = gglm.NewQuatAngleAxisVec(125*gglm.Deg2Rad, rotAxis.Normalize())
|
||||||
a = quat.Angle()
|
a = quat.Angle()
|
||||||
ans = 125 * gglm.Deg2Rad
|
ans = 125 * gglm.Deg2Rad
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func TestQuatAngle(t *testing.T) {
|
|||||||
func TestQuatAxis(t *testing.T) {
|
func TestQuatAxis(t *testing.T) {
|
||||||
|
|
||||||
rotAxis := gglm.NewVec3(0, 1, 0)
|
rotAxis := gglm.NewVec3(0, 1, 0)
|
||||||
quat := gglm.NewQuatAngleAxis(1, &rotAxis)
|
quat := gglm.NewQuatAngleAxisVec(1, &rotAxis)
|
||||||
a := quat.Axis()
|
a := quat.Axis()
|
||||||
ans := gglm.NewVec3(0, 1, 0)
|
ans := gglm.NewVec3(0, 1, 0)
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ func TestQuatAxis(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rotAxis = gglm.NewVec3(1, 1, 0)
|
rotAxis = gglm.NewVec3(1, 1, 0)
|
||||||
quat = gglm.NewQuatAngleAxis(1, rotAxis.Normalize())
|
quat = gglm.NewQuatAngleAxisVec(1, rotAxis.Normalize())
|
||||||
a = quat.Axis()
|
a = quat.Axis()
|
||||||
ans = gglm.NewVec3(1, 1, 0)
|
ans = gglm.NewVec3(1, 1, 0)
|
||||||
ans.Normalize()
|
ans.Normalize()
|
||||||
@ -87,7 +87,7 @@ func TestQuatAxis(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rotAxis = gglm.NewVec3(67, 46, 32)
|
rotAxis = gglm.NewVec3(67, 46, 32)
|
||||||
quat = gglm.NewQuatAngleAxis(1, rotAxis.Normalize())
|
quat = gglm.NewQuatAngleAxisVec(1, rotAxis.Normalize())
|
||||||
a = quat.Axis()
|
a = quat.Axis()
|
||||||
ans = gglm.NewVec3(67, 46, 32)
|
ans = gglm.NewVec3(67, 46, 32)
|
||||||
ans.Normalize()
|
ans.Normalize()
|
||||||
|
|||||||
@ -209,7 +209,7 @@ func TestVecSwizzleSet(t *testing.T) {
|
|||||||
// Test rot by quat
|
// Test rot by quat
|
||||||
v32.SetXY(1, 0)
|
v32.SetXY(1, 0)
|
||||||
rotAxis := gglm.NewVec3(0, 1, 0)
|
rotAxis := gglm.NewVec3(0, 1, 0)
|
||||||
quat := gglm.NewQuatAngleAxis(90*gglm.Deg2Rad, &rotAxis)
|
quat := gglm.NewQuatAngleAxisVec(90*gglm.Deg2Rad, &rotAxis)
|
||||||
v32.RotByQuat(&quat)
|
v32.RotByQuat(&quat)
|
||||||
angleV3 = gglm.AngleVec3(&v3, &v32) * gglm.Rad2Deg
|
angleV3 = gglm.AngleVec3(&v3, &v32) * gglm.Rad2Deg
|
||||||
if angleV3 != 90 {
|
if angleV3 != 90 {
|
||||||
|
|||||||
10
main.go
10
main.go
@ -143,11 +143,11 @@ func main() {
|
|||||||
|
|
||||||
// Quaternion
|
// Quaternion
|
||||||
vRot := &gglm.Vec3{Data: [3]float32{60, 30, 20}}
|
vRot := &gglm.Vec3{Data: [3]float32{60, 30, 20}}
|
||||||
q := gglm.NewQuatEuler(vRot.AsRad())
|
q := gglm.NewQuatEulerVec(vRot.AsRad())
|
||||||
println("\n" + vRot.AsRad().String())
|
println("\n" + vRot.AsRad().String())
|
||||||
println(q.String(), "\n", q.Mag())
|
println(q.String(), "\n", q.Mag())
|
||||||
|
|
||||||
q = gglm.NewQuatAngleAxis(60*gglm.Deg2Rad, vRot.Normalize())
|
q = gglm.NewQuatAngleAxisVec(60*gglm.Deg2Rad, vRot.Normalize())
|
||||||
println("\n" + vRot.Normalize().String())
|
println("\n" + vRot.Normalize().String())
|
||||||
println(q.String())
|
println(q.String())
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ func main() {
|
|||||||
translationMat := gglm.NewTranslationMat(&gglm.Vec3{Data: [3]float32{1, 2, 3}})
|
translationMat := gglm.NewTranslationMat(&gglm.Vec3{Data: [3]float32{1, 2, 3}})
|
||||||
|
|
||||||
rotDegs := gglm.NewVec3(60, 30, 20)
|
rotDegs := gglm.NewVec3(60, 30, 20)
|
||||||
quat := gglm.NewQuatEuler(rotDegs.AsRad())
|
quat := gglm.NewQuatEulerVec(rotDegs.AsRad())
|
||||||
rotMat := gglm.NewRotMat(&quat)
|
rotMat := gglm.NewRotMat(&quat)
|
||||||
|
|
||||||
scale := gglm.NewVec3(1, 1, 1)
|
scale := gglm.NewVec3(1, 1, 1)
|
||||||
@ -186,10 +186,10 @@ func main() {
|
|||||||
|
|
||||||
// Quat geo
|
// Quat geo
|
||||||
q1Degs := gglm.NewVec3(180*gglm.Deg2Rad, 0, 0)
|
q1Degs := gglm.NewVec3(180*gglm.Deg2Rad, 0, 0)
|
||||||
q1 := gglm.NewQuatEuler(&q1Degs)
|
q1 := gglm.NewQuatEulerVec(&q1Degs)
|
||||||
|
|
||||||
q2Degs := gglm.NewVec3(0, 180*gglm.Deg2Rad, 0)
|
q2Degs := gglm.NewVec3(0, 180*gglm.Deg2Rad, 0)
|
||||||
q2 := gglm.NewQuatEuler(&q2Degs)
|
q2 := gglm.NewQuatEulerVec(&q2Degs)
|
||||||
println(gglm.AngleQuat(&q1, &q2) * gglm.Rad2Deg)
|
println(gglm.AngleQuat(&q1, &q2) * gglm.Rad2Deg)
|
||||||
|
|
||||||
// LookAt
|
// LookAt
|
||||||
|
|||||||
Reference in New Issue
Block a user