|
@@ -455,6 +455,11 @@ void Basis::get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) cons
|
|
}
|
|
}
|
|
|
|
|
|
Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
|
|
+ // This epsilon value results in angles within a +/- 0.04 degree range being simplified/truncated.
|
|
|
|
+ // Based on testing, this is the largest the epsilon can be without the angle truncation becoming
|
|
|
|
+ // visually noticeable.
|
|
|
|
+ const real_t epsilon = 0.00000025;
|
|
|
|
+
|
|
switch (p_order) {
|
|
switch (p_order) {
|
|
case EulerOrder::XYZ: {
|
|
case EulerOrder::XYZ: {
|
|
// Euler angles in XYZ convention.
|
|
// Euler angles in XYZ convention.
|
|
@@ -466,8 +471,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
|
|
|
|
Vector3 euler;
|
|
Vector3 euler;
|
|
real_t sy = rows[0][2];
|
|
real_t sy = rows[0][2];
|
|
- if (sy < (1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
- if (sy > -(1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
|
|
+ if (sy < (1.0f - epsilon)) {
|
|
|
|
+ if (sy > -(1.0f - epsilon)) {
|
|
// is this a pure Y rotation?
|
|
// is this a pure Y rotation?
|
|
if (rows[1][0] == 0 && rows[0][1] == 0 && rows[1][2] == 0 && rows[2][1] == 0 && rows[1][1] == 1) {
|
|
if (rows[1][0] == 0 && rows[0][1] == 0 && rows[1][2] == 0 && rows[2][1] == 0 && rows[1][1] == 1) {
|
|
// return the simplest form (human friendlier in editor and scripts)
|
|
// return the simplest form (human friendlier in editor and scripts)
|
|
@@ -501,8 +506,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
|
|
|
|
Vector3 euler;
|
|
Vector3 euler;
|
|
real_t sz = rows[0][1];
|
|
real_t sz = rows[0][1];
|
|
- if (sz < (1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
- if (sz > -(1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
|
|
+ if (sz < (1.0f - epsilon)) {
|
|
|
|
+ if (sz > -(1.0f - epsilon)) {
|
|
euler.x = Math::atan2(rows[2][1], rows[1][1]);
|
|
euler.x = Math::atan2(rows[2][1], rows[1][1]);
|
|
euler.y = Math::atan2(rows[0][2], rows[0][0]);
|
|
euler.y = Math::atan2(rows[0][2], rows[0][0]);
|
|
euler.z = Math::asin(-sz);
|
|
euler.z = Math::asin(-sz);
|
|
@@ -532,8 +537,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
|
|
|
|
real_t m12 = rows[1][2];
|
|
real_t m12 = rows[1][2];
|
|
|
|
|
|
- if (m12 < (1 - (real_t)CMP_EPSILON)) {
|
|
|
|
- if (m12 > -(1 - (real_t)CMP_EPSILON)) {
|
|
|
|
|
|
+ if (m12 < (1 - epsilon)) {
|
|
|
|
+ if (m12 > -(1 - epsilon)) {
|
|
// is this a pure X rotation?
|
|
// is this a pure X rotation?
|
|
if (rows[1][0] == 0 && rows[0][1] == 0 && rows[0][2] == 0 && rows[2][0] == 0 && rows[0][0] == 1) {
|
|
if (rows[1][0] == 0 && rows[0][1] == 0 && rows[0][2] == 0 && rows[2][0] == 0 && rows[0][0] == 1) {
|
|
// return the simplest form (human friendlier in editor and scripts)
|
|
// return the simplest form (human friendlier in editor and scripts)
|
|
@@ -568,8 +573,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
|
|
|
|
Vector3 euler;
|
|
Vector3 euler;
|
|
real_t sz = rows[1][0];
|
|
real_t sz = rows[1][0];
|
|
- if (sz < (1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
- if (sz > -(1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
|
|
+ if (sz < (1.0f - epsilon)) {
|
|
|
|
+ if (sz > -(1.0f - epsilon)) {
|
|
euler.x = Math::atan2(-rows[1][2], rows[1][1]);
|
|
euler.x = Math::atan2(-rows[1][2], rows[1][1]);
|
|
euler.y = Math::atan2(-rows[2][0], rows[0][0]);
|
|
euler.y = Math::atan2(-rows[2][0], rows[0][0]);
|
|
euler.z = Math::asin(sz);
|
|
euler.z = Math::asin(sz);
|
|
@@ -596,8 +601,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
// -cx*sy sx cx*cy
|
|
// -cx*sy sx cx*cy
|
|
Vector3 euler;
|
|
Vector3 euler;
|
|
real_t sx = rows[2][1];
|
|
real_t sx = rows[2][1];
|
|
- if (sx < (1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
- if (sx > -(1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
|
|
+ if (sx < (1.0f - epsilon)) {
|
|
|
|
+ if (sx > -(1.0f - epsilon)) {
|
|
euler.x = Math::asin(sx);
|
|
euler.x = Math::asin(sx);
|
|
euler.y = Math::atan2(-rows[2][0], rows[2][2]);
|
|
euler.y = Math::atan2(-rows[2][0], rows[2][2]);
|
|
euler.z = Math::atan2(-rows[0][1], rows[1][1]);
|
|
euler.z = Math::atan2(-rows[0][1], rows[1][1]);
|
|
@@ -624,8 +629,8 @@ Vector3 Basis::get_euler(EulerOrder p_order) const {
|
|
// -sy cy*sx cy*cx
|
|
// -sy cy*sx cy*cx
|
|
Vector3 euler;
|
|
Vector3 euler;
|
|
real_t sy = rows[2][0];
|
|
real_t sy = rows[2][0];
|
|
- if (sy < (1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
- if (sy > -(1.0f - (real_t)CMP_EPSILON)) {
|
|
|
|
|
|
+ if (sy < (1.0f - epsilon)) {
|
|
|
|
+ if (sy > -(1.0f - epsilon)) {
|
|
euler.x = Math::atan2(rows[2][1], rows[2][2]);
|
|
euler.x = Math::atan2(rows[2][1], rows[2][2]);
|
|
euler.y = Math::asin(-sy);
|
|
euler.y = Math::asin(-sy);
|
|
euler.z = Math::atan2(rows[1][0], rows[0][0]);
|
|
euler.z = Math::atan2(rows[1][0], rows[0][0]);
|