Replace Quaternion Euler constructor with from_euler
method
This commit is contained in:
parent
e6751549cf
commit
83634119d4
@ -330,7 +330,7 @@ Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) {
|
|||||||
// (ax, ay, az), where ax is the angle of rotation around x axis,
|
// (ax, ay, az), where ax is the angle of rotation around x axis,
|
||||||
// and similar for other axes.
|
// and similar for other axes.
|
||||||
// This implementation uses YXZ convention (Z is the first rotation).
|
// This implementation uses YXZ convention (Z is the first rotation).
|
||||||
Quaternion::Quaternion(const Vector3 &p_euler) {
|
Quaternion Quaternion::from_euler(const Vector3 &p_euler) {
|
||||||
real_t half_a1 = p_euler.y * 0.5f;
|
real_t half_a1 = p_euler.y * 0.5f;
|
||||||
real_t half_a2 = p_euler.x * 0.5f;
|
real_t half_a2 = p_euler.x * 0.5f;
|
||||||
real_t half_a3 = p_euler.z * 0.5f;
|
real_t half_a3 = p_euler.z * 0.5f;
|
||||||
@ -346,8 +346,9 @@ Quaternion::Quaternion(const Vector3 &p_euler) {
|
|||||||
real_t cos_a3 = Math::cos(half_a3);
|
real_t cos_a3 = Math::cos(half_a3);
|
||||||
real_t sin_a3 = Math::sin(half_a3);
|
real_t sin_a3 = Math::sin(half_a3);
|
||||||
|
|
||||||
x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
|
return Quaternion(
|
||||||
y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
|
sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3,
|
||||||
z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
|
sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3,
|
||||||
w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
|
-sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3,
|
||||||
|
sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ struct _NO_DISCARD_ Quaternion {
|
|||||||
Vector3 get_euler_xyz() const;
|
Vector3 get_euler_xyz() const;
|
||||||
Vector3 get_euler_yxz() const;
|
Vector3 get_euler_yxz() const;
|
||||||
Vector3 get_euler() const { return get_euler_yxz(); };
|
Vector3 get_euler() const { return get_euler_yxz(); };
|
||||||
|
static Quaternion from_euler(const Vector3 &p_euler);
|
||||||
|
|
||||||
Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const;
|
Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const;
|
||||||
Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const;
|
Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const;
|
||||||
@ -128,8 +129,6 @@ struct _NO_DISCARD_ Quaternion {
|
|||||||
|
|
||||||
Quaternion(const Vector3 &p_axis, real_t p_angle);
|
Quaternion(const Vector3 &p_axis, real_t p_angle);
|
||||||
|
|
||||||
Quaternion(const Vector3 &p_euler);
|
|
||||||
|
|
||||||
Quaternion(const Quaternion &p_q) :
|
Quaternion(const Quaternion &p_q) :
|
||||||
x(p_q.x),
|
x(p_q.x),
|
||||||
y(p_q.y),
|
y(p_q.y),
|
||||||
|
@ -1806,6 +1806,7 @@ static void _register_variant_builtin_methods() {
|
|||||||
bind_method(Quaternion, spherical_cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
|
bind_method(Quaternion, spherical_cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
|
||||||
bind_method(Quaternion, spherical_cubic_interpolate_in_time, sarray("b", "pre_a", "post_b", "weight", "b_t", "pre_a_t", "post_b_t"), varray());
|
bind_method(Quaternion, spherical_cubic_interpolate_in_time, sarray("b", "pre_a", "post_b", "weight", "b_t", "pre_a_t", "post_b_t"), varray());
|
||||||
bind_method(Quaternion, get_euler, sarray(), varray());
|
bind_method(Quaternion, get_euler, sarray(), varray());
|
||||||
|
bind_static_method(Quaternion, from_euler, sarray("euler"), varray());
|
||||||
bind_method(Quaternion, get_axis, sarray(), varray());
|
bind_method(Quaternion, get_axis, sarray(), varray());
|
||||||
bind_method(Quaternion, get_angle, sarray(), varray());
|
bind_method(Quaternion, get_angle, sarray(), varray());
|
||||||
|
|
||||||
|
@ -141,7 +141,6 @@ void Variant::_register_variant_constructors() {
|
|||||||
add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle"));
|
add_constructor<VariantConstructor<Quaternion, Vector3, double>>(sarray("axis", "angle"));
|
||||||
add_constructor<VariantConstructor<Quaternion, Vector3, Vector3>>(sarray("arc_from", "arc_to"));
|
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, double, double, double, double>>(sarray("x", "y", "z", "w"));
|
||||||
add_constructor<VariantConstructor<Quaternion, Vector3>>(sarray("euler_yxz"));
|
|
||||||
|
|
||||||
add_constructor<VariantConstructNoArgs<::AABB>>(sarray());
|
add_constructor<VariantConstructNoArgs<::AABB>>(sarray());
|
||||||
add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from"));
|
add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from"));
|
||||||
|
@ -41,12 +41,6 @@
|
|||||||
Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector.
|
Constructs a quaternion that will rotate around the given axis by the specified angle. The axis must be a normalized vector.
|
||||||
</description>
|
</description>
|
||||||
</constructor>
|
</constructor>
|
||||||
<constructor name="Quaternion">
|
|
||||||
<return type="Quaternion" />
|
|
||||||
<param index="0" name="euler_yxz" type="Vector3" />
|
|
||||||
<description>
|
|
||||||
</description>
|
|
||||||
</constructor>
|
|
||||||
<constructor name="Quaternion">
|
<constructor name="Quaternion">
|
||||||
<return type="Quaternion" />
|
<return type="Quaternion" />
|
||||||
<param index="0" name="from" type="Basis" />
|
<param index="0" name="from" type="Basis" />
|
||||||
@ -86,6 +80,13 @@
|
|||||||
<description>
|
<description>
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="from_euler" qualifiers="static">
|
||||||
|
<return type="Quaternion" />
|
||||||
|
<param index="0" name="euler" type="Vector3" />
|
||||||
|
<description>
|
||||||
|
Constructs a Quaternion from Euler angles in YXZ rotation order.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_angle" qualifiers="const">
|
<method name="get_angle" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
@ -2688,7 +2688,7 @@ void EditorPropertyQuaternion::_custom_value_changed(double val) {
|
|||||||
v.y = Math::deg_to_rad(edit_euler.y);
|
v.y = Math::deg_to_rad(edit_euler.y);
|
||||||
v.z = Math::deg_to_rad(edit_euler.z);
|
v.z = Math::deg_to_rad(edit_euler.z);
|
||||||
|
|
||||||
Quaternion temp_q = Quaternion(v);
|
Quaternion temp_q = Quaternion::from_euler(v);
|
||||||
spin[0]->set_value(temp_q.x);
|
spin[0]->set_value(temp_q.x);
|
||||||
spin[1]->set_value(temp_q.y);
|
spin[1]->set_value(temp_q.y);
|
||||||
spin[2]->set_value(temp_q.z);
|
spin[2]->set_value(temp_q.z);
|
||||||
|
@ -6289,7 +6289,7 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
|
|||||||
|
|
||||||
for (int32_t key_i = 0; key_i < key_count; key_i++) {
|
for (int32_t key_i = 0; key_i < key_count; key_i++) {
|
||||||
Vector3 rotation_radian = p_animation->track_get_key_value(p_track_i, key_i);
|
Vector3 rotation_radian = p_animation->track_get_key_value(p_track_i, key_i);
|
||||||
p_track.rotation_track.values.write[key_i] = Quaternion(rotation_radian);
|
p_track.rotation_track.values.write[key_i] = Quaternion::from_euler(rotation_radian);
|
||||||
}
|
}
|
||||||
} else if (path.contains(":scale")) {
|
} else if (path.contains(":scale")) {
|
||||||
p_track.scale_track.times = times;
|
p_track.scale_track.times = times;
|
||||||
|
@ -506,35 +506,6 @@ namespace Godot
|
|||||||
this = basis.GetQuaternion();
|
this = basis.GetQuaternion();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a <see cref="Quaternion"/> that will perform a rotation specified by
|
|
||||||
/// Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last),
|
|
||||||
/// given in the vector format as (X angle, Y angle, Z angle).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="eulerYXZ">Euler angles that the quaternion will be rotated by.</param>
|
|
||||||
public Quaternion(Vector3 eulerYXZ)
|
|
||||||
{
|
|
||||||
real_t halfA1 = eulerYXZ.y * 0.5f;
|
|
||||||
real_t halfA2 = eulerYXZ.x * 0.5f;
|
|
||||||
real_t halfA3 = eulerYXZ.z * 0.5f;
|
|
||||||
|
|
||||||
// R = Y(a1).X(a2).Z(a3) convention for Euler angles.
|
|
||||||
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
|
|
||||||
// a3 is the angle of the first rotation, following the notation in this reference.
|
|
||||||
|
|
||||||
real_t cosA1 = Mathf.Cos(halfA1);
|
|
||||||
real_t sinA1 = Mathf.Sin(halfA1);
|
|
||||||
real_t cosA2 = Mathf.Cos(halfA2);
|
|
||||||
real_t sinA2 = Mathf.Sin(halfA2);
|
|
||||||
real_t cosA3 = Mathf.Cos(halfA3);
|
|
||||||
real_t sinA3 = Mathf.Sin(halfA3);
|
|
||||||
|
|
||||||
x = (sinA1 * cosA2 * sinA3) + (cosA1 * sinA2 * cosA3);
|
|
||||||
y = (sinA1 * cosA2 * cosA3) - (cosA1 * sinA2 * sinA3);
|
|
||||||
z = (cosA1 * cosA2 * sinA3) - (sinA1 * sinA2 * cosA3);
|
|
||||||
w = (sinA1 * sinA2 * sinA3) + (cosA1 * cosA2 * cosA3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs a <see cref="Quaternion"/> that will rotate around the given axis
|
/// Constructs a <see cref="Quaternion"/> that will rotate around the given axis
|
||||||
/// by the specified angle. The axis must be a normalized vector.
|
/// by the specified angle. The axis must be a normalized vector.
|
||||||
@ -572,6 +543,37 @@ namespace Godot
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a <see cref="Quaternion"/> that will perform a rotation specified by
|
||||||
|
/// Euler angles (in the YXZ convention: when decomposing, first Z, then X, and Y last),
|
||||||
|
/// given in the vector format as (X angle, Y angle, Z angle).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eulerYXZ">Euler angles that the quaternion will be rotated by.</param>
|
||||||
|
public static Quaternion FromEuler(Vector3 eulerYXZ)
|
||||||
|
{
|
||||||
|
real_t halfA1 = eulerYXZ.y * 0.5f;
|
||||||
|
real_t halfA2 = eulerYXZ.x * 0.5f;
|
||||||
|
real_t halfA3 = eulerYXZ.z * 0.5f;
|
||||||
|
|
||||||
|
// R = Y(a1).X(a2).Z(a3) convention for Euler angles.
|
||||||
|
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
|
||||||
|
// a3 is the angle of the first rotation, following the notation in this reference.
|
||||||
|
|
||||||
|
real_t cosA1 = Mathf.Cos(halfA1);
|
||||||
|
real_t sinA1 = Mathf.Sin(halfA1);
|
||||||
|
real_t cosA2 = Mathf.Cos(halfA2);
|
||||||
|
real_t sinA2 = Mathf.Sin(halfA2);
|
||||||
|
real_t cosA3 = Mathf.Cos(halfA3);
|
||||||
|
real_t sinA3 = Mathf.Sin(halfA3);
|
||||||
|
|
||||||
|
return new Quaternion(
|
||||||
|
(sinA1 * cosA2 * sinA3) + (cosA1 * sinA2 * cosA3),
|
||||||
|
(sinA1 * cosA2 * cosA3) - (cosA1 * sinA2 * sinA3),
|
||||||
|
(cosA1 * cosA2 * sinA3) - (sinA1 * sinA2 * cosA3),
|
||||||
|
(sinA1 * sinA2 * sinA3) + (cosA1 * cosA2 * cosA3)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Composes these two quaternions by multiplying them together.
|
/// Composes these two quaternions by multiplying them together.
|
||||||
/// This has the effect of rotating the second quaternion
|
/// This has the effect of rotating the second quaternion
|
||||||
|
@ -47,9 +47,9 @@ Quaternion quat_euler_yxz_deg(Vector3 angle) {
|
|||||||
|
|
||||||
// Generate YXZ (Z-then-X-then-Y) Quaternion using single-axis Euler
|
// Generate YXZ (Z-then-X-then-Y) Quaternion using single-axis Euler
|
||||||
// constructor and quaternion product, both tested separately.
|
// constructor and quaternion product, both tested separately.
|
||||||
Quaternion q_y(Vector3(0.0, yaw, 0.0));
|
Quaternion q_y = Quaternion::from_euler(Vector3(0.0, yaw, 0.0));
|
||||||
Quaternion q_p(Vector3(pitch, 0.0, 0.0));
|
Quaternion q_p = Quaternion::from_euler(Vector3(pitch, 0.0, 0.0));
|
||||||
Quaternion q_r(Vector3(0.0, 0.0, roll));
|
Quaternion q_r = Quaternion::from_euler(Vector3(0.0, 0.0, roll));
|
||||||
// Roll-Z is followed by Pitch-X, then Yaw-Y.
|
// Roll-Z is followed by Pitch-X, then Yaw-Y.
|
||||||
Quaternion q_yxz = q_y * q_p * q_r;
|
Quaternion q_yxz = q_y * q_p * q_r;
|
||||||
|
|
||||||
@ -134,21 +134,21 @@ TEST_CASE("[Quaternion] Construct Euler SingleAxis") {
|
|||||||
double roll = Math::deg_to_rad(10.0);
|
double roll = Math::deg_to_rad(10.0);
|
||||||
|
|
||||||
Vector3 euler_y(0.0, yaw, 0.0);
|
Vector3 euler_y(0.0, yaw, 0.0);
|
||||||
Quaternion q_y(euler_y);
|
Quaternion q_y = Quaternion::from_euler(euler_y);
|
||||||
CHECK(q_y[0] == doctest::Approx(0.0));
|
CHECK(q_y[0] == doctest::Approx(0.0));
|
||||||
CHECK(q_y[1] == doctest::Approx(0.382684));
|
CHECK(q_y[1] == doctest::Approx(0.382684));
|
||||||
CHECK(q_y[2] == doctest::Approx(0.0));
|
CHECK(q_y[2] == doctest::Approx(0.0));
|
||||||
CHECK(q_y[3] == doctest::Approx(0.923879));
|
CHECK(q_y[3] == doctest::Approx(0.923879));
|
||||||
|
|
||||||
Vector3 euler_p(pitch, 0.0, 0.0);
|
Vector3 euler_p(pitch, 0.0, 0.0);
|
||||||
Quaternion q_p(euler_p);
|
Quaternion q_p = Quaternion::from_euler(euler_p);
|
||||||
CHECK(q_p[0] == doctest::Approx(0.258819));
|
CHECK(q_p[0] == doctest::Approx(0.258819));
|
||||||
CHECK(q_p[1] == doctest::Approx(0.0));
|
CHECK(q_p[1] == doctest::Approx(0.0));
|
||||||
CHECK(q_p[2] == doctest::Approx(0.0));
|
CHECK(q_p[2] == doctest::Approx(0.0));
|
||||||
CHECK(q_p[3] == doctest::Approx(0.965926));
|
CHECK(q_p[3] == doctest::Approx(0.965926));
|
||||||
|
|
||||||
Vector3 euler_r(0.0, 0.0, roll);
|
Vector3 euler_r(0.0, 0.0, roll);
|
||||||
Quaternion q_r(euler_r);
|
Quaternion q_r = Quaternion::from_euler(euler_r);
|
||||||
CHECK(q_r[0] == doctest::Approx(0.0));
|
CHECK(q_r[0] == doctest::Approx(0.0));
|
||||||
CHECK(q_r[1] == doctest::Approx(0.0));
|
CHECK(q_r[1] == doctest::Approx(0.0));
|
||||||
CHECK(q_r[2] == doctest::Approx(0.0871558));
|
CHECK(q_r[2] == doctest::Approx(0.0871558));
|
||||||
@ -163,11 +163,11 @@ TEST_CASE("[Quaternion] Construct Euler YXZ dynamic axes") {
|
|||||||
// Generate YXZ comparison data (Z-then-X-then-Y) using single-axis Euler
|
// Generate YXZ comparison data (Z-then-X-then-Y) using single-axis Euler
|
||||||
// constructor and quaternion product, both tested separately.
|
// constructor and quaternion product, both tested separately.
|
||||||
Vector3 euler_y(0.0, yaw, 0.0);
|
Vector3 euler_y(0.0, yaw, 0.0);
|
||||||
Quaternion q_y(euler_y);
|
Quaternion q_y = Quaternion::from_euler(euler_y);
|
||||||
Vector3 euler_p(pitch, 0.0, 0.0);
|
Vector3 euler_p(pitch, 0.0, 0.0);
|
||||||
Quaternion q_p(euler_p);
|
Quaternion q_p = Quaternion::from_euler(euler_p);
|
||||||
Vector3 euler_r(0.0, 0.0, roll);
|
Vector3 euler_r(0.0, 0.0, roll);
|
||||||
Quaternion q_r(euler_r);
|
Quaternion q_r = Quaternion::from_euler(euler_r);
|
||||||
|
|
||||||
// Roll-Z is followed by Pitch-X.
|
// Roll-Z is followed by Pitch-X.
|
||||||
Quaternion check_xz = q_p * q_r;
|
Quaternion check_xz = q_p * q_r;
|
||||||
@ -176,7 +176,7 @@ TEST_CASE("[Quaternion] Construct Euler YXZ dynamic axes") {
|
|||||||
|
|
||||||
// Test construction from YXZ Euler angles.
|
// Test construction from YXZ Euler angles.
|
||||||
Vector3 euler_yxz(pitch, yaw, roll);
|
Vector3 euler_yxz(pitch, yaw, roll);
|
||||||
Quaternion q(euler_yxz);
|
Quaternion q = Quaternion::from_euler(euler_yxz);
|
||||||
CHECK(q[0] == doctest::Approx(check_yxz[0]));
|
CHECK(q[0] == doctest::Approx(check_yxz[0]));
|
||||||
CHECK(q[1] == doctest::Approx(check_yxz[1]));
|
CHECK(q[1] == doctest::Approx(check_yxz[1]));
|
||||||
CHECK(q[2] == doctest::Approx(check_yxz[2]));
|
CHECK(q[2] == doctest::Approx(check_yxz[2]));
|
||||||
@ -191,7 +191,7 @@ TEST_CASE("[Quaternion] Construct Basis Euler") {
|
|||||||
double pitch = Math::deg_to_rad(30.0);
|
double pitch = Math::deg_to_rad(30.0);
|
||||||
double roll = Math::deg_to_rad(10.0);
|
double roll = Math::deg_to_rad(10.0);
|
||||||
Vector3 euler_yxz(pitch, yaw, roll);
|
Vector3 euler_yxz(pitch, yaw, roll);
|
||||||
Quaternion q_yxz(euler_yxz);
|
Quaternion q_yxz = Quaternion::from_euler(euler_yxz);
|
||||||
Basis basis_axes = Basis::from_euler(euler_yxz);
|
Basis basis_axes = Basis::from_euler(euler_yxz);
|
||||||
Quaternion q(basis_axes);
|
Quaternion q(basis_axes);
|
||||||
CHECK(q.is_equal_approx(q_yxz));
|
CHECK(q.is_equal_approx(q_yxz));
|
||||||
@ -209,7 +209,7 @@ TEST_CASE("[Quaternion] Construct Basis Axes") {
|
|||||||
// Quaternion from local calculation.
|
// Quaternion from local calculation.
|
||||||
Quaternion q_local = quat_euler_yxz_deg(Vector3(31.41, -49.16, 12.34));
|
Quaternion q_local = quat_euler_yxz_deg(Vector3(31.41, -49.16, 12.34));
|
||||||
// Quaternion from Euler angles constructor.
|
// Quaternion from Euler angles constructor.
|
||||||
Quaternion q_euler(euler_yxz);
|
Quaternion q_euler = Quaternion::from_euler(euler_yxz);
|
||||||
CHECK(q_calc.is_equal_approx(q_local));
|
CHECK(q_calc.is_equal_approx(q_local));
|
||||||
CHECK(q_local.is_equal_approx(q_euler));
|
CHECK(q_local.is_equal_approx(q_euler));
|
||||||
|
|
||||||
@ -253,21 +253,21 @@ TEST_CASE("[Quaternion] Product") {
|
|||||||
double roll = Math::deg_to_rad(10.0);
|
double roll = Math::deg_to_rad(10.0);
|
||||||
|
|
||||||
Vector3 euler_y(0.0, yaw, 0.0);
|
Vector3 euler_y(0.0, yaw, 0.0);
|
||||||
Quaternion q_y(euler_y);
|
Quaternion q_y = Quaternion::from_euler(euler_y);
|
||||||
CHECK(q_y[0] == doctest::Approx(0.0));
|
CHECK(q_y[0] == doctest::Approx(0.0));
|
||||||
CHECK(q_y[1] == doctest::Approx(0.382684));
|
CHECK(q_y[1] == doctest::Approx(0.382684));
|
||||||
CHECK(q_y[2] == doctest::Approx(0.0));
|
CHECK(q_y[2] == doctest::Approx(0.0));
|
||||||
CHECK(q_y[3] == doctest::Approx(0.923879));
|
CHECK(q_y[3] == doctest::Approx(0.923879));
|
||||||
|
|
||||||
Vector3 euler_p(pitch, 0.0, 0.0);
|
Vector3 euler_p(pitch, 0.0, 0.0);
|
||||||
Quaternion q_p(euler_p);
|
Quaternion q_p = Quaternion::from_euler(euler_p);
|
||||||
CHECK(q_p[0] == doctest::Approx(0.258819));
|
CHECK(q_p[0] == doctest::Approx(0.258819));
|
||||||
CHECK(q_p[1] == doctest::Approx(0.0));
|
CHECK(q_p[1] == doctest::Approx(0.0));
|
||||||
CHECK(q_p[2] == doctest::Approx(0.0));
|
CHECK(q_p[2] == doctest::Approx(0.0));
|
||||||
CHECK(q_p[3] == doctest::Approx(0.965926));
|
CHECK(q_p[3] == doctest::Approx(0.965926));
|
||||||
|
|
||||||
Vector3 euler_r(0.0, 0.0, roll);
|
Vector3 euler_r(0.0, 0.0, roll);
|
||||||
Quaternion q_r(euler_r);
|
Quaternion q_r = Quaternion::from_euler(euler_r);
|
||||||
CHECK(q_r[0] == doctest::Approx(0.0));
|
CHECK(q_r[0] == doctest::Approx(0.0));
|
||||||
CHECK(q_r[1] == doctest::Approx(0.0));
|
CHECK(q_r[1] == doctest::Approx(0.0));
|
||||||
CHECK(q_r[2] == doctest::Approx(0.0871558));
|
CHECK(q_r[2] == doctest::Approx(0.0871558));
|
||||||
|
@ -140,13 +140,13 @@ TEST_CASE("[Animation] Create 3D rotation track") {
|
|||||||
Ref<Animation> animation = memnew(Animation);
|
Ref<Animation> animation = memnew(Animation);
|
||||||
const int track_index = animation->add_track(Animation::TYPE_ROTATION_3D);
|
const int track_index = animation->add_track(Animation::TYPE_ROTATION_3D);
|
||||||
animation->track_set_path(track_index, NodePath("Enemy:rotation"));
|
animation->track_set_path(track_index, NodePath("Enemy:rotation"));
|
||||||
animation->rotation_track_insert_key(track_index, 0.0, Quaternion(Vector3(0, 1, 2)));
|
animation->rotation_track_insert_key(track_index, 0.0, Quaternion::from_euler(Vector3(0, 1, 2)));
|
||||||
animation->rotation_track_insert_key(track_index, 0.5, Quaternion(Vector3(3.5, 4, 5)));
|
animation->rotation_track_insert_key(track_index, 0.5, Quaternion::from_euler(Vector3(3.5, 4, 5)));
|
||||||
|
|
||||||
CHECK(animation->get_track_count() == 1);
|
CHECK(animation->get_track_count() == 1);
|
||||||
CHECK(!animation->track_is_compressed(0));
|
CHECK(!animation->track_is_compressed(0));
|
||||||
CHECK(Quaternion(animation->track_get_key_value(0, 0)).is_equal_approx(Quaternion(Vector3(0, 1, 2))));
|
CHECK(Quaternion(animation->track_get_key_value(0, 0)).is_equal_approx(Quaternion::from_euler(Vector3(0, 1, 2))));
|
||||||
CHECK(Quaternion(animation->track_get_key_value(0, 1)).is_equal_approx(Quaternion(Vector3(3.5, 4, 5))));
|
CHECK(Quaternion(animation->track_get_key_value(0, 1)).is_equal_approx(Quaternion::from_euler(Vector3(3.5, 4, 5))));
|
||||||
|
|
||||||
Quaternion r_interpolation;
|
Quaternion r_interpolation;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ TEST_SUITE("Validate tests") {
|
|||||||
Plane plane(Vector3(1, 1, 1), 1.0);
|
Plane plane(Vector3(1, 1, 1), 1.0);
|
||||||
INFO(plane);
|
INFO(plane);
|
||||||
|
|
||||||
Quaternion quat(Vector3(0.5, 1.0, 2.0));
|
Quaternion quat = Quaternion::from_euler(Vector3(0.5, 1.0, 2.0));
|
||||||
INFO(quat);
|
INFO(quat);
|
||||||
|
|
||||||
AABB aabb(Vector3(), Vector3(100, 100, 100));
|
AABB aabb(Vector3(), Vector3(100, 100, 100));
|
||||||
|
Loading…
Reference in New Issue
Block a user