diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index e0ac5fff0..ffb3f04de 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -16,6 +16,7 @@ #include "client/meshgen/collector.h" #include "util/basic_macros.h" #include "util/numeric.h" +#include "util/rotation_matrix.h" #include "util/serialize.h" #include "camera.h" // CameraModes #include "collision.h" @@ -955,7 +956,7 @@ void GenericCAO::updateNodePos() getPosRotMatrix().setTranslation(pos); if (node != m_spritenode) { // rotate if not a sprite v3f rot = m_is_local_player ? -m_rotation : -rot_translator.val_current; - setPitchYawRoll(getPosRotMatrix(), rot); + setPitchYawRollRad(getPosRotMatrix(), rot * core::RADTODEG); } } } diff --git a/src/mapgen/treegen.cpp b/src/mapgen/treegen.cpp index f59696bea..fe28cec1b 100644 --- a/src/mapgen/treegen.cpp +++ b/src/mapgen/treegen.cpp @@ -5,8 +5,8 @@ // Copyright (C) 2015-2018 paramat #include +#include #include "treegen.h" -#include "irr_v3d.h" #include "util/pointer.h" #include "util/numeric.h" #include "servermap.h" diff --git a/src/objdef.cpp b/src/objdef.cpp index b8b11b7b7..c84c20117 100644 --- a/src/objdef.cpp +++ b/src/objdef.cpp @@ -6,9 +6,10 @@ #include "util/numeric.h" #include "log.h" #include "gamedef.h" -#include "porting.h" // strcasecmp +#include "porting.h" // strcasecmp for Windows #include +#include // strcasecmp for everything else ObjDefManager::ObjDefManager(IGameDef *gamedef, ObjDefType type) { diff --git a/src/profiler.cpp b/src/profiler.cpp index 3516f4ef3..bf0800a34 100644 --- a/src/profiler.cpp +++ b/src/profiler.cpp @@ -4,6 +4,7 @@ #include "profiler.h" #include "porting.h" +#include static Profiler main_profiler; Profiler *g_profiler = &main_profiler; diff --git a/src/server/unit_sao.h b/src/server/unit_sao.h index 6930cd583..2c79841c2 100644 --- a/src/server/unit_sao.h +++ b/src/server/unit_sao.h @@ -8,7 +8,7 @@ #include "object_properties.h" #include "serveractiveobject.h" #include -#include "util/numeric.h" +#include "util/rotation_matrix.h" class UnitSAO : public ServerActiveObject { @@ -26,7 +26,7 @@ public: const v3f getTotalRotation() const { // This replicates what happens clientside serverside core::matrix4 rot; - setPitchYawRoll(rot, -m_rotation); + setPitchYawRollRad(rot, -m_rotation * core::DEGTORAD); v3f res; // First rotate by m_rotation, then rotate by the automatic rotate yaw (core::quaternion(v3f(0, -m_rotation_add_yaw * core::DEGTORAD, 0)) diff --git a/src/unittest/test_utilities.cpp b/src/unittest/test_utilities.cpp index 093dcf1ef..f9c1fec1f 100644 --- a/src/unittest/test_utilities.cpp +++ b/src/unittest/test_utilities.cpp @@ -2,12 +2,14 @@ // SPDX-License-Identifier: LGPL-2.1-or-later // Copyright (C) 2013 celeron55, Perttu Ahola +#include "irrMath.h" #include "test.h" #include #include #include "util/enriched_string.h" #include "util/numeric.h" +#include "util/rotation_matrix.h" #include "util/string.h" #include "util/base64.h" #include "util/colorize.h" @@ -459,11 +461,11 @@ static bool within(const core::matrix4 &m1, const core::matrix4 &m2, return true; } -static bool roundTripsDeg(const v3f &v, const f32 precision) +static bool roundTripsRad(const v3f &v, const f32 precision) { core::matrix4 m; - setPitchYawRoll(m, v); - return within(v, getPitchYawRoll(m), precision); + setPitchYawRollRad(m, v); + return within(v, getPitchYawRollRad(m), precision); } void TestUtilities::testEulerConversion() @@ -484,12 +486,8 @@ void TestUtilities::testEulerConversion() // produce the same results. Check also that the conversion // works both ways for these values. v1 = v3f(M_PI/3.0, M_PI/5.0, M_PI/4.0); - v2 = v3f(60.0f, 36.0f, 45.0f); setPitchYawRollRad(m1, v1); - setPitchYawRoll(m2, v2); - UASSERT(within(m1, m2, tolL)); UASSERT(within(getPitchYawRollRad(m1), v1, tolL)); - UASSERT(within(getPitchYawRoll(m2), v2, tolH)); // Check the rotation matrix produced. UASSERT(within(M1[0], 0.932004869f, tolL)); @@ -535,17 +533,17 @@ void TestUtilities::testEulerConversion() UASSERT(within(M1[10], M2[0], tolL)); // Check that Eulers that produce near gimbal-lock still round-trip - UASSERT(roundTripsDeg(v3f(89.9999f, 17.f, 0.f), tolH)); - UASSERT(roundTripsDeg(v3f(89.9999f, 0.f, 19.f), tolH)); - UASSERT(roundTripsDeg(v3f(89.9999f, 17.f, 19.f), tolH)); + UASSERT(roundTripsRad(core::DEGTORAD * v3f(89.9999f, 17.f, 0.f), tolH)); + UASSERT(roundTripsRad(core::DEGTORAD * v3f(89.9999f, 0.f, 19.f), tolH)); + UASSERT(roundTripsRad(core::DEGTORAD * v3f(89.9999f, 17.f, 19.f), tolH)); // Check that Eulers at an angle > 90 degrees may not round-trip... - v1 = v3f(90.00001f, 1.f, 1.f); - setPitchYawRoll(m1, v1); - v2 = getPitchYawRoll(m1); + v1 = core::DEGTORAD * v3f(90.00001f, 1.f, 1.f); + setPitchYawRollRad(m1, v1); + v2 = getPitchYawRollRad(m1); //UASSERT(within(v1, v2, tolL)); // this is typically false // ... however the rotation matrix is the same for both - setPitchYawRoll(m2, v2); + setPitchYawRollRad(m2, v2); UASSERT(within(m1, m2, tolL)); } diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 7d5ac48fb..8d00e1212 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -9,6 +9,7 @@ set(util_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/ieee_float.cpp ${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp ${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rotation_matrix.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pointabilities.cpp ${CMAKE_CURRENT_SOURCE_DIR}/quicktune.cpp diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp index 59dd0a204..294e2c81b 100644 --- a/src/util/numeric.cpp +++ b/src/util/numeric.cpp @@ -157,38 +157,3 @@ s16 adjustDist(s16 dist, float zoom_fov) { return std::round(adjustDist((float)dist, zoom_fov)); } - -void setPitchYawRollRad(core::matrix4 &m, v3f rot) -{ - f64 a1 = rot.Z, a2 = rot.X, a3 = rot.Y; - f64 c1 = cos(a1), s1 = sin(a1); - f64 c2 = cos(a2), s2 = sin(a2); - f64 c3 = cos(a3), s3 = sin(a3); - f32 *M = m.pointer(); - - M[0] = s1 * s2 * s3 + c1 * c3; - M[1] = s1 * c2; - M[2] = s1 * s2 * c3 - c1 * s3; - - M[4] = c1 * s2 * s3 - s1 * c3; - M[5] = c1 * c2; - M[6] = c1 * s2 * c3 + s1 * s3; - - M[8] = c2 * s3; - M[9] = -s2; - M[10] = c2 * c3; -} - -v3f getPitchYawRollRad(const core::matrix4 &m) -{ - const f32 *M = m.pointer(); - - f64 a1 = atan2(M[1], M[5]); - f32 c2 = std::sqrt((f64)M[10]*M[10] + (f64)M[8]*M[8]); - f32 a2 = atan2f(-M[9], c2); - f64 c1 = cos(a1); - f64 s1 = sin(a1); - f32 a3 = atan2f(s1*M[6] - c1*M[2], c1*M[0] - s1*M[4]); - - return v3f(a2, a3, a1); -} diff --git a/src/util/numeric.h b/src/util/numeric.h index b79ef2aef..72aef544d 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -11,7 +11,6 @@ #include "irr_v3d.h" #include "irr_aabb3d.h" #include "SColor.h" -#include #include #include @@ -478,20 +477,6 @@ inline void wrappedApproachShortest(T ¤t, const T target, const T stepsize } } -void setPitchYawRollRad(core::matrix4 &m, v3f rot); - -inline void setPitchYawRoll(core::matrix4 &m, v3f rot) -{ - setPitchYawRollRad(m, rot * core::DEGTORAD); -} - -v3f getPitchYawRollRad(const core::matrix4 &m); - -inline v3f getPitchYawRoll(const core::matrix4 &m) -{ - return getPitchYawRollRad(m) * core::RADTODEG; -} - // Muliply the RGB value of a color linearly, and clamp to black/white inline video::SColor multiplyColorValue(const video::SColor &color, float mod) { diff --git a/src/util/rotation_matrix.cpp b/src/util/rotation_matrix.cpp new file mode 100644 index 000000000..1fa69171b --- /dev/null +++ b/src/util/rotation_matrix.cpp @@ -0,0 +1,36 @@ +#include "rotation_matrix.h" + +void setPitchYawRollRad(core::matrix4 &m, v3f rot) +{ + f64 a1 = rot.Z, a2 = rot.X, a3 = rot.Y; + f64 c1 = cos(a1), s1 = sin(a1); + f64 c2 = cos(a2), s2 = sin(a2); + f64 c3 = cos(a3), s3 = sin(a3); + f32 *M = m.pointer(); + + M[0] = s1 * s2 * s3 + c1 * c3; + M[1] = s1 * c2; + M[2] = s1 * s2 * c3 - c1 * s3; + + M[4] = c1 * s2 * s3 - s1 * c3; + M[5] = c1 * c2; + M[6] = c1 * s2 * c3 + s1 * s3; + + M[8] = c2 * s3; + M[9] = -s2; + M[10] = c2 * c3; +} + +v3f getPitchYawRollRad(const core::matrix4 &m) +{ + const f32 *M = m.pointer(); + + f64 a1 = atan2(M[1], M[5]); + f32 c2 = std::sqrt((f64)M[10]*M[10] + (f64)M[8]*M[8]); + f32 a2 = atan2f(-M[9], c2); + f64 c1 = cos(a1); + f64 s1 = sin(a1); + f32 a3 = atan2f(s1*M[6] - c1*M[2], c1*M[0] - s1*M[4]); + + return v3f(a2, a3, a1); +} diff --git a/src/util/rotation_matrix.h b/src/util/rotation_matrix.h new file mode 100644 index 000000000..d28145a6f --- /dev/null +++ b/src/util/rotation_matrix.h @@ -0,0 +1,8 @@ +#include +#include "irr_v3d.h" + +/// @note This is not consistent with Irrlicht's setRotationRadians +void setPitchYawRollRad(core::matrix4 &m, v3f rot); + +/// @note This is not consistent with Irrlicht's getRotationRadians +v3f getPitchYawRollRad(const core::matrix4 &m);