mirror of
https://github.com/bloeys/gglm.git
synced 2025-12-29 13:38:20 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5980c50ced | |||
| 5f43d7da88 | |||
| 4a7e66c0b9 | |||
| 0bf7a06315 | |||
| ad5d2c49c8 | |||
| b2e9c48114 | |||
| a3843e2e9c | |||
| 2799b8df2e | |||
| ee27cfaa91 | |||
| a629eab2ca | |||
| a28976286e | |||
| a30003efd4 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -12,4 +12,5 @@
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
vendor/
|
||||
.vscode
|
||||
|
||||
@ -1,2 +1,8 @@
|
||||
# gglm
|
||||
|
||||
An OpenGL focused Go mathematics inspired by the C++ glm (OpenGL Mathematics) library
|
||||
|
||||
## Notes
|
||||
|
||||
You can check compiler inlining decisions using `go run -gcflags "-m" .`. Some functions look a bit weird compared to similar ones
|
||||
because we are trying to reduce function complexity so the compiler inlines.
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package gglm
|
||||
|
||||
import "math"
|
||||
|
||||
func DotVec2(v1, v2 *Vec2) float32 {
|
||||
return v1.X()*v2.X() + v1.Y()*v2.Y()
|
||||
}
|
||||
@ -8,6 +10,10 @@ func DotVec3(v1, v2 *Vec3) float32 {
|
||||
return v1.X()*v2.X() + v1.Y()*v2.Y() + v1.Z()*v2.Z()
|
||||
}
|
||||
|
||||
func DotVec4(v1, v2 *Vec4) float32 {
|
||||
return v1.X()*v2.X() + v1.Y()*v2.Y() + v1.Z()*v2.Z() + v1.W()*v2.W()
|
||||
}
|
||||
|
||||
func Cross(v1, v2 *Vec3) *Vec3 {
|
||||
return &Vec3{
|
||||
Data: [3]float32{
|
||||
@ -17,3 +23,53 @@ func Cross(v1, v2 *Vec3) *Vec3 {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//DistVec2 returns euclidean distance between v1 and v2
|
||||
func DistVec2(v1, v2 *Vec2) float32 {
|
||||
x := v1.X() - v2.X()
|
||||
y := v1.Y() - v2.Y()
|
||||
return float32(math.Sqrt(float64(x*x + y*y)))
|
||||
}
|
||||
|
||||
//DistVec3 returns euclidean distance between v1 and v2
|
||||
func DistVec3(v1, v2 *Vec3) float32 {
|
||||
x := v1.X() - v2.X()
|
||||
y := v1.Y() - v2.Y()
|
||||
z := v1.Z() - v2.Z()
|
||||
return float32(math.Sqrt(float64(x*x + y*y + z*z)))
|
||||
}
|
||||
|
||||
//DistVec4 returns euclidean distance between v1 and v2
|
||||
func DistVec4(v1, v2 *Vec4) float32 {
|
||||
|
||||
//Using X() etc won't let the function inline
|
||||
x := v1.Data[0] - v2.Data[0]
|
||||
y := v1.Data[1] - v2.Data[1]
|
||||
z := v1.Data[2] - v2.Data[2]
|
||||
w := v1.Data[3] - v2.Data[3]
|
||||
return float32(math.Sqrt(float64(x*x + y*y + z*z + w*w)))
|
||||
}
|
||||
|
||||
//DistVec2 returns the squared euclidean distance between v1 and v2 (avoids a sqrt)
|
||||
func SqrDistVec2(v1, v2 *Vec2) float32 {
|
||||
x := v1.X() - v2.X()
|
||||
y := v1.Y() - v2.Y()
|
||||
return x*x + y*y
|
||||
}
|
||||
|
||||
//DistVec3 returns the squared euclidean distance between v1 and v2 (avoids a sqrt)
|
||||
func SqrDistVec3(v1, v2 *Vec3) float32 {
|
||||
x := v1.X() - v2.X()
|
||||
y := v1.Y() - v2.Y()
|
||||
z := v1.Z() - v2.Z()
|
||||
return x*x + y*y + z*z
|
||||
}
|
||||
|
||||
//DistVec4 returns the squared euclidean distance between v1 and v2 (avoids a sqrt)
|
||||
func SqrDistVec4(v1, v2 *Vec4) float32 {
|
||||
x := v1.Data[0] - v2.Data[0]
|
||||
y := v1.Data[1] - v2.Data[1]
|
||||
z := v1.Data[2] - v2.Data[2]
|
||||
w := v1.Data[3] - v2.Data[3]
|
||||
return x*x + y*y + z*z + w*w
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ func (ms MatSize) String() string {
|
||||
}
|
||||
|
||||
type Mat interface {
|
||||
At(row, col int) float32
|
||||
Get(row, col int) float32
|
||||
Set(row, col int, val float32)
|
||||
Size() MatSize
|
||||
}
|
||||
|
||||
16
gglm/mat2.go
16
gglm/mat2.go
@ -11,7 +11,7 @@ type Mat2 struct {
|
||||
Data [4]float32
|
||||
}
|
||||
|
||||
func (m *Mat2) At(row, col int) float32 {
|
||||
func (m *Mat2) Get(row, col int) float32 {
|
||||
return m.Data[row*2+col]
|
||||
}
|
||||
|
||||
@ -63,6 +63,10 @@ func (m *Mat2) Scale(x float32) {
|
||||
m.Data[3] *= x
|
||||
}
|
||||
|
||||
func (m *Mat2) Eq(m2 *Mat2) bool {
|
||||
return m.Data == m2.Data
|
||||
}
|
||||
|
||||
//AddMat2 m3 = m1 + m2
|
||||
func AddMat2(m1, m2 *Mat2) *Mat2 {
|
||||
return &Mat2{
|
||||
@ -100,6 +104,16 @@ func MulMat2(m1, m2 *Mat2) *Mat2 {
|
||||
}
|
||||
}
|
||||
|
||||
//MulMat2Vec2 v2 = m1 * v1
|
||||
func MulMat2Vec2(m1 *Mat2, v1 *Vec2) *Vec2 {
|
||||
return &Vec2{
|
||||
Data: [2]float32{
|
||||
m1.Data[0]*v1.Data[0] + m1.Data[1]*v1.Data[1],
|
||||
m1.Data[2]*v1.Data[0] + m1.Data[3]*v1.Data[1],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//NewMat2Id returns the 2x2 identity matrix
|
||||
func NewMat2Id() *Mat2 {
|
||||
return &Mat2{
|
||||
|
||||
24
gglm/mat2_test.go
Executable file
24
gglm/mat2_test.go
Executable file
@ -0,0 +1,24 @@
|
||||
package gglm_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
)
|
||||
|
||||
func TestMulMat2Vec2(t *testing.T) {
|
||||
|
||||
m := &gglm.Mat2{
|
||||
Data: [4]float32{
|
||||
1, 2,
|
||||
3, 4,
|
||||
}}
|
||||
v := &gglm.Vec2{Data: [2]float32{1, 2}}
|
||||
|
||||
result := gglm.MulMat2Vec2(m, v)
|
||||
correctAns := gglm.Vec2{Data: [2]float32{5, 11}}
|
||||
|
||||
if !result.Eq(&correctAns) {
|
||||
t.Errorf("Got: %v; Expected: %v", result.String(), correctAns.String())
|
||||
}
|
||||
}
|
||||
17
gglm/mat3.go
17
gglm/mat3.go
@ -11,7 +11,7 @@ type Mat3 struct {
|
||||
Data [9]float32
|
||||
}
|
||||
|
||||
func (m *Mat3) At(row, col int) float32 {
|
||||
func (m *Mat3) Get(row, col int) float32 {
|
||||
return m.Data[row*3+col]
|
||||
}
|
||||
|
||||
@ -102,6 +102,10 @@ func (m *Mat3) Scale(x float32) {
|
||||
m.Data[8] *= x
|
||||
}
|
||||
|
||||
func (m *Mat3) Eq(m2 *Mat3) bool {
|
||||
return m.Data == m2.Data
|
||||
}
|
||||
|
||||
//AddMat3 m3 = m1 + m2
|
||||
func AddMat3(m1, m2 *Mat3) *Mat3 {
|
||||
return &Mat3{
|
||||
@ -159,6 +163,17 @@ func MulMat3(m1, m2 *Mat3) *Mat3 {
|
||||
}
|
||||
}
|
||||
|
||||
//MulMat3Vec3 v2 = m1 * v1
|
||||
func MulMat3Vec3(m1 *Mat3, v1 *Vec3) *Vec3 {
|
||||
return &Vec3{
|
||||
Data: [3]float32{
|
||||
m1.Data[0]*v1.Data[0] + m1.Data[1]*v1.Data[1] + m1.Data[2]*v1.Data[2],
|
||||
m1.Data[3]*v1.Data[0] + m1.Data[4]*v1.Data[1] + m1.Data[5]*v1.Data[2],
|
||||
m1.Data[6]*v1.Data[0] + m1.Data[7]*v1.Data[1] + m1.Data[8]*v1.Data[2],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//NewMat3Id returns the 3x3 identity matrix
|
||||
func NewMat3Id() *Mat3 {
|
||||
return &Mat3{
|
||||
|
||||
25
gglm/mat3_test.go
Executable file
25
gglm/mat3_test.go
Executable file
@ -0,0 +1,25 @@
|
||||
package gglm_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
)
|
||||
|
||||
func TestMulMat3Vec3(t *testing.T) {
|
||||
|
||||
m := &gglm.Mat3{
|
||||
Data: [9]float32{
|
||||
1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9,
|
||||
}}
|
||||
v := &gglm.Vec3{Data: [3]float32{1, 2, 3}}
|
||||
|
||||
result := gglm.MulMat3Vec3(m, v)
|
||||
correctAns := gglm.Vec3{Data: [3]float32{14, 32, 50}}
|
||||
|
||||
if !result.Eq(&correctAns) {
|
||||
t.Errorf("Got: %v; Expected: %v", result.String(), correctAns.String())
|
||||
}
|
||||
}
|
||||
47
gglm/mat4.go
47
gglm/mat4.go
@ -11,7 +11,7 @@ type Mat4 struct {
|
||||
Data [16]float32
|
||||
}
|
||||
|
||||
func (m *Mat4) At(row, col int) float32 {
|
||||
func (m *Mat4) Get(row, col int) float32 {
|
||||
return m.Data[row*4+col]
|
||||
}
|
||||
|
||||
@ -89,23 +89,30 @@ func (m *Mat4) Mul(m2 *Mat4) {
|
||||
// 08, 09, 10, 11,
|
||||
// 12, 13, 14, 15,
|
||||
|
||||
//Seems to improve performance by ~5% (18ns/op -> 17ns/op).
|
||||
//Works by improving cache usage by putting 0,4,8,12 together instead of faraway in the array?
|
||||
a := m2.Data[0]
|
||||
b := m2.Data[4]
|
||||
c := m2.Data[8]
|
||||
d := m2.Data[12]
|
||||
|
||||
m.Data = [16]float32{
|
||||
m.Data[0]*m2.Data[0] + m.Data[1]*m2.Data[4] + m.Data[2]*m2.Data[8] + m.Data[3]*m2.Data[12],
|
||||
m.Data[0]*a + m.Data[1]*b + m.Data[2]*c + m.Data[3]*d,
|
||||
m.Data[0]*m2.Data[1] + m.Data[1]*m2.Data[5] + m.Data[2]*m2.Data[9] + m.Data[3]*m2.Data[13],
|
||||
m.Data[0]*m2.Data[2] + m.Data[1]*m2.Data[6] + m.Data[2]*m2.Data[10] + m.Data[3]*m2.Data[14],
|
||||
m.Data[0]*m2.Data[3] + m.Data[1]*m2.Data[7] + m.Data[2]*m2.Data[11] + m.Data[3]*m2.Data[15],
|
||||
|
||||
m.Data[4]*m2.Data[0] + m.Data[5]*m2.Data[4] + m.Data[6]*m2.Data[8] + m.Data[7]*m2.Data[12],
|
||||
m.Data[4]*a + m.Data[5]*b + m.Data[6]*c + m.Data[7]*d,
|
||||
m.Data[4]*m2.Data[1] + m.Data[5]*m2.Data[5] + m.Data[6]*m2.Data[9] + m.Data[7]*m2.Data[13],
|
||||
m.Data[4]*m2.Data[2] + m.Data[5]*m2.Data[6] + m.Data[6]*m2.Data[10] + m.Data[7]*m2.Data[14],
|
||||
m.Data[4]*m2.Data[3] + m.Data[5]*m2.Data[7] + m.Data[6]*m2.Data[11] + m.Data[7]*m2.Data[15],
|
||||
|
||||
m.Data[8]*m2.Data[0] + m.Data[9]*m2.Data[4] + m.Data[10]*m2.Data[8] + m.Data[11]*m2.Data[12],
|
||||
m.Data[8]*a + m.Data[9]*b + m.Data[10]*c + m.Data[11]*d,
|
||||
m.Data[8]*m2.Data[1] + m.Data[9]*m2.Data[5] + m.Data[10]*m2.Data[9] + m.Data[11]*m2.Data[13],
|
||||
m.Data[8]*m2.Data[2] + m.Data[9]*m2.Data[6] + m.Data[10]*m2.Data[10] + m.Data[11]*m2.Data[14],
|
||||
m.Data[8]*m2.Data[3] + m.Data[9]*m2.Data[7] + m.Data[10]*m2.Data[11] + m.Data[11]*m2.Data[15],
|
||||
|
||||
m.Data[12]*m2.Data[0] + m.Data[13]*m2.Data[4] + m.Data[14]*m2.Data[8] + m.Data[15]*m2.Data[12],
|
||||
m.Data[12]*a + m.Data[13]*b + m.Data[14]*c + m.Data[15]*d,
|
||||
m.Data[12]*m2.Data[1] + m.Data[13]*m2.Data[5] + m.Data[14]*m2.Data[9] + m.Data[15]*m2.Data[13],
|
||||
m.Data[12]*m2.Data[2] + m.Data[13]*m2.Data[6] + m.Data[14]*m2.Data[10] + m.Data[15]*m2.Data[14],
|
||||
m.Data[12]*m2.Data[3] + m.Data[13]*m2.Data[7] + m.Data[14]*m2.Data[11] + m.Data[15]*m2.Data[15],
|
||||
@ -136,6 +143,10 @@ func (m *Mat4) Scale(x float32) {
|
||||
m.Data[15] *= x
|
||||
}
|
||||
|
||||
func (m *Mat4) Eq(m2 *Mat4) bool {
|
||||
return m.Data == m2.Data
|
||||
}
|
||||
|
||||
//AddMat4 m3 = m1 + m2
|
||||
func AddMat4(m1, m2 *Mat4) *Mat4 {
|
||||
return &Mat4{
|
||||
@ -192,24 +203,30 @@ func SubMat4(m1, m2 *Mat4) *Mat4 {
|
||||
|
||||
//MulMat4 m3 = m1 * m2
|
||||
func MulMat4(m1, m2 *Mat4) *Mat4 {
|
||||
|
||||
a := m2.Data[0]
|
||||
b := m2.Data[4]
|
||||
c := m2.Data[8]
|
||||
d := m2.Data[12]
|
||||
|
||||
return &Mat4{
|
||||
Data: [16]float32{
|
||||
m1.Data[0]*m2.Data[0] + m1.Data[1]*m2.Data[4] + m1.Data[2]*m2.Data[8] + m1.Data[3]*m2.Data[12],
|
||||
m1.Data[0]*a + m1.Data[1]*b + m1.Data[2]*c + m1.Data[3]*d,
|
||||
m1.Data[0]*m2.Data[1] + m1.Data[1]*m2.Data[5] + m1.Data[2]*m2.Data[9] + m1.Data[3]*m2.Data[13],
|
||||
m1.Data[0]*m2.Data[2] + m1.Data[1]*m2.Data[6] + m1.Data[2]*m2.Data[10] + m1.Data[3]*m2.Data[14],
|
||||
m1.Data[0]*m2.Data[3] + m1.Data[1]*m2.Data[7] + m1.Data[2]*m2.Data[11] + m1.Data[3]*m2.Data[15],
|
||||
|
||||
m1.Data[4]*m2.Data[0] + m1.Data[5]*m2.Data[4] + m1.Data[6]*m2.Data[8] + m1.Data[7]*m2.Data[12],
|
||||
m1.Data[4]*a + m1.Data[5]*b + m1.Data[6]*c + m1.Data[7]*d,
|
||||
m1.Data[4]*m2.Data[1] + m1.Data[5]*m2.Data[5] + m1.Data[6]*m2.Data[9] + m1.Data[7]*m2.Data[13],
|
||||
m1.Data[4]*m2.Data[2] + m1.Data[5]*m2.Data[6] + m1.Data[6]*m2.Data[10] + m1.Data[7]*m2.Data[14],
|
||||
m1.Data[4]*m2.Data[3] + m1.Data[5]*m2.Data[7] + m1.Data[6]*m2.Data[11] + m1.Data[7]*m2.Data[15],
|
||||
|
||||
m1.Data[8]*m2.Data[0] + m1.Data[9]*m2.Data[4] + m1.Data[10]*m2.Data[8] + m1.Data[11]*m2.Data[12],
|
||||
m1.Data[8]*a + m1.Data[9]*b + m1.Data[10]*c + m1.Data[11]*d,
|
||||
m1.Data[8]*m2.Data[1] + m1.Data[9]*m2.Data[5] + m1.Data[10]*m2.Data[9] + m1.Data[11]*m2.Data[13],
|
||||
m1.Data[8]*m2.Data[2] + m1.Data[9]*m2.Data[6] + m1.Data[10]*m2.Data[10] + m1.Data[11]*m2.Data[14],
|
||||
m1.Data[8]*m2.Data[3] + m1.Data[9]*m2.Data[7] + m1.Data[10]*m2.Data[11] + m1.Data[11]*m2.Data[15],
|
||||
|
||||
m1.Data[12]*m2.Data[0] + m1.Data[13]*m2.Data[4] + m1.Data[14]*m2.Data[8] + m1.Data[15]*m2.Data[12],
|
||||
m1.Data[12]*a + m1.Data[13]*b + m1.Data[14]*c + m1.Data[15]*d,
|
||||
m1.Data[12]*m2.Data[1] + m1.Data[13]*m2.Data[5] + m1.Data[14]*m2.Data[9] + m1.Data[15]*m2.Data[13],
|
||||
m1.Data[12]*m2.Data[2] + m1.Data[13]*m2.Data[6] + m1.Data[14]*m2.Data[10] + m1.Data[15]*m2.Data[14],
|
||||
m1.Data[12]*m2.Data[3] + m1.Data[13]*m2.Data[7] + m1.Data[14]*m2.Data[11] + m1.Data[15]*m2.Data[15],
|
||||
@ -217,6 +234,18 @@ func MulMat4(m1, m2 *Mat4) *Mat4 {
|
||||
}
|
||||
}
|
||||
|
||||
//MulMat4Vec4 v2 = m1 * v1
|
||||
func MulMat4Vec4(m1 *Mat4, v1 *Vec4) *Vec4 {
|
||||
return &Vec4{
|
||||
Data: [4]float32{
|
||||
m1.Data[0]*v1.Data[0] + m1.Data[1]*v1.Data[1] + m1.Data[2]*v1.Data[2] + m1.Data[3]*v1.Data[3],
|
||||
m1.Data[4]*v1.Data[0] + m1.Data[5]*v1.Data[1] + m1.Data[6]*v1.Data[2] + m1.Data[7]*v1.Data[3],
|
||||
m1.Data[8]*v1.Data[0] + m1.Data[9]*v1.Data[1] + m1.Data[10]*v1.Data[2] + m1.Data[11]*v1.Data[3],
|
||||
m1.Data[12]*v1.Data[0] + m1.Data[13]*v1.Data[1] + m1.Data[14]*v1.Data[2] + m1.Data[15]*v1.Data[3],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//NewMat4Id returns the 4x4 identity matrix
|
||||
func NewMat4Id() *Mat4 {
|
||||
return &Mat4{
|
||||
|
||||
26
gglm/mat4_test.go
Executable file
26
gglm/mat4_test.go
Executable file
@ -0,0 +1,26 @@
|
||||
package gglm_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
)
|
||||
|
||||
func TestMulMat4Vec4(t *testing.T) {
|
||||
|
||||
m := &gglm.Mat4{
|
||||
Data: [16]float32{
|
||||
1, 2, 3, 4,
|
||||
5, 6, 7, 8,
|
||||
9, 10, 11, 12,
|
||||
13, 14, 15, 16,
|
||||
}}
|
||||
v := &gglm.Vec4{Data: [4]float32{1, 2, 3, 4}}
|
||||
|
||||
result := gglm.MulMat4Vec4(m, v)
|
||||
correctAns := gglm.Vec4{Data: [4]float32{30, 70, 110, 150}}
|
||||
|
||||
if !result.Eq(&correctAns) {
|
||||
t.Errorf("Got: %v; Expected: %v", result.String(), correctAns.String())
|
||||
}
|
||||
}
|
||||
@ -3,12 +3,18 @@ package gglm
|
||||
type Swizzle1 interface {
|
||||
X() float32
|
||||
R() float32
|
||||
|
||||
SetX(float32)
|
||||
SetR(float32)
|
||||
}
|
||||
|
||||
type Swizzle2 interface {
|
||||
Swizzle1
|
||||
Y() float32
|
||||
G() float32
|
||||
|
||||
SetY(float32)
|
||||
SetG(float32)
|
||||
}
|
||||
|
||||
type Swizzle3 interface {
|
||||
@ -16,10 +22,15 @@ type Swizzle3 interface {
|
||||
Z() float32
|
||||
B() float32
|
||||
|
||||
// XYZ
|
||||
// YXZ
|
||||
// XZY
|
||||
// YZX
|
||||
// ZXY
|
||||
// ZYX
|
||||
SetZ(float32)
|
||||
SetB(float32)
|
||||
}
|
||||
|
||||
type Swizzle4 interface {
|
||||
Swizzle3
|
||||
W() float32
|
||||
A() float32
|
||||
|
||||
SetW(float32)
|
||||
SetA(float32)
|
||||
}
|
||||
|
||||
31
gglm/vec2.go
31
gglm/vec2.go
@ -30,6 +30,22 @@ func (v *Vec2) G() float32 {
|
||||
return v.Data[1]
|
||||
}
|
||||
|
||||
func (v *Vec2) SetX(f float32) {
|
||||
v.Data[0] = f
|
||||
}
|
||||
|
||||
func (v *Vec2) SetR(f float32) {
|
||||
v.Data[0] = f
|
||||
}
|
||||
|
||||
func (v *Vec2) SetY(f float32) {
|
||||
v.Data[1] = f
|
||||
}
|
||||
|
||||
func (v *Vec2) SetG(f float32) {
|
||||
v.Data[1] = f
|
||||
}
|
||||
|
||||
func (v *Vec2) String() string {
|
||||
return fmt.Sprintf("(%f, %f)", v.X(), v.Y())
|
||||
}
|
||||
@ -62,6 +78,21 @@ func (v *Vec2) SqrMag() float32 {
|
||||
return v.X()*v.X() + v.Y()*v.Y()
|
||||
}
|
||||
|
||||
func (v *Vec2) Eq(v2 *Vec2) bool {
|
||||
return v.Data == v2.Data
|
||||
}
|
||||
|
||||
func (v *Vec2) Set(x, y float32) {
|
||||
v.Data[0] = x
|
||||
v.Data[1] = y
|
||||
}
|
||||
|
||||
func (v *Vec2) Normalize() {
|
||||
mag := v.Mag()
|
||||
v.Data[0] /= mag
|
||||
v.Data[1] /= mag
|
||||
}
|
||||
|
||||
//AddVec2 v3 = v1 + v2
|
||||
func AddVec2(v1, v2 *Vec2) *Vec2 {
|
||||
return &Vec2{
|
||||
|
||||
41
gglm/vec3.go
41
gglm/vec3.go
@ -36,6 +36,30 @@ func (v *Vec3) B() float32 {
|
||||
return v.Data[2]
|
||||
}
|
||||
|
||||
func (v *Vec3) SetX(f float32) {
|
||||
v.Data[0] = f
|
||||
}
|
||||
|
||||
func (v *Vec3) SetR(f float32) {
|
||||
v.Data[0] = f
|
||||
}
|
||||
|
||||
func (v *Vec3) SetY(f float32) {
|
||||
v.Data[1] = f
|
||||
}
|
||||
|
||||
func (v *Vec3) SetG(f float32) {
|
||||
v.Data[1] = f
|
||||
}
|
||||
|
||||
func (v *Vec3) SetZ(f float32) {
|
||||
v.Data[2] = f
|
||||
}
|
||||
|
||||
func (v *Vec3) SetB(f float32) {
|
||||
v.Data[2] = f
|
||||
}
|
||||
|
||||
func (v *Vec3) String() string {
|
||||
return fmt.Sprintf("(%f, %f, %f)", v.X(), v.Y(), v.Z())
|
||||
}
|
||||
@ -71,6 +95,23 @@ func (v *Vec3) SqrMag() float32 {
|
||||
return v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z()
|
||||
}
|
||||
|
||||
func (v *Vec3) Eq(v2 *Vec3) bool {
|
||||
return v.Data == v2.Data
|
||||
}
|
||||
|
||||
func (v *Vec3) Set(x, y, z float32) {
|
||||
v.Data[0] = x
|
||||
v.Data[1] = y
|
||||
v.Data[2] = z
|
||||
}
|
||||
|
||||
func (v *Vec3) Normalize() {
|
||||
mag := float32(math.Sqrt(float64(v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z())))
|
||||
v.Data[0] /= mag
|
||||
v.Data[1] /= mag
|
||||
v.Data[2] /= mag
|
||||
}
|
||||
|
||||
//AddVec3 v3 = v1 + v2
|
||||
func AddVec3(v1, v2 *Vec3) *Vec3 {
|
||||
return &Vec3{
|
||||
|
||||
158
gglm/vec4.go
Executable file
158
gglm/vec4.go
Executable file
@ -0,0 +1,158 @@
|
||||
package gglm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
var _ Swizzle4 = &Vec4{}
|
||||
var _ fmt.Stringer = &Vec4{}
|
||||
|
||||
type Vec4 struct {
|
||||
Data [4]float32
|
||||
}
|
||||
|
||||
func (v *Vec4) X() float32 {
|
||||
return v.Data[0]
|
||||
}
|
||||
|
||||
func (v *Vec4) Y() float32 {
|
||||
return v.Data[1]
|
||||
}
|
||||
|
||||
func (v *Vec4) Z() float32 {
|
||||
return v.Data[2]
|
||||
}
|
||||
|
||||
func (v *Vec4) W() float32 {
|
||||
return v.Data[3]
|
||||
}
|
||||
|
||||
func (v *Vec4) R() float32 {
|
||||
return v.Data[0]
|
||||
}
|
||||
|
||||
func (v *Vec4) G() float32 {
|
||||
return v.Data[1]
|
||||
}
|
||||
|
||||
func (v *Vec4) B() float32 {
|
||||
return v.Data[2]
|
||||
}
|
||||
|
||||
func (v *Vec4) A() float32 {
|
||||
return v.Data[3]
|
||||
}
|
||||
|
||||
func (v *Vec4) SetX(f float32) {
|
||||
v.Data[0] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetR(f float32) {
|
||||
v.Data[0] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetY(f float32) {
|
||||
v.Data[1] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetG(f float32) {
|
||||
v.Data[1] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetZ(f float32) {
|
||||
v.Data[2] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetB(f float32) {
|
||||
v.Data[2] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetW(f float32) {
|
||||
v.Data[3] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) SetA(f float32) {
|
||||
v.Data[3] = f
|
||||
}
|
||||
|
||||
func (v *Vec4) String() string {
|
||||
return fmt.Sprintf("(%f, %f, %f, %f)", v.X(), v.Y(), v.Z(), v.W())
|
||||
}
|
||||
|
||||
//Scale v *= x (element wise multiplication)
|
||||
func (v *Vec4) Scale(x float32) {
|
||||
v.Data[0] *= x
|
||||
v.Data[1] *= x
|
||||
v.Data[2] *= x
|
||||
v.Data[3] *= x
|
||||
}
|
||||
|
||||
func (v *Vec4) Add(v2 *Vec4) {
|
||||
|
||||
v.Data[0] += v2.X()
|
||||
v.Data[1] += v2.Y()
|
||||
v.Data[2] += v2.Z()
|
||||
v.Data[3] += v2.W()
|
||||
}
|
||||
|
||||
//SubVec4 v -= v2
|
||||
func (v *Vec4) Sub(v2 *Vec4) {
|
||||
v.Data[0] -= v2.X()
|
||||
v.Data[1] -= v2.Y()
|
||||
v.Data[2] -= v2.Z()
|
||||
v.Data[3] -= v2.W()
|
||||
}
|
||||
|
||||
//Mag returns the magnitude of the vector
|
||||
func (v *Vec4) Mag() float32 {
|
||||
return float32(math.Sqrt(float64(v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z() + v.W()*v.W())))
|
||||
}
|
||||
|
||||
//Mag returns the squared magnitude of the vector
|
||||
func (v *Vec4) SqrMag() float32 {
|
||||
return v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z() + v.Z()*v.Z()
|
||||
}
|
||||
|
||||
func (v *Vec4) Eq(v2 *Vec4) bool {
|
||||
return v.Data == v2.Data
|
||||
}
|
||||
|
||||
func (v *Vec4) Set(x, y, z, w float32) {
|
||||
v.Data[0] = x
|
||||
v.Data[1] = y
|
||||
v.Data[2] = z
|
||||
v.Data[3] = w
|
||||
}
|
||||
|
||||
func (v *Vec4) Normalize() {
|
||||
mag := float32(math.Sqrt(float64(v.Data[0]*v.Data[0] + v.Data[1]*v.Data[1] + v.Data[2]*v.Data[2] + v.Data[3]*v.Data[3])))
|
||||
v.Data[0] /= mag
|
||||
v.Data[1] /= mag
|
||||
v.Data[2] /= mag
|
||||
v.Data[3] /= mag
|
||||
}
|
||||
|
||||
//AddVec4 v3 = v1 + v2
|
||||
func AddVec4(v1, v2 *Vec4) *Vec4 {
|
||||
return &Vec4{
|
||||
Data: [4]float32{
|
||||
v1.X() + v2.X(),
|
||||
v1.Y() + v2.Y(),
|
||||
v1.Z() + v2.Z(),
|
||||
v1.W() + v2.W(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//SubVec4 v3 = v1 - v2
|
||||
func SubVec4(v1, v2 *Vec4) *Vec4 {
|
||||
return &Vec4{
|
||||
Data: [4]float32{
|
||||
v1.X() - v2.X(),
|
||||
v1.Y() - v2.Y(),
|
||||
v1.Z() - v2.Z(),
|
||||
v1.W() - v2.W(),
|
||||
},
|
||||
}
|
||||
}
|
||||
47
main.go
47
main.go
@ -49,4 +49,51 @@ func main() {
|
||||
m4.Mul(m5)
|
||||
println(m4.String())
|
||||
println(m6.String())
|
||||
println(m4.Eq(m6))
|
||||
|
||||
//Vec2
|
||||
v1 := &gglm.Vec2{Data: [2]float32{1, 2}}
|
||||
v2 := &gglm.Vec2{Data: [2]float32{3, 4}}
|
||||
println(gglm.DistVec2(v1, v2))
|
||||
println(gglm.SqrDistVec2(v2, v1))
|
||||
println(v1.Eq(v2))
|
||||
v2.Set(1, 2)
|
||||
println(v1.Eq(v2))
|
||||
|
||||
println("V1: " + v1.String())
|
||||
v1.Normalize()
|
||||
println("V1 Normal: " + v1.String())
|
||||
|
||||
//Vec3
|
||||
v3 := &gglm.Vec3{Data: [3]float32{1, 2, 3}}
|
||||
v4 := &gglm.Vec3{Data: [3]float32{4, 5, 6}}
|
||||
println(gglm.DistVec3(v3, v4))
|
||||
println(gglm.SqrDistVec3(v4, v3))
|
||||
|
||||
println(v3.Eq(v4))
|
||||
v4.Set(1, 2, 3)
|
||||
println(v3.Eq(v4))
|
||||
|
||||
println(gglm.DotVec3(v3, v4))
|
||||
println(gglm.Cross(v3, v4).String())
|
||||
|
||||
println("V3: " + v3.String())
|
||||
v3.Normalize()
|
||||
println("V3 Normal: " + v3.String())
|
||||
|
||||
//Vec4
|
||||
v5 := &gglm.Vec4{Data: [4]float32{1, 2, 3, 4}}
|
||||
v6 := &gglm.Vec4{Data: [4]float32{5, 6, 7, 8}}
|
||||
println(gglm.DistVec4(v5, v6))
|
||||
println(gglm.SqrDistVec4(v5, v6))
|
||||
|
||||
println(v5.Eq(v6))
|
||||
v6.Set(1, 2, 3, 4)
|
||||
println(v5.Eq(v6))
|
||||
|
||||
println(gglm.DotVec4(v5, v6))
|
||||
|
||||
println("V6: " + v6.String())
|
||||
v6.Normalize()
|
||||
println("V6 Normal: " + v6.String())
|
||||
}
|
||||
|
||||
62
main_test.go
62
main_test.go
@ -6,22 +6,68 @@ import (
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
)
|
||||
|
||||
func BenchmarkVec3Add(b *testing.B) {
|
||||
var (
|
||||
dotVec2Result float32 = 0
|
||||
dotVec3Result float32 = 0
|
||||
crossResult *gglm.Vec3
|
||||
)
|
||||
|
||||
v1 := gglm.NewMat3Id()
|
||||
v2 := gglm.NewMat3Id()
|
||||
func BenchmarkDotVec2(b *testing.B) {
|
||||
|
||||
v1 := &gglm.Vec2{}
|
||||
v2 := &gglm.Vec2{}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
v1.Mul(v2)
|
||||
dotVec2Result = gglm.DotVec2(v1, v2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkVec3Add2(b *testing.B) {
|
||||
func BenchmarkDotVec3(b *testing.B) {
|
||||
|
||||
v1 := gglm.NewMat3Id()
|
||||
v2 := gglm.NewMat3Id()
|
||||
v1 := &gglm.Vec3{}
|
||||
v2 := &gglm.Vec3{}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
v1.Mul(v2)
|
||||
dotVec3Result = gglm.DotVec3(v1, v2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCross(b *testing.B) {
|
||||
|
||||
v1 := &gglm.Vec3{}
|
||||
v2 := &gglm.Vec3{}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
crossResult = gglm.Cross(v1, v2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMulMat2(b *testing.B) {
|
||||
|
||||
m1 := gglm.NewMat2Id()
|
||||
m2 := gglm.NewMat2Id()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
m1.Mul(m2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMulMat3(b *testing.B) {
|
||||
|
||||
m1 := gglm.NewMat3Id()
|
||||
m2 := gglm.NewMat3Id()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
m1.Mul(m2)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMulMat4(b *testing.B) {
|
||||
|
||||
m1 := gglm.NewMat4Id()
|
||||
m2 := gglm.NewMat4Id()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
m1.Mul(m2)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user