mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2025-12-08 19:26:19 +00:00
357 lines
6.4 KiB
Go
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
|
|
}
|