diff --git a/gglm/mat2.go b/gglm/mat2.go index 193e99c..8e4ee9e 100755 --- a/gglm/mat2.go +++ b/gglm/mat2.go @@ -10,15 +10,16 @@ var _ Mat = &Mat2{} var _ fmt.Stringer = &Mat2{} type Mat2 struct { + Arr [4]float32 *blas32.General } 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) { - m.Data[row*2+col] = val + m.Arr[row*2+col] = val } func (m *Mat2) Size() MatSize { @@ -26,74 +27,80 @@ func (m *Mat2) Size() MatSize { } 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 func (m *Mat2) Add(m2 *Mat2) { - m.Data[0] += m2.Data[0] - m.Data[1] += m2.Data[1] - m.Data[2] += m2.Data[2] - m.Data[3] += m2.Data[3] + m.Arr[0] += m2.Arr[0] + m.Arr[1] += m2.Arr[1] + m.Arr[2] += m2.Arr[2] + m.Arr[3] += m2.Arr[3] } //Add m -= m2 func (m *Mat2) Sub(m2 *Mat2) { - m.Data[0] -= m2.Data[0] - m.Data[1] -= m2.Data[1] - m.Data[2] -= m2.Data[2] - m.Data[3] -= m2.Data[3] + m.Arr[0] -= m2.Arr[0] + m.Arr[1] -= m2.Arr[1] + m.Arr[2] -= m2.Arr[2] + m.Arr[3] -= m2.Arr[3] } //Scale m *= x (element wise multiplication) func (m *Mat2) Scale(x float32) { - m.Data[0] *= x - m.Data[1] *= x - m.Data[2] *= x - m.Data[3] *= x + m.Arr[0] *= x + m.Arr[1] *= x + m.Arr[2] *= x + m.Arr[3] *= x } //AddMat2 m3 = m1 + m2 func AddMat2(m1, m2 *Mat2) *Mat2 { return NewMat2([]float32{ - m1.Data[0] + m2.Data[0], - m1.Data[1] + m2.Data[1], - m1.Data[2] + m2.Data[2], - m1.Data[3] + m2.Data[3], + m1.Arr[0] + m2.Arr[0], + m1.Arr[1] + m2.Arr[1], + m1.Arr[2] + m2.Arr[2], + m1.Arr[3] + m2.Arr[3], }) } //SubMat2 m3 = m1 - m2 func SubMat2(m1, m2 *Mat2) *Mat2 { return NewMat2([]float32{ - m1.Data[0] - m2.Data[0], - m1.Data[1] - m2.Data[1], - m1.Data[2] - m2.Data[2], - m1.Data[3] - m2.Data[3], + m1.Arr[0] - m2.Arr[0], + m1.Arr[1] - m2.Arr[1], + m1.Arr[2] - m2.Arr[2], + m1.Arr[3] - m2.Arr[3], }) } -//NewMat2 returns the identity matrix if data=nil, otherwise data is used -//as the backing array. +//NewMat2 returns the identity matrix if data is nil, otherwise data is copied. // //Note: data must be row major func NewMat2(data []float32) *Mat2 { - if data == nil { - data = []float32{ - 1, 0, - 0, 1, + arr := [4]float32{ + 1, 0, + 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{ + Arr: arr, General: &blas32.General{ Rows: 2, Cols: 2, Stride: 2, - Data: data, + Data: arr[:], }, } } diff --git a/gglm/vec2.go b/gglm/vec2.go index 195acbb..082d7ac 100755 --- a/gglm/vec2.go +++ b/gglm/vec2.go @@ -1,5 +1,7 @@ package gglm +//Note: We don't use the Swizzle interface for add/sub because the interface doesn't allow inling :( + import ( "fmt" @@ -10,23 +12,24 @@ var _ Swizzle2 = &Vec2{} var _ fmt.Stringer = &Vec2{} type Vec2 struct { + Arr [2]float32 *blas32.Vector } func (v *Vec2) X() float32 { - return v.Data[0] + return v.Arr[0] } func (v *Vec2) Y() float32 { - return v.Data[1] + return v.Arr[1] } func (v *Vec2) R() float32 { - return v.Data[0] + return v.Arr[0] } func (v *Vec2) G() float32 { - return v.Data[1] + return v.Arr[1] } func (v *Vec2) String() string { @@ -35,19 +38,20 @@ func (v *Vec2) String() string { //Scale v *= x (element wise multiplication) func (v *Vec2) Scale(x float32) { - v.Data[0] *= x - v.Data[1] *= x + v.Arr[0] *= x + v.Arr[1] *= x } -func (v *Vec2) Add(b Swizzle2) { - v.Data[0] += b.X() - v.Data[1] += b.Y() +//Add v += v2 +func (v *Vec2) Add(v2 *Vec2) { + v.Arr[0] += v2.X() + v.Arr[1] += v2.Y() } //SubVec2 v -= v2 func (v *Vec2) Sub(v2 *Vec2) { - v.Data[0] -= v2.X() - v.Data[1] -= v2.Y() + v.Arr[0] -= v2.X() + v.Arr[1] -= v2.Y() } //Mag returns the magnitude of the vector @@ -61,28 +65,41 @@ func (v *Vec2) SqrMag() float32 { } //AddVec2 v3 = v1 + v2 -func AddVec2(v1 *Vec2, v2 *Vec2) *Vec2 { - return NewVec2([]float32{v1.X() + v2.X(), v1.Y() + v2.Y()}) +func AddVec2(v1, v2 *Vec2) *Vec2 { + 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 { - 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 { - if data == nil { - data = make([]float32, 2) - } else if len(data) != 2 { - panic("Data must be nil or size 2") + arr := [2]float32{} + if data != nil { + + if len(data) != 2 { + panic("Data must be nil or size 2") + } + + arr[0] = data[0] + arr[1] = data[1] } return &Vec2{ + Arr: arr, Vector: &blas32.Vector{ N: 2, Inc: 1, - Data: data, + Data: arr[:], }, } } diff --git a/gglm/vec3.go b/gglm/vec3.go new file mode 100755 index 0000000..96effbc --- /dev/null +++ b/gglm/vec3.go @@ -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[:], + }, + } +} diff --git a/main.go b/main.go index 1ed49ea..a137d01 100755 --- a/main.go +++ b/main.go @@ -1,27 +1,26 @@ package main import ( - "fmt" - "github.com/bloeys/gglm/gglm" ) func main() { - v1 := gglm.NewVec2([]float32{4, 5}) - v2 := gglm.NewVec2([]float32{1, 1}) - println(v1.Mag()) - println(v1.SqrMag()) - + // v1 := gglm.NewVec2([]float32{4, 5}) + // v2 := gglm.NewVec2([]float32{1, 1}) + // println(v1.Mag()) + // println(v1.SqrMag()) + v1 := gglm.NewVec2(nil) + v2 := gglm.NewVec2(nil) v1.Add(v2) - v1.Sub(v2) + // v1.Sub(v2) - fmt.Println(gglm.DotVec2(v1, v2)) - fmt.Println(v1, v1.X(), v1.Y()) + // fmt.Println(gglm.DotVec2(v1, v2)) + // fmt.Println(v1, v1.X(), v1.Y()) - m := gglm.NewMat2(nil) - fmt.Println(m.String(), m.At(0, 1), m.At(1, 1)) - m.Set(0, 1, 55) - m.Set(1, 0, 77) - fmt.Println("\n"+m.String(), m.At(0, 1), m.At(1, 1)) + // m := gglm.NewMat2(nil) + // fmt.Println(m.String(), m.At(0, 1), m.At(1, 1)) + // m.Set(0, 1, 55) + // m.Set(1, 0, 77) + // fmt.Println("\n"+m.String(), m.At(0, 1), m.At(1, 1)) }