diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/core_bind.h | 2 | ||||
-rw-r--r-- | core/debugger/remote_debugger.cpp | 4 | ||||
-rw-r--r-- | core/math/basis.cpp | 508 | ||||
-rw-r--r-- | core/math/basis.h | 42 | ||||
-rw-r--r-- | core/math/quaternion.cpp | 4 | ||||
-rw-r--r-- | core/object/undo_redo.cpp | 2 | ||||
-rw-r--r-- | core/variant/binder_common.h | 1 | ||||
-rw-r--r-- | core/variant/variant.cpp | 4 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 10 | ||||
-rw-r--r-- | core/variant/variant_construct.cpp | 3 | ||||
-rw-r--r-- | core/variant/variant_internal.h | 6 |
11 files changed, 250 insertions, 336 deletions
diff --git a/core/core_bind.h b/core/core_bind.h index 4eab085dda..3eb4c914a1 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -205,7 +205,7 @@ public: void delay_usec(int p_usec) const; void delay_msec(int p_msec) const; - uint32_t get_ticks_msec() const; + uint64_t get_ticks_msec() const; uint64_t get_ticks_usec() const; bool can_use_threads() const; diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index 9967d1e361..4607bd2f3f 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -79,8 +79,8 @@ public: ERR_FAIL_COND_V(p_buffer.size() == 0, 0); int total_bandwidth = 0; - uint32_t timestamp = OS::get_singleton()->get_ticks_msec(); - uint32_t final_timestamp = timestamp - 1000; + uint64_t timestamp = OS::get_singleton()->get_ticks_msec(); + uint64_t final_timestamp = timestamp - 1000; int i = (p_pointer + p_buffer.size() - 1) % p_buffer.size(); diff --git a/core/math/basis.cpp b/core/math/basis.cpp index a7f89522d7..0030cb1144 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -354,7 +354,7 @@ void Basis::rotate(const Quaternion &p_quaternion) { *this = rotated(p_quaternion); } -Vector3 Basis::get_rotation_euler() const { +Vector3 Basis::get_euler_normalized(EulerOrder p_order) const { // Assumes that the matrix can be decomposed into a proper rotation and scaling matrix as M = R.S, // and returns the Euler angles corresponding to the rotation part, complementing get_scale(). // See the comment in get_scale() for further information. @@ -365,7 +365,7 @@ Vector3 Basis::get_rotation_euler() const { m.scale(Vector3(-1, -1, -1)); } - return m.get_euler(); + return m.get_euler(p_order); } Quaternion Basis::get_rotation_quaternion() const { @@ -424,218 +424,203 @@ void Basis::get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) cons p_angle = -p_angle; } -// get_euler_xyz returns a vector containing the Euler angles in the format -// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last -// (following the convention they are commonly defined in the literature). -// -// The current implementation uses XYZ convention (Z is the first rotation), -// so euler.z is the angle of the (first) rotation around Z axis and so on, -// -// And thus, assuming the matrix is a rotation matrix, this function returns -// the angles in the decomposition R = X(a1).Y(a2).Z(a3) where Z(a) rotates -// around the z-axis by a and so on. -Vector3 Basis::get_euler_xyz() const { - // Euler angles in XYZ convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cy*cz -cy*sz sy - // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx - // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy - - Vector3 euler; - real_t sy = elements[0][2]; - if (sy < (1.0 - CMP_EPSILON)) { - if (sy > -(1.0 - CMP_EPSILON)) { - // is this a pure Y rotation? - if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) { - // return the simplest form (human friendlier in editor and scripts) - euler.x = 0; - euler.y = atan2(elements[0][2], elements[0][0]); - euler.z = 0; +Vector3 Basis::get_euler(EulerOrder p_order) const { + switch (p_order) { + case EULER_ORDER_XYZ: { + // Euler angles in XYZ convention. + // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + // + // rot = cy*cz -cy*sz sy + // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx + // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy + + Vector3 euler; + real_t sy = elements[0][2]; + if (sy < (1.0 - CMP_EPSILON)) { + if (sy > -(1.0 - CMP_EPSILON)) { + // is this a pure Y rotation? + if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) { + // return the simplest form (human friendlier in editor and scripts) + euler.x = 0; + euler.y = atan2(elements[0][2], elements[0][0]); + euler.z = 0; + } else { + euler.x = Math::atan2(-elements[1][2], elements[2][2]); + euler.y = Math::asin(sy); + euler.z = Math::atan2(-elements[0][1], elements[0][0]); + } + } else { + euler.x = Math::atan2(elements[2][1], elements[1][1]); + euler.y = -Math_PI / 2.0; + euler.z = 0.0; + } } else { - euler.x = Math::atan2(-elements[1][2], elements[2][2]); - euler.y = Math::asin(sy); - euler.z = Math::atan2(-elements[0][1], elements[0][0]); + euler.x = Math::atan2(elements[2][1], elements[1][1]); + euler.y = Math_PI / 2.0; + euler.z = 0.0; + } + return euler; + } break; + case EULER_ORDER_XZY: { + // Euler angles in XZY convention. + // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + // + // rot = cz*cy -sz cz*sy + // sx*sy+cx*cy*sz cx*cz cx*sz*sy-cy*sx + // cy*sx*sz cz*sx cx*cy+sx*sz*sy + + Vector3 euler; + real_t sz = elements[0][1]; + if (sz < (1.0 - CMP_EPSILON)) { + if (sz > -(1.0 - CMP_EPSILON)) { + euler.x = Math::atan2(elements[2][1], elements[1][1]); + euler.y = Math::atan2(elements[0][2], elements[0][0]); + euler.z = Math::asin(-sz); + } else { + // It's -1 + euler.x = -Math::atan2(elements[1][2], elements[2][2]); + euler.y = 0.0; + euler.z = Math_PI / 2.0; + } + } else { + // It's 1 + euler.x = -Math::atan2(elements[1][2], elements[2][2]); + euler.y = 0.0; + euler.z = -Math_PI / 2.0; + } + return euler; + } break; + case EULER_ORDER_YXZ: { + // Euler angles in YXZ convention. + // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + // + // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy + // cx*sz cx*cz -sx + // cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx + + Vector3 euler; + + real_t m12 = elements[1][2]; + + if (m12 < (1 - CMP_EPSILON)) { + if (m12 > -(1 - CMP_EPSILON)) { + // is this a pure X rotation? + if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) { + // return the simplest form (human friendlier in editor and scripts) + euler.x = atan2(-m12, elements[1][1]); + euler.y = 0; + euler.z = 0; + } else { + euler.x = asin(-m12); + euler.y = atan2(elements[0][2], elements[2][2]); + euler.z = atan2(elements[1][0], elements[1][1]); + } + } else { // m12 == -1 + euler.x = Math_PI * 0.5; + euler.y = atan2(elements[0][1], elements[0][0]); + euler.z = 0; + } + } else { // m12 == 1 + euler.x = -Math_PI * 0.5; + euler.y = -atan2(elements[0][1], elements[0][0]); + euler.z = 0; } - } else { - euler.x = Math::atan2(elements[2][1], elements[1][1]); - euler.y = -Math_PI / 2.0; - euler.z = 0.0; - } - } else { - euler.x = Math::atan2(elements[2][1], elements[1][1]); - euler.y = Math_PI / 2.0; - euler.z = 0.0; - } - return euler; -} - -// set_euler_xyz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// The current implementation uses XYZ convention (Z is the first rotation). -void Basis::set_euler_xyz(const Vector3 &p_euler) { - real_t c, s; - - c = Math::cos(p_euler.x); - s = Math::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = Math::cos(p_euler.y); - s = Math::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = Math::cos(p_euler.z); - s = Math::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - //optimizer will optimize away all this anyway - *this = xmat * (ymat * zmat); -} - -Vector3 Basis::get_euler_xzy() const { - // Euler angles in XZY convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cz*cy -sz cz*sy - // sx*sy+cx*cy*sz cx*cz cx*sz*sy-cy*sx - // cy*sx*sz cz*sx cx*cy+sx*sz*sy - - Vector3 euler; - real_t sz = elements[0][1]; - if (sz < (1.0 - CMP_EPSILON)) { - if (sz > -(1.0 - CMP_EPSILON)) { - euler.x = Math::atan2(elements[2][1], elements[1][1]); - euler.y = Math::atan2(elements[0][2], elements[0][0]); - euler.z = Math::asin(-sz); - } else { - // It's -1 - euler.x = -Math::atan2(elements[1][2], elements[2][2]); - euler.y = 0.0; - euler.z = Math_PI / 2.0; - } - } else { - // It's 1 - euler.x = -Math::atan2(elements[1][2], elements[2][2]); - euler.y = 0.0; - euler.z = -Math_PI / 2.0; - } - return euler; -} - -void Basis::set_euler_xzy(const Vector3 &p_euler) { - real_t c, s; - - c = Math::cos(p_euler.x); - s = Math::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = Math::cos(p_euler.y); - s = Math::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = Math::cos(p_euler.z); - s = Math::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - *this = xmat * zmat * ymat; -} - -Vector3 Basis::get_euler_yzx() const { - // Euler angles in YZX convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cy*cz sy*sx-cy*cx*sz cx*sy+cy*sz*sx - // sz cz*cx -cz*sx - // -cz*sy cy*sx+cx*sy*sz cy*cx-sy*sz*sx - - Vector3 euler; - real_t sz = elements[1][0]; - if (sz < (1.0 - CMP_EPSILON)) { - if (sz > -(1.0 - CMP_EPSILON)) { - euler.x = Math::atan2(-elements[1][2], elements[1][1]); - euler.y = Math::atan2(-elements[2][0], elements[0][0]); - euler.z = Math::asin(sz); - } else { - // It's -1 - euler.x = Math::atan2(elements[2][1], elements[2][2]); - euler.y = 0.0; - euler.z = -Math_PI / 2.0; - } - } else { - // It's 1 - euler.x = Math::atan2(elements[2][1], elements[2][2]); - euler.y = 0.0; - euler.z = Math_PI / 2.0; - } - return euler; -} - -void Basis::set_euler_yzx(const Vector3 &p_euler) { - real_t c, s; - - c = Math::cos(p_euler.x); - s = Math::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = Math::cos(p_euler.y); - s = Math::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = Math::cos(p_euler.z); - s = Math::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - *this = ymat * zmat * xmat; -} - -// get_euler_yxz returns a vector containing the Euler angles in the YXZ convention, -// as in first-Z, then-X, last-Y. The angles for X, Y, and Z rotations are returned -// as the x, y, and z components of a Vector3 respectively. -Vector3 Basis::get_euler_yxz() const { - // Euler angles in YXZ convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy - // cx*sz cx*cz -sx - // cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx - - Vector3 euler; - - real_t m12 = elements[1][2]; - if (m12 < (1 - CMP_EPSILON)) { - if (m12 > -(1 - CMP_EPSILON)) { - // is this a pure X rotation? - if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) { - // return the simplest form (human friendlier in editor and scripts) - euler.x = atan2(-m12, elements[1][1]); - euler.y = 0; + return euler; + } break; + case EULER_ORDER_YZX: { + // Euler angles in YZX convention. + // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + // + // rot = cy*cz sy*sx-cy*cx*sz cx*sy+cy*sz*sx + // sz cz*cx -cz*sx + // -cz*sy cy*sx+cx*sy*sz cy*cx-sy*sz*sx + + Vector3 euler; + real_t sz = elements[1][0]; + if (sz < (1.0 - CMP_EPSILON)) { + if (sz > -(1.0 - CMP_EPSILON)) { + euler.x = Math::atan2(-elements[1][2], elements[1][1]); + euler.y = Math::atan2(-elements[2][0], elements[0][0]); + euler.z = Math::asin(sz); + } else { + // It's -1 + euler.x = Math::atan2(elements[2][1], elements[2][2]); + euler.y = 0.0; + euler.z = -Math_PI / 2.0; + } + } else { + // It's 1 + euler.x = Math::atan2(elements[2][1], elements[2][2]); + euler.y = 0.0; + euler.z = Math_PI / 2.0; + } + return euler; + } break; + case EULER_ORDER_ZXY: { + // Euler angles in ZXY convention. + // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + // + // rot = cz*cy-sz*sx*sy -cx*sz cz*sy+cy*sz*sx + // cy*sz+cz*sx*sy cz*cx sz*sy-cz*cy*sx + // -cx*sy sx cx*cy + Vector3 euler; + real_t sx = elements[2][1]; + if (sx < (1.0 - CMP_EPSILON)) { + if (sx > -(1.0 - CMP_EPSILON)) { + euler.x = Math::asin(sx); + euler.y = Math::atan2(-elements[2][0], elements[2][2]); + euler.z = Math::atan2(-elements[0][1], elements[1][1]); + } else { + // It's -1 + euler.x = -Math_PI / 2.0; + euler.y = Math::atan2(elements[0][2], elements[0][0]); + euler.z = 0; + } + } else { + // It's 1 + euler.x = Math_PI / 2.0; + euler.y = Math::atan2(elements[0][2], elements[0][0]); euler.z = 0; + } + return euler; + } break; + case EULER_ORDER_ZYX: { + // Euler angles in ZYX convention. + // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix + // + // rot = cz*cy cz*sy*sx-cx*sz sz*sx+cz*cx*cy + // cy*sz cz*cx+sz*sy*sx cx*sz*sy-cz*sx + // -sy cy*sx cy*cx + Vector3 euler; + real_t sy = elements[2][0]; + if (sy < (1.0 - CMP_EPSILON)) { + if (sy > -(1.0 - CMP_EPSILON)) { + euler.x = Math::atan2(elements[2][1], elements[2][2]); + euler.y = Math::asin(-sy); + euler.z = Math::atan2(elements[1][0], elements[0][0]); + } else { + // It's -1 + euler.x = 0; + euler.y = Math_PI / 2.0; + euler.z = -Math::atan2(elements[0][1], elements[1][1]); + } } else { - euler.x = asin(-m12); - euler.y = atan2(elements[0][2], elements[2][2]); - euler.z = atan2(elements[1][0], elements[1][1]); + // It's 1 + euler.x = 0; + euler.y = -Math_PI / 2.0; + euler.z = -Math::atan2(elements[0][1], elements[1][1]); } - } else { // m12 == -1 - euler.x = Math_PI * 0.5; - euler.y = atan2(elements[0][1], elements[0][0]); - euler.z = 0; + return euler; + } break; + default: { + ERR_FAIL_V_MSG(Vector3(), "Invalid parameter for get_euler(order)"); } - } else { // m12 == 1 - euler.x = -Math_PI * 0.5; - euler.y = -atan2(elements[0][1], elements[0][0]); - euler.z = 0; } - - return euler; + return Vector3(); } -// set_euler_yxz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// The current implementation uses YXZ convention (Z is the first rotation). -void Basis::set_euler_yxz(const Vector3 &p_euler) { +void Basis::set_euler(const Vector3 &p_euler, EulerOrder p_order) { real_t c, s; c = Math::cos(p_euler.x); @@ -650,102 +635,29 @@ void Basis::set_euler_yxz(const Vector3 &p_euler) { s = Math::sin(p_euler.z); Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - //optimizer will optimize away all this anyway - *this = ymat * xmat * zmat; -} - -Vector3 Basis::get_euler_zxy() const { - // Euler angles in ZXY convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cz*cy-sz*sx*sy -cx*sz cz*sy+cy*sz*sx - // cy*sz+cz*sx*sy cz*cx sz*sy-cz*cy*sx - // -cx*sy sx cx*cy - Vector3 euler; - real_t sx = elements[2][1]; - if (sx < (1.0 - CMP_EPSILON)) { - if (sx > -(1.0 - CMP_EPSILON)) { - euler.x = Math::asin(sx); - euler.y = Math::atan2(-elements[2][0], elements[2][2]); - euler.z = Math::atan2(-elements[0][1], elements[1][1]); - } else { - // It's -1 - euler.x = -Math_PI / 2.0; - euler.y = Math::atan2(elements[0][2], elements[0][0]); - euler.z = 0; + switch (p_order) { + case EULER_ORDER_XYZ: { + *this = xmat * (ymat * zmat); + } break; + case EULER_ORDER_XZY: { + *this = xmat * zmat * ymat; + } break; + case EULER_ORDER_YXZ: { + *this = ymat * xmat * zmat; + } break; + case EULER_ORDER_YZX: { + *this = ymat * zmat * xmat; + } break; + case EULER_ORDER_ZXY: { + *this = zmat * xmat * ymat; + } break; + case EULER_ORDER_ZYX: { + *this = zmat * ymat * xmat; + } break; + default: { + ERR_FAIL_MSG("Invalid order parameter for set_euler(vec3,order)"); } - } else { - // It's 1 - euler.x = Math_PI / 2.0; - euler.y = Math::atan2(elements[0][2], elements[0][0]); - euler.z = 0; } - return euler; -} - -void Basis::set_euler_zxy(const Vector3 &p_euler) { - real_t c, s; - - c = Math::cos(p_euler.x); - s = Math::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = Math::cos(p_euler.y); - s = Math::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = Math::cos(p_euler.z); - s = Math::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - *this = zmat * xmat * ymat; -} - -Vector3 Basis::get_euler_zyx() const { - // Euler angles in ZYX convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cz*cy cz*sy*sx-cx*sz sz*sx+cz*cx*cy - // cy*sz cz*cx+sz*sy*sx cx*sz*sy-cz*sx - // -sy cy*sx cy*cx - Vector3 euler; - real_t sy = elements[2][0]; - if (sy < (1.0 - CMP_EPSILON)) { - if (sy > -(1.0 - CMP_EPSILON)) { - euler.x = Math::atan2(elements[2][1], elements[2][2]); - euler.y = Math::asin(-sy); - euler.z = Math::atan2(elements[1][0], elements[0][0]); - } else { - // It's -1 - euler.x = 0; - euler.y = Math_PI / 2.0; - euler.z = -Math::atan2(elements[0][1], elements[1][1]); - } - } else { - // It's 1 - euler.x = 0; - euler.y = -Math_PI / 2.0; - euler.z = -Math::atan2(elements[0][1], elements[1][1]); - } - return euler; -} - -void Basis::set_euler_zyx(const Vector3 &p_euler) { - real_t c, s; - - c = Math::cos(p_euler.x); - s = Math::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = Math::cos(p_euler.y); - s = Math::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = Math::cos(p_euler.z); - s = Math::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - *this = zmat * ymat * xmat; } bool Basis::is_equal_approx(const Basis &p_basis) const { diff --git a/core/math/basis.h b/core/math/basis.h index eb107d7e4e..617d005f19 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -85,40 +85,35 @@ public: void rotate(const Quaternion &p_quaternion); Basis rotated(const Quaternion &p_quaternion) const; - Vector3 get_rotation_euler() const; + enum EulerOrder { + EULER_ORDER_XYZ, + EULER_ORDER_XZY, + EULER_ORDER_YXZ, + EULER_ORDER_YZX, + EULER_ORDER_ZXY, + EULER_ORDER_ZYX + }; + + Vector3 get_euler_normalized(EulerOrder p_order = EULER_ORDER_YXZ) const; void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const; void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const; Quaternion get_rotation_quaternion() const; - Vector3 get_rotation() const { return get_rotation_euler(); }; void rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction); Vector3 rotref_posscale_decomposition(Basis &rotref) const; - Vector3 get_euler_xyz() const; - void set_euler_xyz(const Vector3 &p_euler); - - Vector3 get_euler_xzy() const; - void set_euler_xzy(const Vector3 &p_euler); - - Vector3 get_euler_yzx() const; - void set_euler_yzx(const Vector3 &p_euler); - - Vector3 get_euler_yxz() const; - void set_euler_yxz(const Vector3 &p_euler); - - Vector3 get_euler_zxy() const; - void set_euler_zxy(const Vector3 &p_euler); - - Vector3 get_euler_zyx() const; - void set_euler_zyx(const Vector3 &p_euler); + Vector3 get_euler(EulerOrder p_order = EULER_ORDER_YXZ) const; + void set_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ); + static Basis from_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ) { + Basis b; + b.set_euler(p_euler, p_order); + return b; + } Quaternion get_quaternion() const; void set_quaternion(const Quaternion &p_quaternion); - Vector3 get_euler() const { return get_euler_yxz(); } - void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); } - void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const; void set_axis_angle(const Vector3 &p_axis, real_t p_phi); @@ -250,9 +245,6 @@ public: Basis(const Quaternion &p_quaternion) { set_quaternion(p_quaternion); }; Basis(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_quaternion_scale(p_quaternion, p_scale); } - Basis(const Vector3 &p_euler) { set_euler(p_euler); } - Basis(const Vector3 &p_euler, const Vector3 &p_scale) { set_euler_scale(p_euler, p_scale); } - Basis(const Vector3 &p_axis, real_t p_phi) { set_axis_angle(p_axis, p_phi); } Basis(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_phi, p_scale); } static Basis from_scale(const Vector3 &p_scale); diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index a29a70c1f0..944474686a 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -44,7 +44,7 @@ real_t Quaternion::angle_to(const Quaternion &p_to) const { // This implementation uses XYZ convention (Z is the first rotation). Vector3 Quaternion::get_euler_xyz() const { Basis m(*this); - return m.get_euler_xyz(); + return m.get_euler(Basis::EULER_ORDER_XYZ); } // get_euler_yxz returns a vector containing the Euler angles in the format @@ -56,7 +56,7 @@ Vector3 Quaternion::get_euler_yxz() const { ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion must be normalized."); #endif Basis m(*this); - return m.get_euler_yxz(); + return m.get_euler(Basis::EULER_ORDER_YXZ); } void Quaternion::operator*=(const Quaternion &p_q) { diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index 9c84c2add7..07006e7968 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -76,7 +76,7 @@ bool UndoRedo::_redo(bool p_execute) { } void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { - uint32_t ticks = OS::get_singleton()->get_ticks_msec(); + uint64_t ticks = OS::get_singleton()->get_ticks_msec(); if (action_level == 0) { _discard_redo(); diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 8592a1dc62..f06d767cf5 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -88,6 +88,7 @@ struct VariantCaster<const T &> { VARIANT_ENUM_CAST(Object::ConnectFlags); VARIANT_ENUM_CAST(Vector3::Axis); +VARIANT_ENUM_CAST(Basis::EulerOrder); VARIANT_ENUM_CAST(Error); VARIANT_ENUM_CAST(Side); diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 3214fc125d..81428caca1 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -313,7 +313,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { case BASIS: { static const Type valid[] = { QUATERNION, - VECTOR3, NIL }; @@ -620,7 +619,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type case BASIS: { static const Type valid[] = { QUATERNION, - VECTOR3, NIL }; @@ -1889,8 +1887,6 @@ Variant::operator Basis() const { return *_data._basis; } else if (type == QUATERNION) { return *reinterpret_cast<const Quaternion *>(_data._mem); - } else if (type == VECTOR3) { - return Basis(*reinterpret_cast<const Vector3 *>(_data._mem)); } else if (type == TRANSFORM3D) { // unexposed in Variant::can_convert? return _data._transform3d->basis; } else { diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 8432ccce85..ec3a6a5ca8 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1731,7 +1731,7 @@ static void _register_variant_builtin_methods() { bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "phi"), varray()); bind_method(Basis, scaled, sarray("scale"), varray()); bind_method(Basis, get_scale, sarray(), varray()); - bind_method(Basis, get_euler, sarray(), varray()); + bind_method(Basis, get_euler, sarray("order"), varray(Basis::EULER_ORDER_YXZ)); bind_method(Basis, tdotx, sarray("with"), varray()); bind_method(Basis, tdoty, sarray("with"), varray()); bind_method(Basis, tdotz, sarray("with"), varray()); @@ -1741,6 +1741,7 @@ static void _register_variant_builtin_methods() { bind_method(Basis, get_rotation_quaternion, sarray(), varray()); bind_static_method(Basis, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); bind_static_method(Basis, from_scale, sarray("scale"), varray()); + bind_static_method(Basis, from_euler, sarray("euler", "order"), varray(Basis::EULER_ORDER_YXZ)); /* AABB */ @@ -2109,6 +2110,13 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR2I, "UP", Vector2i(0, -1)); _VariantCall::add_variant_constant(Variant::VECTOR2I, "DOWN", Vector2i(0, 1)); + _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_XYZ", Basis::EULER_ORDER_XYZ); + _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_XZY", Basis::EULER_ORDER_XZY); + _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_YXZ", Basis::EULER_ORDER_YXZ); + _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_YZX", Basis::EULER_ORDER_YZX); + _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_ZXY", Basis::EULER_ORDER_ZXY); + _VariantCall::add_constant(Variant::BASIS, "EULER_ORDER_ZYX", Basis::EULER_ORDER_ZYX); + _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D()); _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0)); _VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0)); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 6aba7d7d58..5c14f30180 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -128,10 +128,10 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructNoArgs<Quaternion>>(sarray()); add_constructor<VariantConstructor<Quaternion, Quaternion>>(sarray("from")); add_constructor<VariantConstructor<Quaternion, Basis>>(sarray("from")); - add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler")); add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle")); add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to")); add_constructor<VariantConstructor<Quaternion, double, double, double, double>>(sarray("x", "y", "z", "w")); + add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler_yxz")); add_constructor<VariantConstructNoArgs<::AABB>>(sarray()); add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from")); @@ -140,7 +140,6 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructNoArgs<Basis>>(sarray()); add_constructor<VariantConstructor<Basis, Basis>>(sarray("from")); add_constructor<VariantConstructor<Basis, Quaternion>>(sarray("from")); - add_constructor<VariantConstructor<Basis, Vector3>>(sarray("euler")); add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "phi")); add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis")); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 37383ff2ec..2ba24b5af8 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -757,6 +757,12 @@ VARIANT_ACCESSOR_NUMBER(Error) VARIANT_ACCESSOR_NUMBER(Side) template <> +struct VariantInternalAccessor<Basis::EulerOrder> { + static _FORCE_INLINE_ Basis::EulerOrder get(const Variant *v) { return Basis::EulerOrder(*VariantInternal::get_int(v)); } + static _FORCE_INLINE_ void set(Variant *v, Basis::EulerOrder p_value) { *VariantInternal::get_int(v) = p_value; } +}; + +template <> struct VariantInternalAccessor<ObjectID> { static _FORCE_INLINE_ ObjectID get(const Variant *v) { return ObjectID(*VariantInternal::get_int(v)); } static _FORCE_INLINE_ void set(Variant *v, ObjectID p_value) { *VariantInternal::get_int(v) = p_value; } |