mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2025-12-08 19:26:19 +00:00
278 lines
5.2 KiB
Go
278 lines
5.2 KiB
Go
// Copyright 2017-2020 The ShadowEditor Authors. All rights reserved.
|
|
// Use of e 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
|
|
//
|
|
// e package is translated from three.js, visit `https://github.com/mrdoob/three.js`
|
|
// for more information.
|
|
|
|
package three
|
|
|
|
import (
|
|
"math"
|
|
)
|
|
|
|
const (
|
|
// DefaultOrder :
|
|
DefaultOrder = "xyz"
|
|
)
|
|
|
|
// RotationOrders :
|
|
var RotationOrders = []string{"XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"}
|
|
|
|
var _matrix = NewMatrix4()
|
|
var _quaternion = NewQuaternion(0, 0, 0, 1)
|
|
|
|
// NewEuler :
|
|
func NewEuler(x, y, z float64, order string) *Euler {
|
|
if order == "" {
|
|
order = DefaultOrder
|
|
}
|
|
return &Euler{x, y, z, order, nil}
|
|
}
|
|
|
|
// Euler :
|
|
type Euler struct {
|
|
_x float64
|
|
_y float64
|
|
_z float64
|
|
_order string
|
|
_onChangeCallback onChangeCallback
|
|
}
|
|
|
|
// X :
|
|
func (e Euler) X() float64 {
|
|
return e._x
|
|
}
|
|
|
|
// SetX :
|
|
func (e Euler) SetX(value float64) {
|
|
e._x = value
|
|
e._onChangeCallback()
|
|
}
|
|
|
|
// Y :
|
|
func (e Euler) Y() float64 {
|
|
return e._y
|
|
}
|
|
|
|
// SetY :
|
|
func (e Euler) SetY(value float64) {
|
|
e._y = value
|
|
e._onChangeCallback()
|
|
}
|
|
|
|
// Z :
|
|
func (e Euler) Z() float64 {
|
|
return e._z
|
|
}
|
|
|
|
// SetZ :
|
|
func (e Euler) SetZ(value float64) {
|
|
e._z = value
|
|
e._onChangeCallback()
|
|
}
|
|
|
|
// Order :
|
|
func (e Euler) Order() string {
|
|
return e._order
|
|
}
|
|
|
|
// SetOrder :
|
|
func (e Euler) SetOrder(value string) {
|
|
e._order = value
|
|
e._onChangeCallback()
|
|
}
|
|
|
|
// Set :
|
|
func (e Euler) Set(x, y, z float64, order string) *Euler {
|
|
e._x = x
|
|
e._y = y
|
|
e._z = z
|
|
if order != "" {
|
|
e._order = order
|
|
}
|
|
|
|
e._onChangeCallback()
|
|
|
|
return &e
|
|
}
|
|
|
|
// Clone :
|
|
func (e Euler) Clone() *Euler {
|
|
return NewEuler(e._x, e._y, e._z, e._order)
|
|
}
|
|
|
|
// Copy :
|
|
func (e Euler) Copy(euler Euler) *Euler {
|
|
e._x = euler._x
|
|
e._y = euler._y
|
|
e._z = euler._z
|
|
e._order = euler._order
|
|
|
|
e._onChangeCallback()
|
|
|
|
return &e
|
|
}
|
|
|
|
// SetFromRotationMatrix :
|
|
func (e Euler) SetFromRotationMatrix(m Matrix4, order string, update bool) *Euler {
|
|
clamp := Clamp
|
|
|
|
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
|
te := m.Elements
|
|
m11, m12, m13 := te[0], te[4], te[8]
|
|
m21, m22, m23 := te[1], te[5], te[9]
|
|
m31, m32, m33 := te[2], te[6], te[10]
|
|
|
|
if order == "" {
|
|
order = e._order
|
|
}
|
|
|
|
switch order {
|
|
default:
|
|
panic("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: " + order)
|
|
case "XYZ":
|
|
e._y = math.Asin(clamp(m13, -1, 1))
|
|
|
|
if math.Abs(m13) < 0.9999999 {
|
|
e._x = math.Atan2(-m23, m33)
|
|
e._z = math.Atan2(-m12, m11)
|
|
} else {
|
|
e._x = math.Atan2(m32, m22)
|
|
e._z = 0
|
|
}
|
|
case "YXZ":
|
|
e._x = math.Asin(-clamp(m23, -1, 1))
|
|
|
|
if math.Abs(m23) < 0.9999999 {
|
|
e._y = math.Atan2(m13, m33)
|
|
e._z = math.Atan2(m21, m22)
|
|
} else {
|
|
e._y = math.Atan2(-m31, m11)
|
|
e._z = 0
|
|
}
|
|
case "ZXY":
|
|
e._x = math.Asin(clamp(m32, -1, 1))
|
|
|
|
if math.Abs(m32) < 0.9999999 {
|
|
e._y = math.Atan2(-m31, m33)
|
|
e._z = math.Atan2(-m12, m22)
|
|
} else {
|
|
e._y = 0
|
|
e._z = math.Atan2(m21, m11)
|
|
}
|
|
case "ZYX":
|
|
e._y = math.Asin(-clamp(m31, -1, 1))
|
|
|
|
if math.Abs(m31) < 0.9999999 {
|
|
e._x = math.Atan2(m32, m33)
|
|
e._z = math.Atan2(m21, m11)
|
|
} else {
|
|
e._x = 0
|
|
e._z = math.Atan2(-m12, m22)
|
|
}
|
|
case "YZX":
|
|
e._z = math.Asin(clamp(m21, -1, 1))
|
|
|
|
if math.Abs(m21) < 0.9999999 {
|
|
e._x = math.Atan2(-m23, m22)
|
|
e._y = math.Atan2(-m31, m11)
|
|
} else {
|
|
e._x = 0
|
|
e._y = math.Atan2(m13, m33)
|
|
}
|
|
case "XZY":
|
|
e._z = math.Asin(-clamp(m12, -1, 1))
|
|
|
|
if math.Abs(m12) < 0.9999999 {
|
|
e._x = math.Atan2(m32, m22)
|
|
e._y = math.Atan2(m13, m11)
|
|
} else {
|
|
e._x = math.Atan2(-m23, m33)
|
|
e._y = 0
|
|
}
|
|
}
|
|
|
|
e._order = order
|
|
|
|
if update {
|
|
e._onChangeCallback()
|
|
}
|
|
|
|
return &e
|
|
}
|
|
|
|
// SetFromQuaternion :
|
|
func (e Euler) SetFromQuaternion(q Quaternion, order string, update bool) *Euler {
|
|
_matrix.MakeRotationFromQuaternion(q)
|
|
|
|
return e.SetFromRotationMatrix(*_matrix, order, update)
|
|
}
|
|
|
|
// SetFromVector3 :
|
|
func (e Euler) SetFromVector3(v Vector3, order string) *Euler {
|
|
if order == "" {
|
|
order = e._order
|
|
}
|
|
return e.Set(v.X, v.Y, v.Z, order)
|
|
}
|
|
|
|
// Reorder :
|
|
func (e Euler) Reorder(newOrder string) *Euler {
|
|
// WARNING: e discards revolution information -bhouston
|
|
_quaternion.SetFromEuler(e, false)
|
|
|
|
return e.SetFromQuaternion(*_quaternion, newOrder, true)
|
|
}
|
|
|
|
// Equals :
|
|
func (e Euler) Equals(euler Euler) bool {
|
|
return (euler._x == e._x) &&
|
|
(euler._y == e._y) &&
|
|
(euler._z == e._z) &&
|
|
(euler._order == e._order)
|
|
}
|
|
|
|
// FromArray :
|
|
func (e Euler) FromArray(array []float64, order string) *Euler {
|
|
if len(array) < 3 {
|
|
panic("array length should be greater than 3")
|
|
}
|
|
e._x = array[0]
|
|
e._y = array[1]
|
|
e._z = array[2]
|
|
|
|
if order != "" {
|
|
e._order = order
|
|
}
|
|
|
|
e._onChangeCallback()
|
|
|
|
return &e
|
|
}
|
|
|
|
// ToArray :
|
|
func (e Euler) ToArray(array []float64, offset int) ([]float64, string) {
|
|
if len(array) < offset+3 {
|
|
panic("array length should be greater than offset+3")
|
|
}
|
|
array[offset] = e._x
|
|
array[offset+1] = e._y
|
|
array[offset+2] = e._z
|
|
|
|
return array, e._order
|
|
}
|
|
|
|
// ToVector3 :
|
|
func (e Euler) ToVector3(optionalResult Vector3) *Vector3 {
|
|
return optionalResult.Set(e._x, e._y, e._z)
|
|
}
|
|
|
|
func (e Euler) _onChange(callback onChangeCallback) *Euler {
|
|
e._onChangeCallback = callback
|
|
return &e
|
|
}
|