diff --git a/irr/include/matrix4.h b/irr/include/matrix4.h index 973568daf..efb727098 100644 --- a/irr/include/matrix4.h +++ b/irr/include/matrix4.h @@ -162,21 +162,12 @@ public: //! Returns true if the matrix is the identity matrix inline bool isIdentity() const; - //! Returns true if the matrix is orthogonal - inline bool isOrthogonal() const; - - //! Returns true if the matrix is the identity matrix - bool isIdentity_integer_base() const; - //! Set the translation of the current matrix. Will erase any previous values. CMatrix4 &setTranslation(const vector3d &translation); //! Gets the current translation vector3d getTranslation() const; - //! Set the inverse translation of the current matrix. Will erase any previous values. - CMatrix4 &setInverseTranslation(const vector3d &translation); - //! Make a rotation matrix from Euler angles. The 4th row and column are unmodified. //! NOTE: Rotation order is ZYX. This means that vectors are //! first rotated around the X, then the Y, and finally the Z axis. @@ -198,7 +189,7 @@ public: WARNING: There have been troubles with this function over the years and we may still have missed some corner cases. It's generally safer to keep the rotation and scale you used to create the matrix around and work with those. */ - core::vector3d getRotationDegrees(const vector3d &scale) const; + vector3d getRotationDegrees(const vector3d &scale) const; //! Returns the rotation, as set by setRotation(). /** NOTE: You will have the same end-rotation as used in setRotation, but it might not use the same axis values. @@ -207,15 +198,7 @@ public: NOTE: It does not necessarily return the *same* Euler angles as those set by setRotationDegrees(), but the rotation will be equivalent, i.e. will have the same result when used to rotate a vector or node. */ - core::vector3d getRotationDegrees() const; - - //! Make an inverted rotation matrix from Euler angles. - /** The 4th row and column are unmodified. */ - inline CMatrix4 &setInverseRotationRadians(const vector3d &rotation); - - //! Make an inverted rotation matrix from Euler angles. - /** The 4th row and column are unmodified. */ - inline CMatrix4 &setInverseRotationDegrees(const vector3d &rotation); + vector3d getRotationDegrees() const; //! Make a rotation matrix from angle and axis, assuming left handed rotation. /** The 4th row and column are unmodified. */ @@ -225,10 +208,10 @@ public: CMatrix4 &setScale(const vector3d &scale); //! Set Scale - CMatrix4 &setScale(const T scale) { return setScale(core::vector3d(scale, scale, scale)); } + CMatrix4 &setScale(const T scale) { return setScale(vector3d(scale, scale, scale)); } //! Get Scale - core::vector3d getScale() const; + vector3d getScale() const; //! Translate a vector by the inverse of the translation part of this matrix. void inverseTranslateVect(vector3df &vect) const; @@ -259,7 +242,7 @@ public: //! An alternate transform vector method, writing into an array of 4 floats /** This operation is performed as if the vector was 4d with the 4th component =1. NOTE: out[3] will be written to (4th vector component)*/ - void transformVect(T *out, const core::vector3df &in) const; + void transformVect(T *out, const vector3df &in) const; //! An alternate transform vector method, reading from and writing to an array of 3 floats /** This operation is performed as if the vector was 4d with the 4th component =1 @@ -274,13 +257,13 @@ public: void translateVect(vector3df &vect) const; //! Transforms a plane by this matrix - void transformPlane(core::plane3d &plane) const; + void transformPlane(plane3d &plane) const; //! Transforms a plane by this matrix - void transformPlane(const core::plane3d &in, core::plane3d &out) const; + void transformPlane(const plane3d &in, plane3d &out) const; //! Transforms a axis aligned bounding box - void transformBoxEx(core::aabbox3d &box) const; + void transformBoxEx(aabbox3d &box) const; //! Multiplies this matrix by a 1x4 matrix void multiplyWith1x4Matrix(T *matrix) const; @@ -338,16 +321,16 @@ public: \param plane: plane into which the geometry if flattened into \param point: value between 0 and 1, describing the light source. If this is 1, it is a point light, if it is 0, it is a directional light. */ - CMatrix4 &buildShadowMatrix(const core::vector3df &light, core::plane3df plane, f32 point = 1.0f); + CMatrix4 &buildShadowMatrix(const vector3df &light, plane3df plane, f32 point = 1.0f); //! Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates. /** Used to scale <-1,-1><1,1> to viewport, for example from <-1,-1> <1,1> to the viewport <0,0><0,640> */ - CMatrix4 &buildNDCToDCMatrix(const core::rect &area, f32 zScale); + CMatrix4 &buildNDCToDCMatrix(const rect &area, f32 zScale); //! Creates a new matrix as interpolated matrix from two other ones. /** \param b: other matrix to interpolate with \param time: Must be a value between 0 and 1. */ - CMatrix4 interpolate(const core::CMatrix4 &b, f32 time) const; + CMatrix4 interpolate(const CMatrix4 &b, f32 time) const; //! Gets transposed matrix CMatrix4 getTransposed() const; @@ -359,13 +342,13 @@ public: /** \param from: vector to rotate from \param to: vector to rotate to */ - CMatrix4 &buildRotateFromTo(const core::vector3df &from, const core::vector3df &to); + CMatrix4 &buildRotateFromTo(const vector3df &from, const vector3df &to); //! Builds a combined matrix which translates to a center before rotation and translates from origin afterwards /** \param center Position to rotate around \param translate Translation applied after the rotation */ - void setRotationCenter(const core::vector3df ¢er, const core::vector3df &translate); + void setRotationCenter(const vector3df ¢er, const vector3df &translate); //! Builds a matrix which rotates a source vector to a look vector over an arbitrary axis /** \param camPos: viewer position in world coo @@ -374,11 +357,11 @@ public: \param axis: axis to rotate about \param from: source vector to rotate from */ - void buildAxisAlignedBillboard(const core::vector3df &camPos, - const core::vector3df ¢er, - const core::vector3df &translation, - const core::vector3df &axis, - const core::vector3df &from); + void buildAxisAlignedBillboard(const vector3df &camPos, + const vector3df ¢er, + const vector3df &translation, + const vector3df &axis, + const vector3df &from); /* construct 2D Texture transformations @@ -386,9 +369,9 @@ public: */ //! Set to a texture transformation matrix with the given parameters. CMatrix4 &buildTextureTransform(f32 rotateRad, - const core::vector2df &rotatecenter, - const core::vector2df &translate, - const core::vector2df &scale); + const vector2df &rotatecenter, + const vector2df &translate, + const vector2df &scale); //! Set texture transformation rotation /** Rotate about z axis, recenter at (0.5,0.5). @@ -439,7 +422,7 @@ public: CMatrix4 &setM(const T *data); //! Compare two matrices using the equal method - bool equals(const core::CMatrix4 &other, const T tolerance = (T)ROUNDING_ERROR_f64) const; + bool equals(const CMatrix4 &other, const T tolerance = (T)ROUNDING_ERROR_f64) const; private: //! Matrix data, stored in row-major order @@ -645,21 +628,8 @@ inline CMatrix4 &CMatrix4::operator*=(const T &scalar) template inline CMatrix4 &CMatrix4::operator*=(const CMatrix4 &other) { -#if defined(USE_MATRIX_TEST) - // do checks on your own in order to avoid copy creation - if (!other.isIdentity()) { - if (this->isIdentity()) { - return (*this = other); - } else { - CMatrix4 temp(*this); - return setbyproduct_nocheck(temp, other); - } - } - return *this; -#else CMatrix4 temp(*this); return setbyproduct_nocheck(temp, other); -#endif } //! multiply by another matrix @@ -699,30 +669,13 @@ inline CMatrix4 &CMatrix4::setbyproduct_nocheck(const CMatrix4 &other_a template inline CMatrix4 &CMatrix4::setbyproduct(const CMatrix4 &other_a, const CMatrix4 &other_b) { -#if defined(USE_MATRIX_TEST) - if (other_a.isIdentity()) - return (*this = other_b); - else if (other_b.isIdentity()) - return (*this = other_a); - else - return setbyproduct_nocheck(other_a, other_b); -#else return setbyproduct_nocheck(other_a, other_b); -#endif } //! multiply by another matrix template inline CMatrix4 CMatrix4::operator*(const CMatrix4 &m2) const { -#if defined(USE_MATRIX_TEST) - // Testing purpose.. - if (this->isIdentity()) - return m2; - if (m2.isIdentity()) - return *this; -#endif - CMatrix4 m3(EM4CONST_NOTHING); const T *m1 = M; @@ -764,15 +717,6 @@ inline CMatrix4 &CMatrix4::setTranslation(const vector3d &translation) return *this; } -template -inline CMatrix4 &CMatrix4::setInverseTranslation(const vector3d &translation) -{ - M[12] = -translation.X; - M[13] = -translation.Y; - M[14] = -translation.Z; - return *this; -} - template inline CMatrix4 &CMatrix4::setScale(const vector3d &scale) { @@ -805,13 +749,7 @@ inline vector3d CMatrix4::getScale() const template inline CMatrix4 &CMatrix4::setRotationDegrees(const vector3d &rotation) { - return setRotationRadians(rotation * core::DEGTORAD); -} - -template -inline CMatrix4 &CMatrix4::setInverseRotationDegrees(const vector3d &rotation) -{ - return setInverseRotationRadians(rotation * core::DEGTORAD); + return setRotationRadians(rotation * DEGTORAD); } template @@ -847,20 +785,20 @@ This code was originally written by by Chev (assuming no scaling back then, we can be blamed for all problems added by regarding scale) */ template -inline core::vector3d CMatrix4::getRotationDegrees(const vector3d &scale_) const +inline vector3d CMatrix4::getRotationDegrees(const vector3d &scale_) const { const CMatrix4 &mat = *this; - const core::vector3d scale(core::iszero(scale_.X) ? FLT_MAX : scale_.X, core::iszero(scale_.Y) ? FLT_MAX : scale_.Y, core::iszero(scale_.Z) ? FLT_MAX : scale_.Z); - const core::vector3d invScale(core::reciprocal(scale.X), core::reciprocal(scale.Y), core::reciprocal(scale.Z)); + const vector3d scale(iszero(scale_.X) ? FLT_MAX : scale_.X, iszero(scale_.Y) ? FLT_MAX : scale_.Y, iszero(scale_.Z) ? FLT_MAX : scale_.Z); + const vector3d invScale(reciprocal(scale.X), reciprocal(scale.Y), reciprocal(scale.Z)); - f64 Y = -asin(core::clamp(mat[2] * invScale.X, -1.0, 1.0)); + f64 Y = -asin(clamp(mat[2] * invScale.X, -1.0, 1.0)); const f64 C = cos(Y); Y *= RADTODEG64; f64 rotx, roty, X, Z; - if (!core::iszero((T)C)) { - const f64 invC = core::reciprocal(C); + if (!iszero((T)C)) { + const f64 invC = reciprocal(C); rotx = mat[10] * invC * invScale.Z; roty = mat[6] * invC * invScale.Y; X = atan2(roty, rotx) * RADTODEG64; @@ -900,34 +838,6 @@ inline vector3d CMatrix4::getRotationDegrees() const return getRotationDegrees(scale); } -//! Sets matrix to rotation matrix of inverse angles given as parameters -template -inline CMatrix4 &CMatrix4::setInverseRotationRadians(const vector3d &rotation) -{ - f64 cPitch = cos(rotation.X); - f64 sPitch = sin(rotation.X); - f64 cYaw = cos(rotation.Y); - f64 sYaw = sin(rotation.Y); - f64 cRoll = cos(rotation.Z); - f64 sRoll = sin(rotation.Z); - - M[0] = (T)(cYaw * cRoll); - M[4] = (T)(cYaw * sRoll); - M[8] = (T)(-sYaw); - - f64 sPitch_sYaw = sPitch * sYaw; - f64 cPitch_sYaw = cPitch * sYaw; - - M[1] = (T)(sPitch_sYaw * cRoll - cPitch * sRoll); - M[5] = (T)(sPitch_sYaw * sRoll + cPitch * cRoll); - M[9] = (T)(sPitch * cYaw); - - M[2] = (T)(cPitch_sYaw * cRoll + sPitch * sRoll); - M[6] = (T)(cPitch_sYaw * sRoll - sPitch * cRoll); - M[10] = (T)(cPitch * cYaw); - return *this; -} - //! Sets matrix to rotation matrix defined by axis and angle, assuming LH rotation template inline CMatrix4 &CMatrix4::setRotationAxisRadians(const T &angle, const vector3d &axis) @@ -959,8 +869,6 @@ inline CMatrix4 &CMatrix4::setRotationAxisRadians(const T &angle, const ve return *this; } -/*! - */ template inline CMatrix4 &CMatrix4::makeIdentity() { @@ -1002,77 +910,6 @@ inline bool CMatrix4::isIdentity() const return true; } -/* Check orthogonality of matrix. */ -template -inline bool CMatrix4::isOrthogonal() const -{ - T dp = M[0] * M[4] + M[1] * M[5] + M[2] * M[6] + M[3] * M[7]; - if (!iszero(dp)) - return false; - dp = M[0] * M[8] + M[1] * M[9] + M[2] * M[10] + M[3] * M[11]; - if (!iszero(dp)) - return false; - dp = M[0] * M[12] + M[1] * M[13] + M[2] * M[14] + M[3] * M[15]; - if (!iszero(dp)) - return false; - dp = M[4] * M[8] + M[5] * M[9] + M[6] * M[10] + M[7] * M[11]; - if (!iszero(dp)) - return false; - dp = M[4] * M[12] + M[5] * M[13] + M[6] * M[14] + M[7] * M[15]; - if (!iszero(dp)) - return false; - dp = M[8] * M[12] + M[9] * M[13] + M[10] * M[14] + M[11] * M[15]; - return (iszero(dp)); -} - -/* - doesn't solve floating range problems.. - but takes care on +/- 0 on translation because we are changing it.. - reducing floating point branches - but it needs the floats in memory.. -*/ -template -inline bool CMatrix4::isIdentity_integer_base() const -{ - if (IR(M[0]) != F32_VALUE_1) - return false; - if (IR(M[1]) != 0) - return false; - if (IR(M[2]) != 0) - return false; - if (IR(M[3]) != 0) - return false; - - if (IR(M[4]) != 0) - return false; - if (IR(M[5]) != F32_VALUE_1) - return false; - if (IR(M[6]) != 0) - return false; - if (IR(M[7]) != 0) - return false; - - if (IR(M[8]) != 0) - return false; - if (IR(M[9]) != 0) - return false; - if (IR(M[10]) != F32_VALUE_1) - return false; - if (IR(M[11]) != 0) - return false; - - if (IR(M[12]) != 0) - return false; - if (IR(M[13]) != 0) - return false; - if (IR(M[13]) != 0) - return false; - if (IR(M[15]) != F32_VALUE_1) - return false; - - return true; -} - template inline vector3d CMatrix4::rotateAndScaleVect(const vector3d &v) const { @@ -1104,7 +941,7 @@ inline vector3d CMatrix4::transformVect(const vector3d &v) const } template -inline void CMatrix4::transformVect(T *out, const core::vector3df &in) const +inline void CMatrix4::transformVect(T *out, const vector3df &in) const { out[0] = in.X * M[0] + in.Y * M[4] + in.Z * M[8] + M[12]; out[1] = in.X * M[1] + in.Y * M[5] + in.Z * M[9] + M[13]; @@ -1131,7 +968,7 @@ inline void CMatrix4::transformVec4(T *out, const T *in) const //! Transforms a plane by this matrix template -inline void CMatrix4::transformPlane(core::plane3d &plane) const +inline void CMatrix4::transformPlane(plane3d &plane) const { vector3df member; // Transform the plane member point, i.e. rotate, translate and scale it. @@ -1145,7 +982,7 @@ inline void CMatrix4::transformPlane(core::plane3d &plane) const //! Transforms a plane by this matrix template -inline void CMatrix4::transformPlane(const core::plane3d &in, core::plane3d &out) const +inline void CMatrix4::transformPlane(const plane3d &in, plane3d &out) const { out = in; transformPlane(out); @@ -1153,13 +990,8 @@ inline void CMatrix4::transformPlane(const core::plane3d &in, core::plan //! Transforms a axis aligned bounding box more accurately than transformBox() template -inline void CMatrix4::transformBoxEx(core::aabbox3d &box) const +inline void CMatrix4::transformBoxEx(aabbox3d &box) const { -#if defined(USE_MATRIX_TEST) - if (isIdentity()) - return; -#endif - const f32 Amin[3] = {box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z}; const f32 Amax[3] = {box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z}; @@ -1242,12 +1074,6 @@ inline bool CMatrix4::getInverse(CMatrix4 &out) const /// The inverse is calculated using Cramers rule. /// If no inverse exists then 'false' is returned. -#if defined(USE_MATRIX_TEST) - if (this->isIdentity()) { - out = *this; - return true; - } -#endif const CMatrix4 &m = *this; f32 d = (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) - @@ -1257,10 +1083,10 @@ inline bool CMatrix4::getInverse(CMatrix4 &out) const (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) + (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]); - if (core::iszero(d, FLT_MIN)) + if (iszero(d, FLT_MIN)) return false; - d = core::reciprocal(d); + d = reciprocal(d); out[0] = d * (m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + @@ -1642,7 +1468,7 @@ inline CMatrix4 &CMatrix4::buildProjectionMatrixPerspectiveLH( // Builds a matrix that flattens geometry into a plane. template -inline CMatrix4 &CMatrix4::buildShadowMatrix(const core::vector3df &light, core::plane3df plane, f32 point) +inline CMatrix4 &CMatrix4::buildShadowMatrix(const vector3df &light, plane3df plane, f32 point) { plane.Normal.normalize(); const f32 d = plane.Normal.dotProduct(light); @@ -1748,7 +1574,7 @@ inline CMatrix4 &CMatrix4::buildCameraLookAtMatrixRH( // creates a new matrix as interpolated matrix from this and the passed one. template -inline CMatrix4 CMatrix4::interpolate(const core::CMatrix4 &b, f32 time) const +inline CMatrix4 CMatrix4::interpolate(const CMatrix4 &b, f32 time) const { CMatrix4 mat(EM4CONST_NOTHING); @@ -1797,7 +1623,7 @@ inline void CMatrix4::getTransposed(CMatrix4 &o) const // used to scale <-1,-1><1,1> to viewport template -inline CMatrix4 &CMatrix4::buildNDCToDCMatrix(const core::rect &viewport, f32 zScale) +inline CMatrix4 &CMatrix4::buildNDCToDCMatrix(const rect &viewport, f32 zScale) { const f32 scaleX = (viewport.getWidth() - 0.75f) * 0.5f; const f32 scaleY = -(viewport.getHeight() - 0.75f) * 0.5f; @@ -1808,7 +1634,7 @@ inline CMatrix4 &CMatrix4::buildNDCToDCMatrix(const core::rect &viewp makeIdentity(); M[12] = (T)dx; M[13] = (T)dy; - return setScale(core::vector3d((T)scaleX, (T)scaleY, (T)zScale)); + return setScale(vector3d((T)scaleX, (T)scaleY, (T)zScale)); } //! Builds a matrix that rotates from one vector to another @@ -1818,25 +1644,25 @@ inline CMatrix4 &CMatrix4::buildNDCToDCMatrix(const core::rect &viewp http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm */ template -inline CMatrix4 &CMatrix4::buildRotateFromTo(const core::vector3df &from, const core::vector3df &to) +inline CMatrix4 &CMatrix4::buildRotateFromTo(const vector3df &from, const vector3df &to) { // unit vectors - core::vector3df f(from); - core::vector3df t(to); + vector3df f(from); + vector3df t(to); f.normalize(); t.normalize(); // axis multiplication by sin - core::vector3df vs(t.crossProduct(f)); + vector3df vs(t.crossProduct(f)); // axis of rotation - core::vector3df v(vs); + vector3df v(vs); v.normalize(); // cosine angle T ca = f.dotProduct(t); - core::vector3df vt(v * (1 - ca)); + vector3df vt(v * (1 - ca)); M[0] = vt.X * v.X + ca; M[5] = vt.Y * v.Y + ca; @@ -1875,29 +1701,29 @@ inline CMatrix4 &CMatrix4::buildRotateFromTo(const core::vector3df &from, */ template inline void CMatrix4::buildAxisAlignedBillboard( - const core::vector3df &camPos, - const core::vector3df ¢er, - const core::vector3df &translation, - const core::vector3df &axis, - const core::vector3df &from) + const vector3df &camPos, + const vector3df ¢er, + const vector3df &translation, + const vector3df &axis, + const vector3df &from) { // axis of rotation - core::vector3df up = axis; + vector3df up = axis; up.normalize(); - const core::vector3df forward = (camPos - center).normalize(); - const core::vector3df right = up.crossProduct(forward).normalize(); + const vector3df forward = (camPos - center).normalize(); + const vector3df right = up.crossProduct(forward).normalize(); // correct look vector - const core::vector3df look = right.crossProduct(up); + const vector3df look = right.crossProduct(up); // rotate from to // axis multiplication by sin - const core::vector3df vs = look.crossProduct(from); + const vector3df vs = look.crossProduct(from); // cosine angle const f32 ca = from.dotProduct(look); - core::vector3df vt(up * (1.f - ca)); + vector3df vt(up * (1.f - ca)); M[0] = static_cast(vt.X * up.X + ca); M[5] = static_cast(vt.Y * up.Y + ca); @@ -1924,7 +1750,7 @@ inline void CMatrix4::buildAxisAlignedBillboard( //! Builds a combined matrix which translate to a center before rotation and translate afterward template -inline void CMatrix4::setRotationCenter(const core::vector3df ¢er, const core::vector3df &translation) +inline void CMatrix4::setRotationCenter(const vector3df ¢er, const vector3df &translation) { M[12] = -M[0] * center.X - M[4] * center.Y - M[8] * center.Z + (center.X - translation.X); M[13] = -M[1] * center.X - M[5] * center.Y - M[9] * center.Z + (center.Y - translation.Y); @@ -1945,9 +1771,9 @@ inline void CMatrix4::setRotationCenter(const core::vector3df ¢er, const template inline CMatrix4 &CMatrix4::buildTextureTransform(f32 rotateRad, - const core::vector2df &rotatecenter, - const core::vector2df &translate, - const core::vector2df &scale) + const vector2df &rotatecenter, + const vector2df &translate, + const vector2df &scale) { const f32 c = cosf(rotateRad); const f32 s = sinf(rotateRad); @@ -2052,7 +1878,7 @@ inline CMatrix4 &CMatrix4::setM(const T *data) //! Compare two matrices using the equal method template -inline bool CMatrix4::equals(const core::CMatrix4 &other, const T tolerance) const +inline bool CMatrix4::equals(const CMatrix4 &other, const T tolerance) const { for (s32 i = 0; i < 16; ++i) if (!core::equals(M[i], other.M[i], tolerance)) diff --git a/src/unittest/test_irr_gltf_mesh_loader.cpp b/src/unittest/test_irr_gltf_mesh_loader.cpp index b1b0d99a1..51d8e2251 100644 --- a/src/unittest/test_irr_gltf_mesh_loader.cpp +++ b/src/unittest/test_irr_gltf_mesh_loader.cpp @@ -414,7 +414,7 @@ SECTION("simple skin") CHECK(child->Animatedrotation == irr::core::quaternion()); CHECK(child->Animatedscale == v3f(1, 1, 1)); irr::core::matrix4 inverseBindMatrix; - inverseBindMatrix.setInverseTranslation(childTranslation); + inverseBindMatrix.setTranslation(-childTranslation); CHECK(child->GlobalInversedMatrix == inverseBindMatrix); }