// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0.If a copy of the MPL was not distributed with this // file, You can obtain one at https ://mozilla.org/MPL/2.0/. #include "SwingTwist.h" template SwingTwistOf::SwingTwistOf() { this->swing = DirectionOf(AngleOf(), AngleOf()); this->twist = AngleOf(); } template SwingTwistOf::SwingTwistOf(DirectionOf swing, AngleOf twist) { // Normalize angles AngleOf deg90 = AngleOf::Degrees(90); AngleOf deg180 = AngleOf::Degrees(180); if (swing.vertical > deg90 || swing.vertical < -deg90) { swing.horizontal += deg180; swing.vertical = deg180 - swing.vertical; twist += deg180; } this->swing = swing; this->twist = twist; } template SwingTwistOf::SwingTwistOf(AngleOf horizontal, AngleOf vertical, AngleOf twist) { // Normalize angles AngleOf deg90 = AngleOf::Degrees(90); AngleOf deg180 = AngleOf::Degrees(180); if (vertical > deg90 || vertical < -deg90) { horizontal += deg180; vertical = deg180 - vertical; twist += deg180; } this->swing = DirectionOf(horizontal, vertical); this->twist = twist; } template SwingTwistOf SwingTwistOf::Degrees(float horizontal, float vertical, float twist) { SwingTwistOf orientation = SwingTwistOf(AngleOf::Degrees(horizontal), -AngleOf::Degrees(vertical), AngleOf::Degrees(twist)); // DirectionOf swing = DirectionOf::Degrees(horizontal, vertical); // AngleOf twistAngle = AngleOf::Degrees(twist); // SwingTwistOf orientation = SwingTwistOf(swing, twistAngle); return orientation; } template Quaternion SwingTwistOf::ToQuaternion() const { Quaternion q = Quaternion::Euler(-this->swing.vertical.InDegrees(), this->swing.horizontal.InDegrees(), this->twist.InDegrees()); return q; } template SwingTwistOf SwingTwistOf::FromQuaternion(Quaternion q) { Vector3 angles = Quaternion::ToAngles(q); SwingTwistOf r = SwingTwistOf::Degrees(angles.Up(), angles.Right(), angles.Forward()); r.Normalize(); return r; } template SphericalOf SwingTwistOf::ToAngleAxis() const { Quaternion q = this->ToQuaternion(); float angle; Vector3 axis; q.ToAngleAxis(&angle, &axis); DirectionOf direction = DirectionOf::FromVector3(axis); SphericalOf aa = SphericalOf(angle, direction); return aa; } template SwingTwistOf SwingTwistOf::FromAngleAxis(SphericalOf aa) { Vector3 vectorAxis = aa.direction.ToVector3(); Quaternion q = Quaternion::AngleAxis(aa.distance, vectorAxis); return SwingTwistOf(); } template bool SwingTwistOf::operator==(const SwingTwistOf s) const { return (this->swing == s.swing) && (this->twist == s.twist); } template const SwingTwistOf SwingTwistOf::identity = SwingTwistOf(); template SphericalOf SwingTwistOf::operator*(const SphericalOf& vector) const { SphericalOf v = SphericalOf( vector.distance, vector.direction.horizontal + this->swing.horizontal, vector.direction.vertical + this->swing.vertical); return v; } template SwingTwistOf SwingTwistOf::operator*( const SwingTwistOf& rotation) const { SwingTwistOf r = SwingTwistOf(this->swing.horizontal + rotation.swing.horizontal, this->swing.vertical + rotation.swing.vertical, this->twist + rotation.twist); return r; } template SwingTwistOf SwingTwistOf::operator*=(const SwingTwistOf& rotation) { this->swing.horizontal += rotation.swing.horizontal; this->swing.vertical += rotation.swing.vertical; this->twist += rotation.twist; return *this; } template SwingTwistOf SwingTwistOf::Inverse(SwingTwistOf rotation) { SwingTwistOf r = SwingTwistOf( -rotation.swing.horizontal, -rotation.swing.vertical, -rotation.twist); return r; } template SwingTwistOf SwingTwistOf::AngleAxis(float angle, const DirectionOf& axis) { Vector3 axis_vector = axis.ToVector3(); Quaternion q = Quaternion::AngleAxis(angle, axis_vector); SwingTwistOf r = SwingTwistOf::FromQuaternion(q); return r; } template AngleOf SwingTwistOf::Angle(const SwingTwistOf& r1, const SwingTwistOf& r2) { Quaternion q1 = r1.ToQuaternion(); Quaternion q2 = r2.ToQuaternion(); float angle = Quaternion::Angle(q1, q2); return AngleOf::Degrees(angle); } template void SwingTwistOf::Normalize() { AngleOf deg90 = AngleOf::Degrees(90); AngleOf deg180 = AngleOf::Degrees(180); if (this->swing.vertical > deg90 || this->swing.vertical < -deg90) { this->swing.horizontal += deg180; this->swing.vertical = deg180 - this->swing.vertical; this->twist += deg180; } } template class Passer::LinearAlgebra::SwingTwistOf; template class Passer::LinearAlgebra::SwingTwistOf;