From 3eb372dec3f23a9f475ad875d447f9ffe8e3567b Mon Sep 17 00:00:00 2001 From: bloeys Date: Sun, 5 May 2024 00:24:44 +0400 Subject: [PATCH] Remove more pointers+better NewXYZ funcs --- README.md | 2 +- gglm/transform.go | 141 ++++++++++++++++++++++++++++++++++------- gglm/transform_test.go | 8 +-- main.go | 17 ++--- 4 files changed, 128 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 8944b5d..140aa45 100644 --- a/README.md +++ b/README.md @@ -54,5 +54,5 @@ func main() { ## Notes -You can check compiler inlining decisions using `go run -gcflags "-m" .`. Some functions look a bit weird compared to similar ones +You can check compiler inlining decisions using `go run -gcflags "-m" .`. Some functions look a bit weird because we are trying to reduce function complexity so the compiler inlines. diff --git a/gglm/transform.go b/gglm/transform.go index 5a1a342..d2dd889 100755 --- a/gglm/transform.go +++ b/gglm/transform.go @@ -13,24 +13,36 @@ type TrMat struct { Mat4 } +// TranslateVec adds v to the translation components of the transformation matrix +func (t *TrMat) TranslateVec(v *Vec3) *TrMat { + return t.Translate(v.X(), v.Y(), v.Z()) +} + // Translate adds v to the translation components of the transformation matrix -func (t *TrMat) Translate(v *Vec3) *TrMat { - t.Data[3][0] += v.Data[0] - t.Data[3][1] += v.Data[1] - t.Data[3][2] += v.Data[2] +func (t *TrMat) Translate(x, y, z float32) *TrMat { + t.Data[3][0] += x + t.Data[3][1] += y + t.Data[3][2] += z return t } +// ScaleVec multiplies the scale components of the transformation matrix by v +func (t *TrMat) ScaleVec(v *Vec3) *TrMat { + return t.Scale(v.X(), v.Y(), v.Z()) +} + // Scale multiplies the scale components of the transformation matrix by v -func (t *TrMat) Scale(v *Vec3) *TrMat { - t.Data[0][0] *= v.Data[0] - t.Data[1][1] *= v.Data[1] - t.Data[2][2] *= v.Data[2] +func (t *TrMat) Scale(x, y, z float32) *TrMat { + t.Data[0][0] *= z + t.Data[1][1] *= y + t.Data[2][2] *= z return t } -// Rotate takes a *normalized* axis and angles in radians to rotate around the given axis -func (t *TrMat) Rotate(rads float32, axis *Vec3) *TrMat { +// RotateVec takes a *normalized* axis and angles in radians to rotate around the given axis +func (t *TrMat) RotateVec(rads float32, axis *Vec3) *TrMat { + + // Manually inlined s := Sin32(rads) c := Cos32(rads) @@ -83,6 +95,61 @@ func (t *TrMat) Rotate(rads float32, axis *Vec3) *TrMat { return t } +// Rotate takes a *normalized* axis and angles in radians to rotate around the given axis +func (t *TrMat) Rotate(rads float32, axisX, axisY, axisZ float32) *TrMat { + + s := Sin32(rads) + c := Cos32(rads) + + axis := NewVec3(axisX, axisY, axisZ) + axis.Normalize() + temp := axis.Clone().Scale(1 - c) + + rotate := TrMat{} + rotate.Data[0][0] = c + temp.Data[0]*axis.Data[0] + rotate.Data[0][1] = temp.Data[0]*axis.Data[1] + s*axis.Data[2] + rotate.Data[0][2] = temp.Data[0]*axis.Data[2] - s*axis.Data[1] + + rotate.Data[1][0] = temp.Data[1]*axis.Data[0] - s*axis.Data[2] + rotate.Data[1][1] = c + temp.Data[1]*axis.Data[1] + rotate.Data[1][2] = temp.Data[1]*axis.Data[2] + s*axis.Data[0] + + rotate.Data[2][0] = temp.Data[2]*axis.Data[0] + s*axis.Data[1] + rotate.Data[2][1] = temp.Data[2]*axis.Data[1] - s*axis.Data[0] + rotate.Data[2][2] = c + temp.Data[2]*axis.Data[2] + + result := Mat4{} + + col0 := t.Col(0) + col1 := t.Col(1) + col2 := t.Col(2) + result.Data[0] = col0.Scale(rotate.Data[0][0]). + Add(col1.Scale(rotate.Data[0][1])). + Add(col2.Scale(rotate.Data[0][2])). + Data + + col0 = t.Col(0) + col1 = t.Col(1) + col2 = t.Col(2) + result.Data[1] = col0.Scale(rotate.Data[1][0]). + Add(col1.Scale(rotate.Data[1][1])). + Add(col2.Scale(rotate.Data[1][2])). + Data + + col0 = t.Col(0) + col1 = t.Col(1) + col2 = t.Col(2) + result.Data[2] = col0.Scale(rotate.Data[2][0]). + Add(col1.Scale(rotate.Data[2][1])). + Add(col2.Scale(rotate.Data[2][2])). + Data + + t.Data[0] = result.Data[0] + t.Data[1] = result.Data[1] + t.Data[2] = result.Data[2] + return t +} + func (t *TrMat) Mul(m *TrMat) *TrMat { t.Mat4.Mul(&m.Mat4) return t @@ -98,8 +165,8 @@ func (t *TrMat) Clone() *TrMat { } } -func NewTranslationMat(v *Vec3) *TrMat { - return &TrMat{ +func NewTranslationMatVec(v *Vec3) TrMat { + return TrMat{ Mat4: Mat4{ Data: [4][4]float32{ {1, 0, 0, 0}, @@ -111,8 +178,21 @@ func NewTranslationMat(v *Vec3) *TrMat { } } -func NewScaleMat(v *Vec3) *TrMat { - return &TrMat{ +func NewTranslationMat(posX, posY, posZ float32) TrMat { + return TrMat{ + Mat4: Mat4{ + Data: [4][4]float32{ + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {posX, posY, posZ, 1}, + }, + }, + } +} + +func NewScaleMatVec(v *Vec3) TrMat { + return TrMat{ Mat4: Mat4{ Data: [4][4]float32{ {v.Data[0], 0, 0, 0}, @@ -124,7 +204,20 @@ func NewScaleMat(v *Vec3) *TrMat { } } -func NewRotMat(q *Quat) *TrMat { +func NewScaleMat(scaleX, scaleY, scaleZ float32) TrMat { + return TrMat{ + Mat4: Mat4{ + Data: [4][4]float32{ + {scaleX, 0, 0, 0}, + {0, scaleY, 0, 0}, + {0, 0, scaleZ, 0}, + {0, 0, 0, 1}, + }, + }, + } +} + +func NewRotMatQuat(q *Quat) TrMat { //Based on: https://www.weizmann.ac.il/sci-tea/benari/sites/sci-tea.benari/files/uploads/softwareAndLearningMaterials/quaternion-tutorial-2-0-1.pdf //Note: in the reference p0,p1,p2,p3 == w,x,y,z @@ -143,7 +236,7 @@ func NewRotMat(q *Quat) *TrMat { zw := q.Data[2] * q.Data[3] - return &TrMat{ + return TrMat{ Mat4: Mat4{ Data: [4][4]float32{ {2*(ww+xx) - 1, 2 * (zw + xy), 2 * (xz - yw), 0}, @@ -157,7 +250,7 @@ func NewRotMat(q *Quat) *TrMat { // LookAtRH does a right-handed coordinate system lookAt (RH is the default for OpenGL). // Can be used to create the view matrix -func LookAtRH(pos, targetPos, worldUp *Vec3) *TrMat { +func LookAtRH(pos, targetPos, worldUp *Vec3) TrMat { forward := SubVec3(targetPos, pos) forward.Normalize() @@ -165,7 +258,7 @@ func LookAtRH(pos, targetPos, worldUp *Vec3) *TrMat { right.Normalize() up := Cross(&right, &forward) - return &TrMat{ + return TrMat{ Mat4: Mat4{ Data: [4][4]float32{ {right.Data[0], up.Data[0], -forward.Data[0], 0}, @@ -179,7 +272,7 @@ func LookAtRH(pos, targetPos, worldUp *Vec3) *TrMat { // LookAtLH does a left-handed coordinate system lookAt. // Can be used to create the view matrix -func LookAtLH(pos, targetPos, worldUp *Vec3) *TrMat { +func LookAtLH(pos, targetPos, worldUp *Vec3) TrMat { forward := SubVec3(targetPos, pos) forward.Normalize() @@ -187,7 +280,7 @@ func LookAtLH(pos, targetPos, worldUp *Vec3) *TrMat { right.Normalize() up := Cross(&forward, &right) - return &TrMat{ + return TrMat{ Mat4: Mat4{ Data: [4][4]float32{ {right.Data[0], up.Data[0], forward.Data[0], 0}, @@ -200,9 +293,9 @@ func LookAtLH(pos, targetPos, worldUp *Vec3) *TrMat { } // Perspective creates a perspective projection matrix -func Perspective(fov, aspectRatio, nearClip, farClip float32) *Mat4 { +func Perspective(fov, aspectRatio, nearClip, farClip float32) Mat4 { halfFovTan := float32(math.Tan(float64(fov * 0.5))) - return &Mat4{ + return Mat4{ Data: [4][4]float32{ {1 / (aspectRatio * halfFovTan), 0, 0, 0}, {0, 1 / halfFovTan, 0, 0}, @@ -213,8 +306,8 @@ func Perspective(fov, aspectRatio, nearClip, farClip float32) *Mat4 { } // Perspective creates an orthographic projection matrix -func Ortho(left, right, top, bottom, nearClip, farClip float32) *TrMat { - return &TrMat{ +func Ortho(left, right, top, bottom, nearClip, farClip float32) TrMat { + return TrMat{ Mat4: Mat4{ Data: [4][4]float32{ {2 / (right - left), 0, 0, 0}, diff --git a/gglm/transform_test.go b/gglm/transform_test.go index cd71672..32cef6a 100755 --- a/gglm/transform_test.go +++ b/gglm/transform_test.go @@ -27,8 +27,7 @@ func TestNewTrMatId(t *testing.T) { func TestNewTranslationMat(t *testing.T) { - pos := gglm.NewVec3(1, 2, 3) - m := gglm.NewTranslationMat(&pos) + m := gglm.NewTranslationMat(1, 2, 3) ans := &gglm.TrMat{ Mat4: gglm.Mat4{ Data: [4][4]float32{ @@ -47,8 +46,7 @@ func TestNewTranslationMat(t *testing.T) { func TestNewScaleMat(t *testing.T) { - pos := gglm.NewVec3(1, 2, 3) - m := gglm.NewScaleMat(&pos) + m := gglm.NewScaleMat(1, 2, 3) ans := &gglm.TrMat{ Mat4: gglm.Mat4{ Data: [4][4]float32{ @@ -68,7 +66,7 @@ func TestNewScaleMat(t *testing.T) { func TestNewRotMat(t *testing.T) { quat := gglm.NewQuatId() - m := gglm.NewRotMat(&quat) + m := gglm.NewRotMatQuat(&quat) ans := &gglm.TrMat{ Mat4: gglm.Mat4{ Data: [4][4]float32{ diff --git a/main.go b/main.go index c7935c5..3808d56 100755 --- a/main.go +++ b/main.go @@ -152,17 +152,16 @@ func main() { println(q.String()) // Transform - translationMat := gglm.NewTranslationMat(&gglm.Vec3{Data: [3]float32{1, 2, 3}}) + translationMat := gglm.NewTranslationMatVec(&gglm.Vec3{Data: [3]float32{1, 2, 3}}) rotDegs := gglm.NewVec3(60, 30, 20) quat := gglm.NewQuatEulerVec(rotDegs.AsRad()) - rotMat := gglm.NewRotMat(&quat) + rotMat := gglm.NewRotMatQuat(&quat) - scale := gglm.NewVec3(1, 1, 1) - scaleMat := gglm.NewScaleMat(&scale) + scaleMat := gglm.NewScaleMat(1, 1, 1) modelMat := gglm.NewTrMatId() - modelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat))) + modelMat.Mul(translationMat.Mul(rotMat.Mul(&scaleMat))) println("\n\n\n", modelMat.String()) @@ -173,15 +172,13 @@ func main() { println("\n\n", v2Orig.String(), "; ", v2Clone.String()) // Clone TrMat - pos := gglm.NewVec3(1, 2, 3) - trMatOrig := gglm.NewTranslationMat(&pos) + trMatOrig := gglm.NewTranslationMat(1, 2, 3) trMatClone := trMatOrig.Clone() trMatCloneScale := gglm.NewVec3(2, 2, 2) - trMatClone.Scale(&trMatCloneScale) + trMatClone.ScaleVec(&trMatCloneScale) - pos = gglm.NewVec3(9, 0, 0) - trMatClone.Translate(&pos) + trMatClone.Translate(9, 0, 0) println("\n\n", trMatOrig.String(), "; ", trMatClone.String()) // Quat geo