2020-06-13 21:40:56 +08:00

357 lines
6.4 KiB
Go

// Copyright 2017-2020 The ShadowEditor Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//
// For more information, please visit: https://github.com/tengge1/ShadowEditor
// You can also visit: https://gitee.com/tengge1/ShadowEditor
//
// This package is translated from three.js, visit `https://github.com/mrdoob/three.js`
// for more information.
package three
import "math"
// NewMatrix3 :
func NewMatrix3() *Matrix3 {
elements := [9]float64{
1, 0, 0,
0, 1, 0,
0, 0, 1,
}
return &Matrix3{elements}
}
// Matrix3 :
type Matrix3 struct {
Elements [9]float64
}
// Set :
func (m Matrix3) Set(n11, n12, n13, n21, n22, n23, n31, n32, n33 float64) *Matrix3 {
te := m.Elements
te[0] = n11
te[1] = n21
te[2] = n31
te[3] = n12
te[4] = n22
te[5] = n32
te[6] = n13
te[7] = n23
te[8] = n33
return &m
}
// Identity :
func (m Matrix3) Identity() *Matrix3 {
m.Set(
1, 0, 0,
0, 1, 0,
0, 0, 1,
)
return &m
}
// Clone :
func (m Matrix3) Clone() *Matrix3 {
array := make([]float64, 0)
for _, elem := range m.Elements {
array = append(array, elem)
}
return NewMatrix3().FromArray(array, 0)
}
// Copy :
func (m Matrix3) Copy(n Matrix3) *Matrix3 {
te := m.Elements
me := n.Elements
te[0] = me[0]
te[1] = me[1]
te[2] = me[2]
te[3] = me[3]
te[4] = me[4]
te[5] = me[5]
te[6] = me[6]
te[7] = me[7]
te[8] = me[8]
return &m
}
// ExtractBasis :
func (m Matrix3) ExtractBasis(xAxis, yAxis, zAxis Vector3) *Matrix3 {
xAxis.SetFromMatrix3Column(m, 0)
yAxis.SetFromMatrix3Column(m, 1)
zAxis.SetFromMatrix3Column(m, 2)
return &m
}
// SetFromMatrix4 :
func (m Matrix3) SetFromMatrix4(n Matrix4) *Matrix3 {
me := n.Elements
m.Set(
me[0], me[4], me[8],
me[1], me[5], me[9],
me[2], me[6], me[10],
)
return &m
}
// Multiply :
func (m Matrix3) Multiply(n Matrix3) *Matrix3 {
return m.MultiplyMatrices(m, n)
}
// Premultiply :
func (m Matrix3) Premultiply(n Matrix3) *Matrix3 {
return m.MultiplyMatrices(n, m)
}
// MultiplyMatrices :
func (m Matrix3) MultiplyMatrices(a, b Matrix3) *Matrix3 {
ae := a.Elements
be := b.Elements
te := m.Elements
a11, a12, a13 := ae[0], ae[3], ae[6]
a21, a22, a23 := ae[1], ae[4], ae[7]
a31, a32, a33 := ae[2], ae[5], ae[8]
b11, b12, b13 := be[0], be[3], be[6]
b21, b22, b23 := be[1], be[4], be[7]
b31, b32, b33 := be[2], be[5], be[8]
te[0] = a11*b11 + a12*b21 + a13*b31
te[3] = a11*b12 + a12*b22 + a13*b32
te[6] = a11*b13 + a12*b23 + a13*b33
te[1] = a21*b11 + a22*b21 + a23*b31
te[4] = a21*b12 + a22*b22 + a23*b32
te[7] = a21*b13 + a22*b23 + a23*b33
te[2] = a31*b11 + a32*b21 + a33*b31
te[5] = a31*b12 + a32*b22 + a33*b32
te[8] = a31*b13 + a32*b23 + a33*b33
return &m
}
// MultiplyScalar :
func (m Matrix3) MultiplyScalar(s float64) *Matrix3 {
te := m.Elements
te[0] *= s
te[3] *= s
te[6] *= s
te[1] *= s
te[4] *= s
te[7] *= s
te[2] *= s
te[5] *= s
te[8] *= s
return &m
}
// Determinant :
func (m Matrix3) Determinant() float64 {
te := m.Elements
a, b, c := te[0], te[1], te[2]
d, e, f := te[3], te[4], te[5]
g, h, i := te[6], te[7], te[8]
return a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g
}
// GetInverse :
func (m Matrix3) GetInverse(matrix Matrix3) *Matrix3 {
me := matrix.Elements
te := m.Elements
n11, n21, n31 := me[0], me[1], me[2]
n12, n22, n32 := me[3], me[4], me[5]
n13, n23, n33 := me[6], me[7], me[8]
t11 := n33*n22 - n32*n23
t12 := n32*n13 - n33*n12
t13 := n23*n12 - n22*n13
det := n11*t11 + n21*t12 + n31*t13
if det == 0 {
return m.Set(0, 0, 0, 0, 0, 0, 0, 0, 0)
}
detInv := 1 / det
te[0] = t11 * detInv
te[1] = (n31*n23 - n33*n21) * detInv
te[2] = (n32*n21 - n31*n22) * detInv
te[3] = t12 * detInv
te[4] = (n33*n11 - n31*n13) * detInv
te[5] = (n31*n12 - n32*n11) * detInv
te[6] = t13 * detInv
te[7] = (n21*n13 - n23*n11) * detInv
te[8] = (n22*n11 - n21*n12) * detInv
return &m
}
// Transpose :
func (m Matrix3) Transpose() *Matrix3 {
te := m.Elements
tmp := te[1]
te[1] = te[3]
te[3] = tmp
tmp = te[2]
te[2] = te[6]
te[6] = tmp
tmp = te[5]
te[5] = te[7]
te[7] = tmp
return &m
}
// GetNormalMatrix :
func (m Matrix3) GetNormalMatrix(matrix4 Matrix4) *Matrix3 {
return m.SetFromMatrix4(matrix4).GetInverse(m).Transpose()
}
// TransposeIntoArray :
func (m Matrix3) TransposeIntoArray(r []float64) *Matrix3 {
if len(r) < 9 {
panic("array length should be greater than 9")
}
te := m.Elements
r[0] = te[0]
r[1] = te[3]
r[2] = te[6]
r[3] = te[1]
r[4] = te[4]
r[5] = te[7]
r[6] = te[2]
r[7] = te[5]
r[8] = te[8]
return &m
}
// SetUvTransform :
func (m Matrix3) SetUvTransform(tx, ty, sx, sy, rotation, cx, cy float64) *Matrix3 {
c := math.Cos(rotation)
s := math.Sin(rotation)
m.Set(
sx*c, sx*s, -sx*(c*cx+s*cy)+cx+tx,
-sy*s, sy*c, -sy*(-s*cx+c*cy)+cy+ty,
0, 0, 1,
)
return &m
}
// Scale :
func (m Matrix3) Scale(sx, sy float64) *Matrix3 {
var te = m.Elements
te[0] *= sx
te[3] *= sx
te[6] *= sx
te[1] *= sy
te[4] *= sy
te[7] *= sy
return &m
}
// Rotate :
func (m Matrix3) Rotate(theta float64) *Matrix3 {
c := math.Cos(theta)
s := math.Sin(theta)
te := m.Elements
a11, a12, a13 := te[0], te[3], te[6]
a21, a22, a23 := te[1], te[4], te[7]
te[0] = c*a11 + s*a21
te[3] = c*a12 + s*a22
te[6] = c*a13 + s*a23
te[1] = -s*a11 + c*a21
te[4] = -s*a12 + c*a22
te[7] = -s*a13 + c*a23
return &m
}
// Translate :
func (m Matrix3) Translate(tx, ty float64) *Matrix3 {
te := m.Elements
te[0] += tx * te[2]
te[3] += tx * te[5]
te[6] += tx * te[8]
te[1] += ty * te[2]
te[4] += ty * te[5]
te[7] += ty * te[8]
return &m
}
// Equals :
func (m Matrix3) Equals(matrix Matrix3) bool {
te := m.Elements
me := matrix.Elements
for i := 0; i < 9; i++ {
if te[i] != me[i] {
return false
}
}
return true
}
// FromArray :
func (m Matrix3) FromArray(array []float64, offset int) *Matrix3 {
if len(array) < offset+9 {
panic("array length should be greater than offset+9")
}
for i := 0; i < 9; i++ {
m.Elements[i] = array[i+offset]
}
return &m
}
// ToArray :
func (m Matrix3) ToArray(array []float64, offset int) []float64 {
if len(array) < offset+9 {
panic("array length should be greater than offset+9")
}
te := m.Elements
array[offset] = te[0]
array[offset+1] = te[1]
array[offset+2] = te[2]
array[offset+3] = te[3]
array[offset+4] = te[4]
array[offset+5] = te[5]
array[offset+6] = te[6]
array[offset+7] = te[7]
array[offset+8] = te[8]
return array
}