mirror of
https://github.com/bloeys/gglm.git
synced 2025-12-29 13:38:20 +00:00
Use arrays instead of slices for speed+implement Vec3
This commit is contained in:
71
gglm/mat2.go
71
gglm/mat2.go
@ -10,15 +10,16 @@ var _ Mat = &Mat2{}
|
|||||||
var _ fmt.Stringer = &Mat2{}
|
var _ fmt.Stringer = &Mat2{}
|
||||||
|
|
||||||
type Mat2 struct {
|
type Mat2 struct {
|
||||||
|
Arr [4]float32
|
||||||
*blas32.General
|
*blas32.General
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mat2) At(row, col int) float32 {
|
func (m *Mat2) At(row, col int) float32 {
|
||||||
return m.Data[row*2+col]
|
return m.Arr[row*2+col]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mat2) Set(row, col int, val float32) {
|
func (m *Mat2) Set(row, col int, val float32) {
|
||||||
m.Data[row*2+col] = val
|
m.Arr[row*2+col] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mat2) Size() MatSize {
|
func (m *Mat2) Size() MatSize {
|
||||||
@ -26,74 +27,80 @@ func (m *Mat2) Size() MatSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mat2) String() string {
|
func (m *Mat2) String() string {
|
||||||
return fmt.Sprintf("| %f %f |\n| %f %f |", m.Data[0], m.Data[1], m.Data[2], m.Data[3])
|
return fmt.Sprintf("| %f %f |\n| %f %f |", m.Arr[0], m.Arr[1], m.Arr[2], m.Arr[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add m += m2
|
//Add m += m2
|
||||||
func (m *Mat2) Add(m2 *Mat2) {
|
func (m *Mat2) Add(m2 *Mat2) {
|
||||||
m.Data[0] += m2.Data[0]
|
m.Arr[0] += m2.Arr[0]
|
||||||
m.Data[1] += m2.Data[1]
|
m.Arr[1] += m2.Arr[1]
|
||||||
m.Data[2] += m2.Data[2]
|
m.Arr[2] += m2.Arr[2]
|
||||||
m.Data[3] += m2.Data[3]
|
m.Arr[3] += m2.Arr[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add m -= m2
|
//Add m -= m2
|
||||||
func (m *Mat2) Sub(m2 *Mat2) {
|
func (m *Mat2) Sub(m2 *Mat2) {
|
||||||
m.Data[0] -= m2.Data[0]
|
m.Arr[0] -= m2.Arr[0]
|
||||||
m.Data[1] -= m2.Data[1]
|
m.Arr[1] -= m2.Arr[1]
|
||||||
m.Data[2] -= m2.Data[2]
|
m.Arr[2] -= m2.Arr[2]
|
||||||
m.Data[3] -= m2.Data[3]
|
m.Arr[3] -= m2.Arr[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
//Scale m *= x (element wise multiplication)
|
//Scale m *= x (element wise multiplication)
|
||||||
func (m *Mat2) Scale(x float32) {
|
func (m *Mat2) Scale(x float32) {
|
||||||
m.Data[0] *= x
|
m.Arr[0] *= x
|
||||||
m.Data[1] *= x
|
m.Arr[1] *= x
|
||||||
m.Data[2] *= x
|
m.Arr[2] *= x
|
||||||
m.Data[3] *= x
|
m.Arr[3] *= x
|
||||||
}
|
}
|
||||||
|
|
||||||
//AddMat2 m3 = m1 + m2
|
//AddMat2 m3 = m1 + m2
|
||||||
func AddMat2(m1, m2 *Mat2) *Mat2 {
|
func AddMat2(m1, m2 *Mat2) *Mat2 {
|
||||||
return NewMat2([]float32{
|
return NewMat2([]float32{
|
||||||
m1.Data[0] + m2.Data[0],
|
m1.Arr[0] + m2.Arr[0],
|
||||||
m1.Data[1] + m2.Data[1],
|
m1.Arr[1] + m2.Arr[1],
|
||||||
m1.Data[2] + m2.Data[2],
|
m1.Arr[2] + m2.Arr[2],
|
||||||
m1.Data[3] + m2.Data[3],
|
m1.Arr[3] + m2.Arr[3],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//SubMat2 m3 = m1 - m2
|
//SubMat2 m3 = m1 - m2
|
||||||
func SubMat2(m1, m2 *Mat2) *Mat2 {
|
func SubMat2(m1, m2 *Mat2) *Mat2 {
|
||||||
return NewMat2([]float32{
|
return NewMat2([]float32{
|
||||||
m1.Data[0] - m2.Data[0],
|
m1.Arr[0] - m2.Arr[0],
|
||||||
m1.Data[1] - m2.Data[1],
|
m1.Arr[1] - m2.Arr[1],
|
||||||
m1.Data[2] - m2.Data[2],
|
m1.Arr[2] - m2.Arr[2],
|
||||||
m1.Data[3] - m2.Data[3],
|
m1.Arr[3] - m2.Arr[3],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewMat2 returns the identity matrix if data=nil, otherwise data is used
|
//NewMat2 returns the identity matrix if data is nil, otherwise data is copied.
|
||||||
//as the backing array.
|
|
||||||
//
|
//
|
||||||
//Note: data must be row major
|
//Note: data must be row major
|
||||||
func NewMat2(data []float32) *Mat2 {
|
func NewMat2(data []float32) *Mat2 {
|
||||||
|
|
||||||
if data == nil {
|
arr := [4]float32{
|
||||||
data = []float32{
|
1, 0,
|
||||||
1, 0,
|
0, 1,
|
||||||
0, 1,
|
}
|
||||||
|
if data != nil {
|
||||||
|
if len(data) != 4 {
|
||||||
|
panic("Data must be nil or size 4")
|
||||||
}
|
}
|
||||||
} else if len(data) != 4 {
|
|
||||||
panic("Data must be nil or size 4")
|
arr[0] = data[0]
|
||||||
|
arr[1] = data[1]
|
||||||
|
arr[2] = data[2]
|
||||||
|
arr[3] = data[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Mat2{
|
return &Mat2{
|
||||||
|
Arr: arr,
|
||||||
General: &blas32.General{
|
General: &blas32.General{
|
||||||
Rows: 2,
|
Rows: 2,
|
||||||
Cols: 2,
|
Cols: 2,
|
||||||
Stride: 2,
|
Stride: 2,
|
||||||
Data: data,
|
Data: arr[:],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
57
gglm/vec2.go
57
gglm/vec2.go
@ -1,5 +1,7 @@
|
|||||||
package gglm
|
package gglm
|
||||||
|
|
||||||
|
//Note: We don't use the Swizzle interface for add/sub because the interface doesn't allow inling :(
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@ -10,23 +12,24 @@ var _ Swizzle2 = &Vec2{}
|
|||||||
var _ fmt.Stringer = &Vec2{}
|
var _ fmt.Stringer = &Vec2{}
|
||||||
|
|
||||||
type Vec2 struct {
|
type Vec2 struct {
|
||||||
|
Arr [2]float32
|
||||||
*blas32.Vector
|
*blas32.Vector
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec2) X() float32 {
|
func (v *Vec2) X() float32 {
|
||||||
return v.Data[0]
|
return v.Arr[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec2) Y() float32 {
|
func (v *Vec2) Y() float32 {
|
||||||
return v.Data[1]
|
return v.Arr[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec2) R() float32 {
|
func (v *Vec2) R() float32 {
|
||||||
return v.Data[0]
|
return v.Arr[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec2) G() float32 {
|
func (v *Vec2) G() float32 {
|
||||||
return v.Data[1]
|
return v.Arr[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec2) String() string {
|
func (v *Vec2) String() string {
|
||||||
@ -35,19 +38,20 @@ func (v *Vec2) String() string {
|
|||||||
|
|
||||||
//Scale v *= x (element wise multiplication)
|
//Scale v *= x (element wise multiplication)
|
||||||
func (v *Vec2) Scale(x float32) {
|
func (v *Vec2) Scale(x float32) {
|
||||||
v.Data[0] *= x
|
v.Arr[0] *= x
|
||||||
v.Data[1] *= x
|
v.Arr[1] *= x
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vec2) Add(b Swizzle2) {
|
//Add v += v2
|
||||||
v.Data[0] += b.X()
|
func (v *Vec2) Add(v2 *Vec2) {
|
||||||
v.Data[1] += b.Y()
|
v.Arr[0] += v2.X()
|
||||||
|
v.Arr[1] += v2.Y()
|
||||||
}
|
}
|
||||||
|
|
||||||
//SubVec2 v -= v2
|
//SubVec2 v -= v2
|
||||||
func (v *Vec2) Sub(v2 *Vec2) {
|
func (v *Vec2) Sub(v2 *Vec2) {
|
||||||
v.Data[0] -= v2.X()
|
v.Arr[0] -= v2.X()
|
||||||
v.Data[1] -= v2.Y()
|
v.Arr[1] -= v2.Y()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mag returns the magnitude of the vector
|
//Mag returns the magnitude of the vector
|
||||||
@ -61,28 +65,41 @@ func (v *Vec2) SqrMag() float32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//AddVec2 v3 = v1 + v2
|
//AddVec2 v3 = v1 + v2
|
||||||
func AddVec2(v1 *Vec2, v2 *Vec2) *Vec2 {
|
func AddVec2(v1, v2 *Vec2) *Vec2 {
|
||||||
return NewVec2([]float32{v1.X() + v2.X(), v1.Y() + v2.Y()})
|
return NewVec2([]float32{
|
||||||
|
v1.X() + v2.X(),
|
||||||
|
v1.Y() + v2.Y(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//SubVec2 v3 = v1 + v2
|
//SubVec2 v3 = v1 - v2
|
||||||
func SubVec2(v1, v2 *Vec2) *Vec2 {
|
func SubVec2(v1, v2 *Vec2) *Vec2 {
|
||||||
return NewVec2([]float32{v1.X() - v2.X(), v1.Y() - v2.Y()})
|
return NewVec2([]float32{
|
||||||
|
v1.X() - v2.X(),
|
||||||
|
v1.Y() - v2.Y(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewVec2 copies data if its not nil
|
||||||
func NewVec2(data []float32) *Vec2 {
|
func NewVec2(data []float32) *Vec2 {
|
||||||
|
|
||||||
if data == nil {
|
arr := [2]float32{}
|
||||||
data = make([]float32, 2)
|
if data != nil {
|
||||||
} else if len(data) != 2 {
|
|
||||||
panic("Data must be nil or size 2")
|
if len(data) != 2 {
|
||||||
|
panic("Data must be nil or size 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
arr[0] = data[0]
|
||||||
|
arr[1] = data[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Vec2{
|
return &Vec2{
|
||||||
|
Arr: arr,
|
||||||
Vector: &blas32.Vector{
|
Vector: &blas32.Vector{
|
||||||
N: 2,
|
N: 2,
|
||||||
Inc: 1,
|
Inc: 1,
|
||||||
Data: data,
|
Data: arr[:],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
116
gglm/vec3.go
Executable file
116
gglm/vec3.go
Executable file
@ -0,0 +1,116 @@
|
|||||||
|
package gglm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gonum.org/v1/gonum/blas/blas32"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Swizzle3 = &Vec3{}
|
||||||
|
var _ fmt.Stringer = &Vec3{}
|
||||||
|
|
||||||
|
type Vec3 struct {
|
||||||
|
Arr [3]float32
|
||||||
|
*blas32.Vector
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) X() float32 {
|
||||||
|
return v.Arr[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) Y() float32 {
|
||||||
|
return v.Arr[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) Z() float32 {
|
||||||
|
return v.Arr[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) R() float32 {
|
||||||
|
return v.Arr[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) G() float32 {
|
||||||
|
return v.Arr[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) B() float32 {
|
||||||
|
return v.Arr[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) String() string {
|
||||||
|
return fmt.Sprintf("(%f, %f, %f)", v.X(), v.Y(), v.Z())
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scale v *= x (element wise multiplication)
|
||||||
|
func (v *Vec3) Scale(x float32) {
|
||||||
|
v.Arr[0] *= x
|
||||||
|
v.Arr[1] *= x
|
||||||
|
v.Arr[2] *= x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vec3) Add(v2 *Vec3) {
|
||||||
|
v.Arr[0] += v2.X()
|
||||||
|
v.Arr[1] += v2.Y()
|
||||||
|
v.Arr[2] += v2.Z()
|
||||||
|
}
|
||||||
|
|
||||||
|
//SubVec3 v -= v2
|
||||||
|
func (v *Vec3) Sub(v2 *Vec3) {
|
||||||
|
v.Arr[0] -= v2.X()
|
||||||
|
v.Arr[1] -= v2.Y()
|
||||||
|
v.Arr[2] -= v2.Z()
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mag returns the magnitude of the vector
|
||||||
|
func (v *Vec3) Mag() float32 {
|
||||||
|
return blas32.Nrm2(*v.Vector)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mag returns the squared magnitude of the vector
|
||||||
|
func (v *Vec3) SqrMag() float32 {
|
||||||
|
return v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z()
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddVec3 v3 = v1 + v2
|
||||||
|
func AddVec3(v1, v2 *Vec3) *Vec3 {
|
||||||
|
return NewVec3([]float32{
|
||||||
|
v1.X() + v2.X(),
|
||||||
|
v1.Y() + v2.Y(),
|
||||||
|
v1.Z() + v2.Z(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//SubVec3 v3 = v1 - v2
|
||||||
|
func SubVec3(v1, v2 *Vec3) *Vec3 {
|
||||||
|
return NewVec3([]float32{
|
||||||
|
v1.X() - v2.X(),
|
||||||
|
v1.Y() - v2.Y(),
|
||||||
|
v1.Z() - v2.Z(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewVec3 copies data if its not nil
|
||||||
|
func NewVec3(data []float32) *Vec3 {
|
||||||
|
|
||||||
|
arr := [3]float32{}
|
||||||
|
if data != nil {
|
||||||
|
|
||||||
|
if len(data) != 3 {
|
||||||
|
panic("Data must be nil or size 3")
|
||||||
|
}
|
||||||
|
|
||||||
|
arr[0] = data[0]
|
||||||
|
arr[1] = data[1]
|
||||||
|
arr[2] = data[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Vec3{
|
||||||
|
Arr: arr,
|
||||||
|
Vector: &blas32.Vector{
|
||||||
|
N: 3,
|
||||||
|
Inc: 1,
|
||||||
|
Data: arr[:],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
29
main.go
29
main.go
@ -1,27 +1,26 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/bloeys/gglm/gglm"
|
"github.com/bloeys/gglm/gglm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
v1 := gglm.NewVec2([]float32{4, 5})
|
// v1 := gglm.NewVec2([]float32{4, 5})
|
||||||
v2 := gglm.NewVec2([]float32{1, 1})
|
// v2 := gglm.NewVec2([]float32{1, 1})
|
||||||
println(v1.Mag())
|
// println(v1.Mag())
|
||||||
println(v1.SqrMag())
|
// println(v1.SqrMag())
|
||||||
|
v1 := gglm.NewVec2(nil)
|
||||||
|
v2 := gglm.NewVec2(nil)
|
||||||
v1.Add(v2)
|
v1.Add(v2)
|
||||||
v1.Sub(v2)
|
// v1.Sub(v2)
|
||||||
|
|
||||||
fmt.Println(gglm.DotVec2(v1, v2))
|
// fmt.Println(gglm.DotVec2(v1, v2))
|
||||||
fmt.Println(v1, v1.X(), v1.Y())
|
// fmt.Println(v1, v1.X(), v1.Y())
|
||||||
|
|
||||||
m := gglm.NewMat2(nil)
|
// m := gglm.NewMat2(nil)
|
||||||
fmt.Println(m.String(), m.At(0, 1), m.At(1, 1))
|
// fmt.Println(m.String(), m.At(0, 1), m.At(1, 1))
|
||||||
m.Set(0, 1, 55)
|
// m.Set(0, 1, 55)
|
||||||
m.Set(1, 0, 77)
|
// m.Set(1, 0, 77)
|
||||||
fmt.Println("\n"+m.String(), m.At(0, 1), m.At(1, 1))
|
// fmt.Println("\n"+m.String(), m.At(0, 1), m.At(1, 1))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user