Skip to content

Commit

Permalink
Remove Quat set methods in favour of constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
madmiraal committed Jan 26, 2021
1 parent ad0f1c6 commit 8b983bd
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 87 deletions.
107 changes: 43 additions & 64 deletions core/math/quat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,6 @@
#include "core/math/basis.h"
#include "core/string/print_string.h"

// 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.
// This implementation uses XYZ convention (Z is the first rotation).
void Quat::set_euler_xyz(const Vector3 &p_euler) {
real_t half_a1 = p_euler.x * 0.5;
real_t half_a2 = p_euler.y * 0.5;
real_t half_a3 = p_euler.z * 0.5;

// R = X(a1).Y(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-2)
// a3 is the angle of the first rotation, following the notation in this reference.

real_t cos_a1 = Math::cos(half_a1);
real_t sin_a1 = Math::sin(half_a1);
real_t cos_a2 = Math::cos(half_a2);
real_t sin_a2 = Math::sin(half_a2);
real_t cos_a3 = Math::cos(half_a3);
real_t sin_a3 = Math::sin(half_a3);

set(sin_a1 * cos_a2 * cos_a3 + sin_a2 * sin_a3 * cos_a1,
-sin_a1 * sin_a3 * cos_a2 + sin_a2 * cos_a1 * cos_a3,
sin_a1 * sin_a2 * cos_a3 + sin_a3 * cos_a1 * cos_a2,
-sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
}

// get_euler_xyz returns 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.
Expand All @@ -68,32 +42,6 @@ Vector3 Quat::get_euler_xyz() const {
return m.get_euler_xyz();
}

// 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.
// This implementation uses YXZ convention (Z is the first rotation).
void Quat::set_euler_yxz(const Vector3 &p_euler) {
real_t half_a1 = p_euler.y * 0.5;
real_t half_a2 = p_euler.x * 0.5;
real_t half_a3 = p_euler.z * 0.5;

// 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 cos_a1 = Math::cos(half_a1);
real_t sin_a1 = Math::sin(half_a1);
real_t cos_a2 = Math::cos(half_a2);
real_t sin_a2 = Math::sin(half_a2);
real_t cos_a3 = Math::cos(half_a3);
real_t sin_a3 = Math::sin(half_a3);

set(sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3,
sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_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);
}

// get_euler_yxz returns 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.
Expand All @@ -107,10 +55,10 @@ Vector3 Quat::get_euler_yxz() const {
}

void Quat::operator*=(const Quat &p_q) {
set(w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y,
w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z,
w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x,
w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z);
x = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y;
y = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z;
z = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x;
w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z;
}

Quat Quat::operator*(const Quat &p_q) const {
Expand Down Expand Up @@ -233,18 +181,49 @@ Quat::operator String() const {
return String::num(x) + ", " + String::num(y) + ", " + String::num(z) + ", " + String::num(w);
}

void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) {
Quat::Quat(const Vector3 &p_axis, real_t p_angle) {
#ifdef MATH_CHECKS
ERR_FAIL_COND_MSG(!axis.is_normalized(), "The axis Vector3 must be normalized.");
ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized.");
#endif
real_t d = axis.length();
real_t d = p_axis.length();
if (d == 0) {
set(0, 0, 0, 0);
x = 0;
y = 0;
z = 0;
w = 0;
} else {
real_t sin_angle = Math::sin(angle * 0.5);
real_t cos_angle = Math::cos(angle * 0.5);
real_t sin_angle = Math::sin(p_angle * 0.5);
real_t cos_angle = Math::cos(p_angle * 0.5);
real_t s = sin_angle / d;
set(axis.x * s, axis.y * s, axis.z * s,
cos_angle);
x = p_axis.x * s;
y = p_axis.y * s;
z = p_axis.z * s;
w = cos_angle;
}
}

// Euler constructor 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.
// This implementation uses YXZ convention (Z is the first rotation).
Quat::Quat(const Vector3 &p_euler) {
real_t half_a1 = p_euler.y * 0.5;
real_t half_a2 = p_euler.x * 0.5;
real_t half_a3 = p_euler.z * 0.5;

// 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 cos_a1 = Math::cos(half_a1);
real_t sin_a1 = Math::sin(half_a1);
real_t cos_a2 = Math::cos(half_a2);
real_t sin_a2 = Math::sin(half_a2);
real_t cos_a3 = Math::cos(half_a3);
real_t sin_a3 = Math::sin(half_a3);

x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
}
19 changes: 5 additions & 14 deletions core/math/quat.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,14 @@ class Quat {
Quat inverse() const;
_FORCE_INLINE_ real_t dot(const Quat &p_q) const;

void set_euler_xyz(const Vector3 &p_euler);
Vector3 get_euler_xyz() const;
void set_euler_yxz(const Vector3 &p_euler);
Vector3 get_euler_yxz() const;

void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); };
Vector3 get_euler() const { return get_euler_yxz(); };

Quat slerp(const Quat &p_to, const real_t &p_weight) const;
Quat slerpni(const Quat &p_to, const real_t &p_weight) const;
Quat cubic_slerp(const Quat &p_b, const Quat &p_pre_a, const Quat &p_post_b, const real_t &p_weight) const;

void set_axis_angle(const Vector3 &axis, const real_t &angle);
_FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
r_angle = 2 * Math::acos(w);
real_t r = ((real_t)1) / Math::sqrt(1 - w * w);
Expand Down Expand Up @@ -124,23 +119,19 @@ class Quat {

operator String() const;

inline void set(real_t p_x, real_t p_y, real_t p_z, real_t p_w) {
x = p_x;
y = p_y;
z = p_z;
w = p_w;
}

_FORCE_INLINE_ Quat() {}

_FORCE_INLINE_ Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) :
x(p_x),
y(p_y),
z(p_z),
w(p_w) {
}
Quat(const Vector3 &axis, const real_t &angle) { set_axis_angle(axis, angle); }

Quat(const Vector3 &euler) { set_euler(euler); }
Quat(const Vector3 &p_axis, real_t p_angle);

Quat(const Vector3 &p_euler);

Quat(const Quat &p_q) :
x(p_q.x),
y(p_q.y),
Expand Down
4 changes: 0 additions & 4 deletions core/variant/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1126,10 +1126,6 @@ static void _register_variant_builtin_methods() {
bind_method(Quat, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray());
bind_method(Quat, get_euler, sarray(), varray());

// FIXME: Quat is atomic, this should be done via construcror
//ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray());
//ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray());

/* Color */

bind_method(Color, to_argb32, sarray(), varray());
Expand Down
7 changes: 2 additions & 5 deletions modules/gltf/gltf_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5287,8 +5287,7 @@ void GLTFDocument::_convert_mult_mesh_instance_to_gltf(Node *p_scene_parent, con
transform.origin =
Vector3(xform_2d.get_origin().x, 0, xform_2d.get_origin().y);
real_t rotation = xform_2d.get_rotation();
Quat quat;
quat.set_axis_angle(Vector3(0, 1, 0), rotation);
Quat quat(Vector3(0, 1, 0), rotation);
Size2 scale = xform_2d.get_scale();
transform.basis.set_quat_scale(quat,
Vector3(scale.x, 0, scale.y));
Expand Down Expand Up @@ -6040,14 +6039,12 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
p_track.rotation_track.interpolation = gltf_interpolation;

for (int32_t key_i = 0; key_i < key_count; key_i++) {
Quat rotation;
Vector3 rotation_degrees = p_animation->track_get_key_value(p_track_i, key_i);
Vector3 rotation_radian;
rotation_radian.x = Math::deg2rad(rotation_degrees.x);
rotation_radian.y = Math::deg2rad(rotation_degrees.y);
rotation_radian.z = Math::deg2rad(rotation_degrees.z);
rotation.set_euler(rotation_radian);
p_track.rotation_track.values.write[key_i] = rotation;
p_track.rotation_track.values.write[key_i] = Quat(rotation_radian);
}
} else if (path.find(":scale") != -1) {
p_track.scale_track.times = times;
Expand Down

0 comments on commit 8b983bd

Please sign in to comment.