123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- // Description : Common matrix class
- #pragma once
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- // struct Matrix34_tpl
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- template <typename F>
- struct Matrix34_tpl
- {
- F m00, m01, m02, m03;
- F m10, m11, m12, m13;
- F m20, m21, m22, m23;
- //default constructor
- #if defined(_DEBUG)
- ILINE Matrix34_tpl()
- {
- if constexpr (sizeof(F) == 4)
- {
- uint32* p = (uint32*)&m00;
- p[ 0] = F32NAN;
- p[ 1] = F32NAN;
- p[ 2] = F32NAN;
- p[ 3] = F32NAN;
- p[ 4] = F32NAN;
- p[ 5] = F32NAN;
- p[ 6] = F32NAN;
- p[ 7] = F32NAN;
- p[ 8] = F32NAN;
- p[ 9] = F32NAN;
- p[10] = F32NAN;
- p[11] = F32NAN;
- }
- if constexpr (sizeof(F) == 8)
- {
- uint64* p = (uint64*)&m00;
- p[ 0] = F64NAN;
- p[ 1] = F64NAN;
- p[ 2] = F64NAN;
- p[ 3] = F64NAN;
- p[ 4] = F64NAN;
- p[ 5] = F64NAN;
- p[ 6] = F64NAN;
- p[ 7] = F64NAN;
- p[ 8] = F64NAN;
- p[ 9] = F64NAN;
- p[10] = F64NAN;
- p[11] = F64NAN;
- }
- }
- #else
- ILINE Matrix34_tpl(){};
- #endif
- //set matrix to Identity
- ILINE Matrix34_tpl(type_identity)
- {
- m00 = 1;
- m01 = 0;
- m02 = 0;
- m03 = 0;
- m10 = 0;
- m11 = 1;
- m12 = 0;
- m13 = 0;
- m20 = 0;
- m21 = 0;
- m22 = 1;
- m23 = 0;
- }
- //set matrix to Zero
- ILINE Matrix34_tpl(type_zero)
- {
- m00 = 0;
- m01 = 0;
- m02 = 0;
- m03 = 0;
- m10 = 0;
- m11 = 0;
- m12 = 0;
- m13 = 0;
- m20 = 0;
- m21 = 0;
- m22 = 0;
- m23 = 0;
- }
- //ASSIGNMENT OPERATOR of identical Matrix33 types.
- //The assignment operator has precedence over assignment constructor
- //Matrix34 m; m=m34;
- ILINE Matrix34_tpl<F>& operator = (const Matrix34_tpl<F>& m)
- {
- assert(m.IsValid());
- m00 = m.m00;
- m01 = m.m01;
- m02 = m.m02;
- m03 = m.m03;
- m10 = m.m10;
- m11 = m.m11;
- m12 = m.m12;
- m13 = m.m13;
- m20 = m.m20;
- m21 = m.m21;
- m22 = m.m22;
- m23 = m.m23;
- return *this;
- }
- //--------------------------------------------------------------------
- //---- implementation of the constructors ---
- //--------------------------------------------------------------------
- //CONSTRUCTOR for identical float-types. It initialises a matrix34 with 12 floats.
- ILINE Matrix34_tpl<F>(F v00, F v01, F v02, F v03, F v10, F v11, F v12, F v13, F v20, F v21, F v22, F v23)
- {
- m00 = v00;
- m01 = v01;
- m02 = v02;
- m03 = v03;
- m10 = v10;
- m11 = v11;
- m12 = v12;
- m13 = v13;
- m20 = v20;
- m21 = v21;
- m22 = v22;
- m23 = v23;
- }
- //CONSTRUCTOR for different float-types. It initialises a matrix34 with 12 floats.
- template<class F1>
- ILINE Matrix34_tpl<F>(F1 v00, F1 v01, F1 v02, F1 v03, F1 v10, F1 v11, F1 v12, F1 v13, F1 v20, F1 v21, F1 v22, F1 v23)
- {
- m00 = F(v00);
- m01 = F(v01);
- m02 = F(v02);
- m03 = F(v03);
- m10 = F(v10);
- m11 = F(v11);
- m12 = F(v12);
- m13 = F(v13);
- m20 = F(v20);
- m21 = F(v21);
- m22 = F(v22);
- m23 = F(v23);
- }
- //CONSTRUCTOR for identical float-types. It converts a Matrix33 into a Matrix34.
- //Matrix34(m33);
- ILINE Matrix34_tpl<F>(const Matrix33_tpl<F>&m)
- {
- assert(m.IsValid());
- m00 = m.m00;
- m01 = m.m01;
- m02 = m.m02;
- m03 = 0;
- m10 = m.m10;
- m11 = m.m11;
- m12 = m.m12;
- m13 = 0;
- m20 = m.m20;
- m21 = m.m21;
- m22 = m.m22;
- m23 = 0;
- }
- //CONSTRUCTOR for different float-types. It converts a Matrix33 into a Matrix34 and also converts between double/float.
- //Matrix34(Matrix33);
- template<class F1>
- ILINE Matrix34_tpl<F>(const Matrix33_tpl<F1>&m)
- {
- assert(m.IsValid());
- m00 = F(m.m00);
- m01 = F(m.m01);
- m02 = F(m.m02);
- m03 = 0;
- m10 = F(m.m10);
- m11 = F(m.m11);
- m12 = F(m.m12);
- m13 = 0;
- m20 = F(m.m20);
- m21 = F(m.m21);
- m22 = F(m.m22);
- m23 = 0;
- }
- //CONSTRUCTOR for identical float-types. It converts a Matrix33 with a translation-vector into a Matrix34.
- //Matrix34(m33,Vec3(1,2,3));
- ILINE Matrix34_tpl<F>(const Matrix33_tpl<F>&m, const Vec3_tpl<F>&t)
- {
- assert(m.IsValid());
- assert(t.IsValid());
- m00 = m.m00;
- m01 = m.m01;
- m02 = m.m02;
- m03 = t.x;
- m10 = m.m10;
- m11 = m.m11;
- m12 = m.m12;
- m13 = t.y;
- m20 = m.m20;
- m21 = m.m21;
- m22 = m.m22;
- m23 = t.z;
- }
- //CONSTRUCTOR for different float-types. It converts a Matrix33 with a translation-vector into a Matrix34 and also converts between double/float.
- //Matrix34(Matrix33r,Vec3d(1,2,3));
- template<class F1>
- ILINE Matrix34_tpl<F>(const Matrix33_tpl<F1>&m, const Vec3_tpl<F1>&t)
- {
- assert(m.IsValid());
- assert(t.IsValid());
- m00 = F(m.m00);
- m01 = F(m.m01);
- m02 = F(m.m02);
- m03 = F(t.x);
- m10 = F(m.m10);
- m11 = F(m.m11);
- m12 = F(m.m12);
- m13 = F(t.y);
- m20 = F(m.m20);
- m21 = F(m.m21);
- m22 = F(m.m22);
- m23 = F(t.z);
- }
- //CONSTRUCTOR for identical float types
- //Matrix34 m=m34;
- ILINE Matrix34_tpl<F>(const Matrix34_tpl<F>&m)
- {
- assert(m.IsValid());
- m00 = m.m00;
- m01 = m.m01;
- m02 = m.m02;
- m03 = m.m03;
- m10 = m.m10;
- m11 = m.m11;
- m12 = m.m12;
- m13 = m.m13;
- m20 = m.m20;
- m21 = m.m21;
- m22 = m.m22;
- m23 = m.m23;
- }
- //CONSTRUCTOR for different float-types.
- //Matrix34 m=m34d;
- template<class F1>
- ILINE Matrix34_tpl<F>(const Matrix34_tpl<F1>&m)
- {
- assert(m.IsValid());
- m00 = F(m.m00);
- m01 = F(m.m01);
- m02 = F(m.m02);
- m03 = F(m.m03);
- m10 = F(m.m10);
- m11 = F(m.m11);
- m12 = F(m.m12);
- m13 = F(m.m13);
- m20 = F(m.m20);
- m21 = F(m.m21);
- m22 = F(m.m22);
- m23 = F(m.m23);
- }
- //CONSTRUCTOR for identical float-types. It converts a Matrix44 into a Matrix34.
- //Needs to be 'explicit' because we loose the translation vector in the conversion process
- //Matrix34(m44);
- ILINE explicit Matrix34_tpl<F>(const Matrix44_tpl<F>&m)
- {
- assert(m.IsValid());
- m00 = m.m00;
- m01 = m.m01;
- m02 = m.m02;
- m03 = m.m03;
- m10 = m.m10;
- m11 = m.m11;
- m12 = m.m12;
- m13 = m.m13;
- m20 = m.m20;
- m21 = m.m21;
- m22 = m.m22;
- m23 = m.m23;
- }
- //CONSTRUCTOR for different float types. It converts a Matrix44 into a Matrix34 and converts between double/float.
- //Needs to be 'explicit' because we loose the translation vector in the conversion process
- //Matrix34(m44r);
- template<class F1>
- ILINE explicit Matrix34_tpl<F>(const Matrix44_tpl<F1>&m)
- {
- assert(m.IsValid());
- m00 = F(m.m00);
- m01 = F(m.m01);
- m02 = F(m.m02);
- m03 = F(m.m03);
- m10 = F(m.m10);
- m11 = F(m.m11);
- m12 = F(m.m12);
- m13 = F(m.m13);
- m20 = F(m.m20);
- m21 = F(m.m21);
- m22 = F(m.m22);
- m23 = F(m.m23);
- }
- //CONSTRUCTOR for identical float-types. It converts a Quat into a Matrix34.
- //Needs to be 'explicit' because we loose float-precision in the conversion process
- //Matrix34(QuatT);
- explicit ILINE Matrix34_tpl<F>(const Quat_tpl<F>&q)
- {
- *this = Matrix33_tpl<F>(q);
- }
- //CONSTRUCTOR for different float-types. It converts a Quat into a Matrix34.
- //Needs to be 'explicit' because we loose float-precision in the conversion process
- //Matrix34(QuatTd);
- template<class F1>
- explicit ILINE Matrix34_tpl<F>(const Quat_tpl<F1>&q)
- {
- *this = Matrix33_tpl<F>(q);
- }
- //apply scaling to the columns of the matrix.
- ILINE void ScaleColumn(const Vec3_tpl<F>& s)
- {
- m00 *= s.x;
- m01 *= s.y;
- m02 *= s.z;
- m10 *= s.x;
- m11 *= s.y;
- m12 *= s.z;
- m20 *= s.x;
- m21 *= s.y;
- m22 *= s.z;
- }
- /*!
- *
- * Initializes the Matrix34 with the identity.
- *
- */
- void SetIdentity()
- {
- m00 = 1.0f;
- m01 = 0.0f;
- m02 = 0.0f;
- m03 = 0.0f;
- m10 = 0.0f;
- m11 = 1.0f;
- m12 = 0.0f;
- m13 = 0.0f;
- m20 = 0.0f;
- m21 = 0.0f;
- m22 = 1.0f;
- m23 = 0.0f;
- }
- ILINE static Matrix34_tpl<F> CreateIdentity()
- {
- Matrix34_tpl<F> m;
- m.SetIdentity();
- return m;
- }
- /*!
- * Create rotation-matrix about X axis using an angle.
- * The angle is assumed to be in radians.
- * The translation-vector is set to zero.
- *
- * Example:
- * Matrix34 m34;
- * m34.SetRotationX(0.5f);
- */
- ILINE void SetRotationX(const f32 rad, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- *this = Matrix33_tpl<F>::CreateRotationX(rad);
- this->SetTranslation(t);
- }
- ILINE static Matrix34_tpl<F> CreateRotationX(const f32 rad, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- Matrix34_tpl<F> m34;
- m34.SetRotationX(rad, t);
- return m34;
- }
- /*!
- * Create rotation-matrix about Y axis using an angle.
- * The angle is assumed to be in radians.
- * The translation-vector is set to zero.
- *
- * Example:
- * Matrix34 m34;
- * m34.SetRotationY(0.5f);
- */
- ILINE void SetRotationY(const f32 rad, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- *this = Matrix33_tpl<F>::CreateRotationY(rad);
- this->SetTranslation(t);
- }
- ILINE static Matrix34_tpl<F> CreateRotationY(const f32 rad, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- Matrix34_tpl<F> m34;
- m34.SetRotationY(rad, t);
- return m34;
- }
- /*!
- *
- * Convert three Euler angle to mat33 (rotation order:XYZ)
- * The Euler angles are assumed to be in radians.
- * The translation-vector is set to zero.
- *
- * Example 1:
- * Matrix34 m34;
- * m34.SetRotationXYZ( Ang3(0.5f,0.2f,0.9f), translation );
- *
- * Example 2:
- * Matrix34 m34=Matrix34::CreateRotationXYZ( Ang3(0.5f,0.2f,0.9f), translation );
- */
- ILINE void SetRotationXYZ(const Ang3_tpl<F>& rad, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- assert(rad.IsValid());
- assert(t.IsValid());
- *this = Matrix33_tpl<F>::CreateRotationXYZ(rad);
- this->SetTranslation(t);
- }
- ILINE static Matrix34_tpl<F> CreateRotationXYZ(const Ang3_tpl<F>& rad, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- assert(rad.IsValid());
- assert(t.IsValid());
- Matrix34_tpl<F> m34;
- m34.SetRotationXYZ(rad, t);
- return m34;
- }
- ILINE void SetTranslationMat(const Vec3_tpl<F>& v)
- {
- m00 = 1.0f;
- m01 = 0.0f;
- m02 = 0.0f;
- m03 = v.x;
- m10 = 0.0f;
- m11 = 1.0f;
- m12 = 0.0f;
- m13 = v.y;
- m20 = 0.0f;
- m21 = 0.0f;
- m22 = 1.0f;
- m23 = v.z;
- }
- ILINE static Matrix34_tpl<F> CreateTranslationMat(const Vec3_tpl<F>& v)
- {
- Matrix34_tpl<F> m34;
- m34.SetTranslationMat(v);
- return m34;
- }
- //NOTE: all vectors are stored in columns
- ILINE void SetFromVectors(const Vec3& vx, const Vec3& vy, const Vec3& vz, const Vec3& pos)
- {
- m00 = vx.x;
- m01 = vy.x;
- m02 = vz.x;
- m03 = pos.x;
- m10 = vx.y;
- m11 = vy.y;
- m12 = vz.y;
- m13 = pos.y;
- m20 = vx.z;
- m21 = vy.z;
- m22 = vz.z;
- m23 = pos.z;
- }
- ILINE static Matrix34_tpl<F> CreateFromVectors(const Vec3_tpl<F>& vx, const Vec3_tpl<F>& vy, const Vec3_tpl<F>& vz, const Vec3_tpl<F>& pos)
- {
- Matrix34_tpl<F> m;
- m.SetFromVectors(vx, vy, vz, pos);
- return m;
- }
- Matrix34_tpl<F> GetInvertedFast() const
- {
- assert(IsOrthonormal());
- Matrix34_tpl<F> dst;
- dst.m00 = m00;
- dst.m01 = m10;
- dst.m02 = m20;
- dst.m03 = -m03 * m00 - m13 * m10 - m23 * m20;
- dst.m10 = m01;
- dst.m11 = m11;
- dst.m12 = m21;
- dst.m13 = -m03 * m01 - m13 * m11 - m23 * m21;
- dst.m20 = m02;
- dst.m21 = m12;
- dst.m22 = m22;
- dst.m23 = -m03 * m02 - m13 * m12 - m23 * m22;
- return dst;
- }
- //! transforms a vector. the translation is not beeing considered
- ILINE Vec3_tpl<F> TransformVector(const Vec3_tpl<F>& v) const
- {
- assert(v.IsValid());
- return Vec3_tpl<F>(m00 * v.x + m01 * v.y + m02 * v.z, m10 * v.x + m11 * v.y + m12 * v.z, m20 * v.x + m21 * v.y + m22 * v.z);
- }
- //! transforms a point and add translation vector
- ILINE Vec3_tpl<F> TransformPoint(const Vec3_tpl<F>& p) const
- {
- assert(p.IsValid());
- return Vec3_tpl<F>(m00 * p.x + m01 * p.y + m02 * p.z + m03, m10 * p.x + m11 * p.y + m12 * p.z + m13, m20 * p.x + m21 * p.y + m22 * p.z + m23);
- }
- //! Remove scale from matrix.
- void OrthonormalizeFast()
- {
- Vec3_tpl<F> x(m00, m10, m20);
- Vec3_tpl<F> y(m01, m11, m21);
- Vec3_tpl<F> z;
- x = x.GetNormalized();
- z = (x % y).GetNormalized();
- y = (z % x).GetNormalized();
- m00 = x.x;
- m10 = x.y;
- m20 = x.z;
- m01 = y.x;
- m11 = y.y;
- m21 = y.z;
- m02 = z.x;
- m12 = z.y;
- m22 = z.z;
- }
- //--------------------------------------------------------------------------------
- //---- helper functions to access matrix-members ------------
- //--------------------------------------------------------------------------------
- F* GetData() { return &m00; }
- const F* GetData() const { return &m00; }
- ILINE F operator () (uint32 i, uint32 j) const { assert ((i < 3) && (j < 4)); F* p_data = (F*)(&m00); return p_data[i * 4 + j]; }
- ILINE F& operator () (uint32 i, uint32 j) { assert ((i < 3) && (j < 4)); F* p_data = (F*)(&m00); return p_data[i * 4 + j]; }
- ILINE void SetRow(int i, const Vec3_tpl<F>& v) { assert(i < 3); F* p = (F*)(&m00); p[0 + 4 * i] = v.x; p[1 + 4 * i] = v.y; p[2 + 4 * i] = v.z; }
- ILINE const Vec3_tpl<F>& GetRow(int i) const { assert(i < 3); return *(const Vec3_tpl<F>*)(&m00 + 4 * i); }
- ILINE const Vec4& GetRow4(int i) const { assert(i < 3); return *(const Vec4*)(&m00 + 4 * i); }
- ILINE Vec3_tpl<F> GetColumn0() const { return Vec3_tpl<F>(m00, m10, m20); }
- ILINE Vec3_tpl<F> GetColumn1() const { return Vec3_tpl<F>(m01, m11, m21); }
- ILINE Vec3_tpl<F> GetColumn2() const { return Vec3_tpl<F>(m02, m12, m22); }
- ILINE Vec3_tpl<F> GetColumn3() const { return Vec3_tpl<F>(m03, m13, m23); }
- ILINE void SetTranslation(const Vec3_tpl<F>& t) { m03 = t.x; m13 = t.y; m23 = t.z; }
- ILINE Vec3_tpl<F> GetTranslation() const { return Vec3_tpl<F>(m03, m13, m23); }
- ILINE void SetRotation33(const Matrix33_tpl<F>& m33)
- {
- m00 = m33.m00;
- m01 = m33.m01;
- m02 = m33.m02;
- m10 = m33.m10;
- m11 = m33.m11;
- m12 = m33.m12;
- m20 = m33.m20;
- m21 = m33.m21;
- m22 = m33.m22;
- }
- //check if we have an orthonormal-base (general case, works even with reflection matrices)
- int IsOrthonormal(F threshold = 0.001) const
- {
- f32 d0 = fabs_tpl(GetColumn0() | GetColumn1());
- if (d0 > threshold)
- {
- return 0;
- }
- f32 d1 = fabs_tpl(GetColumn0() | GetColumn2());
- if (d1 > threshold)
- {
- return 0;
- }
- f32 d2 = fabs_tpl(GetColumn1() | GetColumn2());
- if (d2 > threshold)
- {
- return 0;
- }
- int a = (fabs_tpl(1 - (GetColumn0() | GetColumn0()))) < threshold;
- int b = (fabs_tpl(1 - (GetColumn1() | GetColumn1()))) < threshold;
- int c = (fabs_tpl(1 - (GetColumn2() | GetColumn2()))) < threshold;
- return a & b & c;
- }
- //check if we have an orthonormal-base (assuming we are using a right-handed coordinate system)
- int IsOrthonormalRH(F threshold = 0.001) const
- {
- int a = Vec3_tpl<F>::IsEquivalent(GetColumn0(), GetColumn1() % GetColumn2(), threshold);
- int b = Vec3_tpl<F>::IsEquivalent(GetColumn1(), GetColumn2() % GetColumn0(), threshold);
- int c = Vec3_tpl<F>::IsEquivalent(GetColumn2(), GetColumn0() % GetColumn1(), threshold);
- return a & b & c;
- }
- bool static IsEquivalent(const Matrix34_tpl<F>& m0, const Matrix34_tpl<F>& m1, F e = VEC_EPSILON)
- {
- return (
- (fabs_tpl(m0.m00 - m1.m00) <= e) && (fabs_tpl(m0.m01 - m1.m01) <= e) && (fabs_tpl(m0.m02 - m1.m02) <= e) && (fabs_tpl(m0.m03 - m1.m03) <= e) &&
- (fabs_tpl(m0.m10 - m1.m10) <= e) && (fabs_tpl(m0.m11 - m1.m11) <= e) && (fabs_tpl(m0.m12 - m1.m12) <= e) && (fabs_tpl(m0.m13 - m1.m13) <= e) &&
- (fabs_tpl(m0.m20 - m1.m20) <= e) && (fabs_tpl(m0.m21 - m1.m21) <= e) && (fabs_tpl(m0.m22 - m1.m22) <= e) && (fabs_tpl(m0.m23 - m1.m23) <= e)
- );
- }
- bool IsValid() const
- {
- if (!NumberValid(m00))
- {
- return false;
- }
- if (!NumberValid(m01))
- {
- return false;
- }
- if (!NumberValid(m02))
- {
- return false;
- }
- if (!NumberValid(m03))
- {
- return false;
- }
- if (!NumberValid(m10))
- {
- return false;
- }
- if (!NumberValid(m11))
- {
- return false;
- }
- if (!NumberValid(m12))
- {
- return false;
- }
- if (!NumberValid(m13))
- {
- return false;
- }
- if (!NumberValid(m20))
- {
- return false;
- }
- if (!NumberValid(m21))
- {
- return false;
- }
- if (!NumberValid(m22))
- {
- return false;
- }
- if (!NumberValid(m23))
- {
- return false;
- }
- return true;
- }
- /*!
- * Create a matrix with SCALING, ROTATION and TRANSLATION (in this order).
- *
- * Example 1:
- * Matrix m34;
- * m34.SetMatrix( Vec3(1,2,3), quat, Vec3(11,22,33) );
- */
- ILINE void Set(const Vec3_tpl<F>& s, const Quat_tpl<F>& q, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- assert(s.IsValid());
- assert(q.IsUnit(0.1f));
- assert(t.IsValid());
- F vxvx = q.v.x * q.v.x;
- F vzvz = q.v.z * q.v.z;
- F vyvy = q.v.y * q.v.y;
- F vxvy = q.v.x * q.v.y;
- F vxvz = q.v.x * q.v.z;
- F vyvz = q.v.y * q.v.z;
- F svx = q.w * q.v.x;
- F svy = q.w * q.v.y;
- F svz = q.w * q.v.z;
- m00 = (1 - (vyvy + vzvz) * 2) * s.x;
- m01 = (vxvy - svz) * 2 * s.y;
- m02 = (vxvz + svy) * 2 * s.z;
- m03 = t.x;
- m10 = (vxvy + svz) * 2 * s.x;
- m11 = (1 - (vxvx + vzvz) * 2) * s.y;
- m12 = (vyvz - svx) * 2 * s.z;
- m13 = t.y;
- m20 = (vxvz - svy) * 2 * s.x;
- m21 = (vyvz + svx) * 2 * s.y;
- m22 = (1 - (vxvx + vyvy) * 2) * s.z;
- m23 = t.z;
- }
- ILINE static Matrix34_tpl<F> Create(const Vec3_tpl<F>& s, const Quat_tpl<F>& q, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- Matrix34_tpl<F> m34;
- m34.Set(s, q, t);
- return m34;
- }
- Matrix34_tpl(const Vec3_tpl<F>& s, const Quat_tpl<F>& q, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- Set(s, q, t);
- }
- /*!
- * Create scaling-matrix.
- * The translation-vector is set to zero.
- *
- * Example 1:
- * Matrix m34;
- * m34.SetScale( Vec3(0.5f, 1.0f, 2.0f) );
- */
- ILINE void SetScale(const Vec3_tpl<F>& s, const Vec3_tpl<F>& t = Vec3(ZERO))
- {
- *this = Matrix33::CreateScale(s);
- this->SetTranslation(t);
- }
- /*!
- * calculate a real inversion of a Matrix34
- * an inverse-matrix is an UnDo-matrix for all kind of transformations
- *
- * Example 1:
- * Matrix34 im34; im34.Invert();
- *
- * Example 2:
- * Matrix34 im34 = m34.GetInverted();
- */
- void Invert()
- {
- //rescue members
- Matrix34_tpl<F> m = *this;
- // calculate 12 cofactors
- m00 = m.m22 * m.m11 - m.m12 * m.m21;
- m10 = m.m12 * m.m20 - m.m22 * m.m10;
- m20 = m.m10 * m.m21 - m.m20 * m.m11;
- m01 = m.m02 * m.m21 - m.m22 * m.m01;
- m11 = m.m22 * m.m00 - m.m02 * m.m20;
- m21 = m.m20 * m.m01 - m.m00 * m.m21;
- m02 = m.m12 * m.m01 - m.m02 * m.m11;
- m12 = m.m02 * m.m10 - m.m12 * m.m00;
- m22 = m.m00 * m.m11 - m.m10 * m.m01;
- m03 = (m.m22 * m.m13 * m.m01 + m.m02 * m.m23 * m.m11 + m.m12 * m.m03 * m.m21) - (m.m12 * m.m23 * m.m01 + m.m22 * m.m03 * m.m11 + m.m02 * m.m13 * m.m21);
- m13 = (m.m12 * m.m23 * m.m00 + m.m22 * m.m03 * m.m10 + m.m02 * m.m13 * m.m20) - (m.m22 * m.m13 * m.m00 + m.m02 * m.m23 * m.m10 + m.m12 * m.m03 * m.m20);
- m23 = (m.m20 * m.m11 * m.m03 + m.m00 * m.m21 * m.m13 + m.m10 * m.m01 * m.m23) - (m.m10 * m.m21 * m.m03 + m.m20 * m.m01 * m.m13 + m.m00 * m.m11 * m.m23);
- // calculate determinant
- F det = m.m00 * m00 + m.m10 * m01 + m.m20 * m02;
- assert(fabs_tpl(det) > (F)0.00000001);
- F rcpDet = 1.0f / det;
- // calculate matrix inverse/
- m00 *= rcpDet;
- m01 *= rcpDet;
- m02 *= rcpDet;
- m03 *= rcpDet;
- m10 *= rcpDet;
- m11 *= rcpDet;
- m12 *= rcpDet;
- m13 *= rcpDet;
- m20 *= rcpDet;
- m21 *= rcpDet;
- m22 *= rcpDet;
- m23 *= rcpDet;
- }
- ILINE Matrix34_tpl<F> GetInverted() const
- {
- Matrix34_tpl<F> dst = *this;
- dst.Invert();
- return dst;
- }
- };
- ///////////////////////////////////////////////////////////////////////////////
- // Typedefs //
- ///////////////////////////////////////////////////////////////////////////////
- typedef Matrix34_tpl<f32> Matrix34; //always 32 bit
- //----------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------
- //------------- implementation of Matrix34 ------------------------------
- //----------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------
- //----------------------------------------------------------------------------------
- //! multiply all matrix's values by f and return the matrix
- template<class F>
- ILINE Matrix34_tpl<F> operator * (const Matrix34_tpl<F>& m, const f32 f)
- {
- assert(m.IsValid());
- Matrix34_tpl<F> r;
- r.m00 = m.m00 * f;
- r.m01 = m.m01 * f;
- r.m02 = m.m02 * f;
- r.m03 = m.m03 * f;
- r.m10 = m.m10 * f;
- r.m11 = m.m11 * f;
- r.m12 = m.m12 * f;
- r.m13 = m.m13 * f;
- r.m20 = m.m20 * f;
- r.m21 = m.m21 * f;
- r.m22 = m.m22 * f;
- r.m23 = m.m23 * f;
- return r;
- }
- /*!
- * multiplication of Matrix34 by a (column) Vec3.
- * This function transforms the given input Vec3
- * into the coordinate system defined by this matrix.
- *
- * Example:
- * Matrix34 m34;
- * Vec3 vector(44,55,66);
- * Vec3 result = m34*vector;
- */
- template<class F>
- ILINE Vec3_tpl<F> operator * (const Matrix34_tpl<F>& m, const Vec3_tpl<F>& p)
- {
- assert(m.IsValid());
- assert(p.IsValid());
- Vec3_tpl<F> tp;
- tp.x = m.m00 * p.x + m.m01 * p.y + m.m02 * p.z + m.m03;
- tp.y = m.m10 * p.x + m.m11 * p.y + m.m12 * p.z + m.m13;
- tp.z = m.m20 * p.x + m.m21 * p.y + m.m22 * p.z + m.m23;
- return tp;
- }
- template<class F1, class F2>
- ILINE Matrix34_tpl<F1> operator + (const Matrix34_tpl<F1>& l, const Matrix34_tpl<F2>& r)
- {
- assert(l.IsValid());
- assert(r.IsValid());
- Matrix34_tpl<F1> m;
- m.m00 = l.m00 + r.m00;
- m.m01 = l.m01 + r.m01;
- m.m02 = l.m02 + r.m02;
- m.m03 = l.m03 + r.m03;
- m.m10 = l.m10 + r.m10;
- m.m11 = l.m11 + r.m11;
- m.m12 = l.m12 + r.m12;
- m.m13 = l.m13 + r.m13;
- m.m20 = l.m20 + r.m20;
- m.m21 = l.m21 + r.m21;
- m.m22 = l.m22 + r.m22;
- m.m23 = l.m23 + r.m23;
- return m;
- }
- template<class F1, class F2>
- ILINE Matrix34_tpl<F1>& operator += (Matrix34_tpl<F1>& l, const Matrix34_tpl<F2>& r)
- {
- assert(l.IsValid());
- assert(r.IsValid());
- l.m00 += r.m00;
- l.m01 += r.m01;
- l.m02 += r.m02;
- l.m03 += r.m03;
- l.m10 += r.m10;
- l.m11 += r.m11;
- l.m12 += r.m12;
- l.m13 += r.m13;
- l.m20 += r.m20;
- l.m21 += r.m21;
- l.m22 += r.m22;
- l.m23 += r.m23;
- return l;
- }
- /*!
- * Implements the multiplication operator: Matrix34=Matrix34*Matrix33
- *
- * Matrix33 and Matrix44 are specified in collumn order for a right-handed coordinate-system.
- * AxB = operation B followed by operation A.
- * A multiplication takes 27 muls and 24 adds.
- *
- * Example:
- * Matrix34 m34=Matrix33::CreateRotationX(1.94192f);;
- * Matrix33 m33=Matrix34::CreateRotationZ(3.14192f);
- * Matrix34 result=m34*m33;
- */
- template<class F>
- ILINE Matrix34_tpl<F> operator * (const Matrix34_tpl<F>& l, const Matrix33_tpl<F>& r)
- {
- assert(l.IsValid());
- assert(r.IsValid());
- Matrix34_tpl<F> m;
- m.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20;
- m.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20;
- m.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20;
- m.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21;
- m.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21;
- m.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21;
- m.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22;
- m.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22;
- m.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22;
- m.m03 = l.m03;
- m.m13 = l.m13;
- m.m23 = l.m23;
- return m;
- }
- /*!
- * Implements the multiplication operator: Matrix34=Matrix34*Matrix34
- *
- * Matrix34 is specified in collumn order.
- * AxB = rotation B followed by rotation A.
- * This operation takes 36 mults and 27 adds.
- *
- * Example:
- * Matrix34 m34=Matrix34::CreateRotationX(1.94192f, Vec3(11,22,33));;
- * Matrix34 m34=Matrix33::CreateRotationZ(3.14192f);
- * Matrix34 result=m34*m34;
- */
- template<class F>
- ILINE Matrix34_tpl<F> operator * (const Matrix34_tpl<F>& l, const Matrix34_tpl<F>& r)
- {
- assert(l.IsValid());
- assert(r.IsValid());
- Matrix34_tpl<F> m;
- m.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20;
- m.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20;
- m.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20;
- m.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21;
- m.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21;
- m.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21;
- m.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22;
- m.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22;
- m.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22;
- m.m03 = l.m00 * r.m03 + l.m01 * r.m13 + l.m02 * r.m23 + l.m03;
- m.m13 = l.m10 * r.m03 + l.m11 * r.m13 + l.m12 * r.m23 + l.m13;
- m.m23 = l.m20 * r.m03 + l.m21 * r.m13 + l.m22 * r.m23 + l.m23;
- return m;
- }
- /*!
- * Implements the multiplication operator: Matrix44=Matrix34*Matrix44
- *
- * Matrix44 and Matrix34 are specified in collumn order.
- * AxB = rotation B followed by rotation A.
- * This operation takes 48 mults and 36 adds.
- *
- * Example:
- * Matrix34 m34=Matrix33::CreateRotationX(1.94192f);;
- * Matrix44 m44=Matrix33::CreateRotationZ(3.14192f);
- * Matrix44 result=m34*m44;
- */
- template<class F>
- ILINE Matrix44_tpl<F> operator * (const Matrix34_tpl<F>& l, const Matrix44_tpl<F>& r)
- {
- assert(l.IsValid());
- assert(r.IsValid());
- Matrix44_tpl<F> m;
- m.m00 = l.m00 * r.m00 + l.m01 * r.m10 + l.m02 * r.m20 + l.m03 * r.m30;
- m.m10 = l.m10 * r.m00 + l.m11 * r.m10 + l.m12 * r.m20 + l.m13 * r.m30;
- m.m20 = l.m20 * r.m00 + l.m21 * r.m10 + l.m22 * r.m20 + l.m23 * r.m30;
- m.m30 = r.m30;
- m.m01 = l.m00 * r.m01 + l.m01 * r.m11 + l.m02 * r.m21 + l.m03 * r.m31;
- m.m11 = l.m10 * r.m01 + l.m11 * r.m11 + l.m12 * r.m21 + l.m13 * r.m31;
- m.m21 = l.m20 * r.m01 + l.m21 * r.m11 + l.m22 * r.m21 + l.m23 * r.m31;
- m.m31 = r.m31;
- m.m02 = l.m00 * r.m02 + l.m01 * r.m12 + l.m02 * r.m22 + l.m03 * r.m32;
- m.m12 = l.m10 * r.m02 + l.m11 * r.m12 + l.m12 * r.m22 + l.m13 * r.m32;
- m.m22 = l.m20 * r.m02 + l.m21 * r.m12 + l.m22 * r.m22 + l.m23 * r.m32;
- m.m32 = r.m32;
- m.m03 = l.m00 * r.m03 + l.m01 * r.m13 + l.m02 * r.m23 + l.m03 * r.m33;
- m.m13 = l.m10 * r.m03 + l.m11 * r.m13 + l.m12 * r.m23 + l.m13 * r.m33;
- m.m23 = l.m20 * r.m03 + l.m21 * r.m13 + l.m22 * r.m23 + l.m23 * r.m33;
- m.m33 = r.m33;
- return m;
- }
|