diff options
Diffstat (limited to 'indra/llmath/m4math.h')
-rw-r--r-- | indra/llmath/m4math.h | 486 |
1 files changed, 243 insertions, 243 deletions
diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index b9da970cde..b0f8c90cdf 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -1,25 +1,25 @@ -/** +/** * @file m4math.h * @brief LLMatrix4 class header file. * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -58,16 +58,16 @@ class LLMatrix4a; // One way to think about it is a matrix that takes the origin frame A // and rotates it into B': i.e. A*M = B // -// Vectors: -// f - forward axis of B expressed in A -// l - left axis of B expressed in A -// u - up axis of B expressed in A +// Vectors: +// f - forward axis of B expressed in A +// l - left axis of B expressed in A +// u - up axis of B expressed in A // -// | 0: fx 1: fy 2: fz 3:0 | +// | 0: fx 1: fy 2: fz 3:0 | // M = | 4: lx 5: ly 6: lz 7:0 | // | 8: ux 9: uy 10: uz 11:0 | // | 12: 0 13: 0 14: 0 15:1 | -// +// // // // @@ -76,18 +76,18 @@ class LLMatrix4a; // // so p*M = p' // -// Vectors: +// Vectors: // f - forward of frame B in frame A // l - left of frame B in frame A // u - up of frame B in frame A // o - origin of frame frame B in frame A // -// | 0: fx 1: lx 2: ux 3:0 | +// | 0: fx 1: lx 2: ux 3:0 | // M = | 4: fy 5: ly 6: uy 7:0 | // | 8: fz 9: lz 10: uz 11:0 | // | 12:-of 13:-ol 14:-ou 15:1 | // -// of, ol, and ou mean the component of the "global" origin o in the f axis, l axis, and u axis. +// of, ol, and ou mean the component of the "global" origin o in the f axis, l axis, and u axis. // static const U32 NUM_VALUES_IN_MAT4 = 4; @@ -95,283 +95,283 @@ static const U32 NUM_VALUES_IN_MAT4 = 4; class LLMatrix4 { public: - F32 mMatrix[NUM_VALUES_IN_MAT4][NUM_VALUES_IN_MAT4]; - - // Initializes Matrix to identity matrix - LLMatrix4() - { - setIdentity(); - } - explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat - explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0) - explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0) + F32 mMatrix[NUM_VALUES_IN_MAT4][NUM_VALUES_IN_MAT4]; + + // Initializes Matrix to identity matrix + LLMatrix4() + { + setIdentity(); + } + explicit LLMatrix4(const F32 *mat); // Initializes Matrix to values in mat + explicit LLMatrix4(const LLMatrix3 &mat); // Initializes Matrix to values in mat and sets position to (0,0,0) + explicit LLMatrix4(const LLQuaternion &q); // Initializes Matrix with rotation q and sets position to (0,0,0) explicit LLMatrix4(const LLMatrix4a& mat); - LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos + LLMatrix4(const LLMatrix3 &mat, const LLVector4 &pos); // Initializes Matrix to values in mat and pos + + // These are really, really, inefficient as implemented! - djs + LLMatrix4(const LLQuaternion &q, const LLVector4 &pos); // Initializes Matrix with rotation q and position pos + LLMatrix4(F32 angle, + const LLVector4 &vec, + const LLVector4 &pos); // Initializes Matrix with axis-angle and position + LLMatrix4(F32 angle, const LLVector4 &vec); // Initializes Matrix with axis-angle and sets position to (0,0,0) + LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, + const LLVector4 &pos); // Initializes Matrix with Euler angles + LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw); // Initializes Matrix with Euler angles + + ~LLMatrix4(void); // Destructor + + LLSD getValue() const; + void setValue(const LLSD&); - // These are really, really, inefficient as implemented! - djs - LLMatrix4(const LLQuaternion &q, const LLVector4 &pos); // Initializes Matrix with rotation q and position pos - LLMatrix4(F32 angle, - const LLVector4 &vec, - const LLVector4 &pos); // Initializes Matrix with axis-angle and position - LLMatrix4(F32 angle, const LLVector4 &vec); // Initializes Matrix with axis-angle and sets position to (0,0,0) - LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, - const LLVector4 &pos); // Initializes Matrix with Euler angles - LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw); // Initializes Matrix with Euler angles + ////////////////////////////// + // + // Matrix initializers - these replace any existing values in the matrix + // - ~LLMatrix4(void); // Destructor + void initRows(const LLVector4 &row0, + const LLVector4 &row1, + const LLVector4 &row2, + const LLVector4 &row3); - LLSD getValue() const; - void setValue(const LLSD&); + // various useful matrix functions + const LLMatrix4& setIdentity(); // Load identity matrix + bool isIdentity() const; + const LLMatrix4& setZero(); // Clears matrix to all zeros. - ////////////////////////////// - // - // Matrix initializers - these replace any existing values in the matrix - // + const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis); // Calculate rotation matrix for rotating angle radians about vec + const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles + const LLMatrix4& initRotation(const LLQuaternion &q); // Set with Quaternion and position - void initRows(const LLVector4 &row0, - const LLVector4 &row1, - const LLVector4 &row2, - const LLVector4 &row3); + // Position Only + const LLMatrix4& initMatrix(const LLMatrix3 &mat); // + const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation); - // various useful matrix functions - const LLMatrix4& setIdentity(); // Load identity matrix - bool isIdentity() const; - const LLMatrix4& setZero(); // Clears matrix to all zeros. + // These operation create a matrix that will rotate and translate by the + // specified amounts. + const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation); // Rotation from axis angle + translation + const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation + const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position - const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis); // Calculate rotation matrix for rotating angle radians about vec - const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles - const LLMatrix4& initRotation(const LLQuaternion &q); // Set with Quaternion and position - - // Position Only - const LLMatrix4& initMatrix(const LLMatrix3 &mat); // - const LLMatrix4& initMatrix(const LLMatrix3 &mat, const LLVector4 &translation); + const LLMatrix4& initScale(const LLVector3 &scale); - // These operation create a matrix that will rotate and translate by the - // specified amounts. - const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation); // Rotation from axis angle + translation - const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation - const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position + // Set all + const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos); - const LLMatrix4& initScale(const LLVector3 &scale); - // Set all - const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos); + /////////////////////////// + // + // Matrix setters - set some properties without modifying others + // + const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z); // Sets matrix to translate by (x,y,z) - /////////////////////////// - // - // Matrix setters - set some properties without modifying others - // + void setFwdRow(const LLVector3 &row); + void setLeftRow(const LLVector3 &row); + void setUpRow(const LLVector3 &row); - const LLMatrix4& setTranslation(const F32 x, const F32 y, const F32 z); // Sets matrix to translate by (x,y,z) + void setFwdCol(const LLVector3 &col); + void setLeftCol(const LLVector3 &col); + void setUpCol(const LLVector3 &col); - void setFwdRow(const LLVector3 &row); - void setLeftRow(const LLVector3 &row); - void setUpRow(const LLVector3 &row); + const LLMatrix4& setTranslation(const LLVector4 &translation); + const LLMatrix4& setTranslation(const LLVector3 &translation); - void setFwdCol(const LLVector3 &col); - void setLeftCol(const LLVector3 &col); - void setUpCol(const LLVector3 &col); + // Convenience func for simplifying comparison-heavy code by + // intentionally stomping values [-FLT_EPS,FLT_EPS] to 0.0 + // + void condition(void); - const LLMatrix4& setTranslation(const LLVector4 &translation); - const LLMatrix4& setTranslation(const LLVector3 &translation); + /////////////////////////// + // + // Get properties of a matrix + // - // Convenience func for simplifying comparison-heavy code by - // intentionally stomping values [-FLT_EPS,FLT_EPS] to 0.0 - // - void condition(void); + F32 determinant(void) const; // Return determinant + LLQuaternion quaternion(void) const; // Returns quaternion - /////////////////////////// - // - // Get properties of a matrix - // + LLVector4 getFwdRow4() const; + LLVector4 getLeftRow4() const; + LLVector4 getUpRow4() const; - F32 determinant(void) const; // Return determinant - LLQuaternion quaternion(void) const; // Returns quaternion + LLMatrix3 getMat3() const; - LLVector4 getFwdRow4() const; - LLVector4 getLeftRow4() const; - LLVector4 getUpRow4() const; + const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; } - LLMatrix3 getMat3() const; + /////////////////////////// + // + // Operations on an existing matrix + // - const LLVector3& getTranslation() const { return *(LLVector3*)&mMatrix[3][0]; } + const LLMatrix4& transpose(); // Transpose LLMatrix4 + const LLMatrix4& invert(); // Invert LLMatrix4 - /////////////////////////// - // - // Operations on an existing matrix - // + // Rotate existing matrix + // These are really, really, inefficient as implemented! - djs + const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec); // Rotate matrix by rotating angle radians about vec + const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw); // Rotate matrix by Euler angles + const LLMatrix4& rotate(const LLQuaternion &q); // Rotate matrix by Quaternion - const LLMatrix4& transpose(); // Transpose LLMatrix4 - const LLMatrix4& invert(); // Invert LLMatrix4 - // Rotate existing matrix - // These are really, really, inefficient as implemented! - djs - const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec); // Rotate matrix by rotating angle radians about vec - const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw); // Rotate matrix by Euler angles - const LLMatrix4& rotate(const LLQuaternion &q); // Rotate matrix by Quaternion + // Translate existing matrix + const LLMatrix4& translate(const LLVector3 &vec); // Translate matrix by (vec[VX], vec[VY], vec[VZ]) - - // Translate existing matrix - const LLMatrix4& translate(const LLVector3 &vec); // Translate matrix by (vec[VX], vec[VY], vec[VZ]) - - /////////////////////// - // - // Operators - // + /////////////////////// + // + // Operators + // - // friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b - friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b); // Return transform of vector a by matrix b - friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b - friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate - friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate + // friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b + friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b); // Return transform of vector a by matrix b + friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b + friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate + friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate - friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b); // Return a == b - friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b); // Return a != b - friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b); // Return a < b + friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b); // Return a == b + friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b); // Return a != b + friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b); // Return a < b - friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b); // Return a + b - friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b); // Return a - b - friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b); // Return a * b - friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b); // Return a * b + friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b); // Return a + b + friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b); // Return a - b + friend const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b); // Return a * b + friend const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b); // Return a * b - friend std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a); // Stream a + friend std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a); // Stream a }; -inline const LLMatrix4& LLMatrix4::setIdentity() +inline const LLMatrix4& LLMatrix4::setIdentity() { - mMatrix[0][0] = 1.f; - mMatrix[0][1] = 0.f; - mMatrix[0][2] = 0.f; - mMatrix[0][3] = 0.f; - - mMatrix[1][0] = 0.f; - mMatrix[1][1] = 1.f; - mMatrix[1][2] = 0.f; - mMatrix[1][3] = 0.f; - - mMatrix[2][0] = 0.f; - mMatrix[2][1] = 0.f; - mMatrix[2][2] = 1.f; - mMatrix[2][3] = 0.f; - - mMatrix[3][0] = 0.f; - mMatrix[3][1] = 0.f; - mMatrix[3][2] = 0.f; - mMatrix[3][3] = 1.f; - return (*this); + mMatrix[0][0] = 1.f; + mMatrix[0][1] = 0.f; + mMatrix[0][2] = 0.f; + mMatrix[0][3] = 0.f; + + mMatrix[1][0] = 0.f; + mMatrix[1][1] = 1.f; + mMatrix[1][2] = 0.f; + mMatrix[1][3] = 0.f; + + mMatrix[2][0] = 0.f; + mMatrix[2][1] = 0.f; + mMatrix[2][2] = 1.f; + mMatrix[2][3] = 0.f; + + mMatrix[3][0] = 0.f; + mMatrix[3][1] = 0.f; + mMatrix[3][2] = 0.f; + mMatrix[3][3] = 1.f; + return (*this); } inline bool LLMatrix4::isIdentity() const { - return - mMatrix[0][0] == 1.f && - mMatrix[0][1] == 0.f && - mMatrix[0][2] == 0.f && - mMatrix[0][3] == 0.f && - - mMatrix[1][0] == 0.f && - mMatrix[1][1] == 1.f && - mMatrix[1][2] == 0.f && - mMatrix[1][3] == 0.f && - - mMatrix[2][0] == 0.f && - mMatrix[2][1] == 0.f && - mMatrix[2][2] == 1.f && - mMatrix[2][3] == 0.f && - - mMatrix[3][0] == 0.f && - mMatrix[3][1] == 0.f && - mMatrix[3][2] == 0.f && - mMatrix[3][3] == 1.f; + return + mMatrix[0][0] == 1.f && + mMatrix[0][1] == 0.f && + mMatrix[0][2] == 0.f && + mMatrix[0][3] == 0.f && + + mMatrix[1][0] == 0.f && + mMatrix[1][1] == 1.f && + mMatrix[1][2] == 0.f && + mMatrix[1][3] == 0.f && + + mMatrix[2][0] == 0.f && + mMatrix[2][1] == 0.f && + mMatrix[2][2] == 1.f && + mMatrix[2][3] == 0.f && + + mMatrix[3][0] == 0.f && + mMatrix[3][1] == 0.f && + mMatrix[3][2] == 0.f && + mMatrix[3][3] == 1.f; } /* inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b) { - U32 i, j; - LLMatrix4 mat; - for (i = 0; i < NUM_VALUES_IN_MAT4; i++) - { - for (j = 0; j < NUM_VALUES_IN_MAT4; j++) - { - mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + - a.mMatrix[j][1] * b.mMatrix[1][i] + - a.mMatrix[j][2] * b.mMatrix[2][i] + - a.mMatrix[j][3] * b.mMatrix[3][i]; - } - } - return mat; + U32 i, j; + LLMatrix4 mat; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + + a.mMatrix[j][1] * b.mMatrix[1][i] + + a.mMatrix[j][2] * b.mMatrix[2][i] + + a.mMatrix[j][3] * b.mMatrix[3][i]; + } + } + return mat; } */ inline const LLMatrix4& operator*=(LLMatrix4 &a, const LLMatrix4 &b) { - U32 i, j; - LLMatrix4 mat; - for (i = 0; i < NUM_VALUES_IN_MAT4; i++) - { - for (j = 0; j < NUM_VALUES_IN_MAT4; j++) - { - mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + - a.mMatrix[j][1] * b.mMatrix[1][i] + - a.mMatrix[j][2] * b.mMatrix[2][i] + - a.mMatrix[j][3] * b.mMatrix[3][i]; - } - } - a = mat; - return a; + U32 i, j; + LLMatrix4 mat; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + mat.mMatrix[j][i] = a.mMatrix[j][0] * b.mMatrix[0][i] + + a.mMatrix[j][1] * b.mMatrix[1][i] + + a.mMatrix[j][2] * b.mMatrix[2][i] + + a.mMatrix[j][3] * b.mMatrix[3][i]; + } + } + a = mat; + return a; } inline const LLMatrix4& operator*=(LLMatrix4 &a, const F32 &b) { - U32 i, j; - LLMatrix4 mat; - for (i = 0; i < NUM_VALUES_IN_MAT4; i++) - { - for (j = 0; j < NUM_VALUES_IN_MAT4; j++) - { - mat.mMatrix[j][i] = a.mMatrix[j][i] * b; - } - } - a = mat; - return a; + U32 i, j; + LLMatrix4 mat; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + mat.mMatrix[j][i] = a.mMatrix[j][i] * b; + } + } + a = mat; + return a; } inline const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b) { - LLMatrix4 mat; - U32 i, j; - for (i = 0; i < NUM_VALUES_IN_MAT4; i++) - { - for (j = 0; j < NUM_VALUES_IN_MAT4; j++) - { - mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i]; - } - } - a = mat; - return a; + LLMatrix4 mat; + U32 i, j; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + mat.mMatrix[j][i] = a.mMatrix[j][i] + b.mMatrix[j][i]; + } + } + a = mat; + return a; } inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b) { - LLMatrix4 mat; - U32 i, j; - for (i = 0; i < NUM_VALUES_IN_MAT4; i++) - { - for (j = 0; j < NUM_VALUES_IN_MAT4; j++) - { - mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i]; - } - } - a = mat; - return a; + LLMatrix4 mat; + U32 i, j; + for (i = 0; i < NUM_VALUES_IN_MAT4; i++) + { + for (j = 0; j < NUM_VALUES_IN_MAT4; j++) + { + mat.mMatrix[j][i] = a.mMatrix[j][i] - b.mMatrix[j][i]; + } + } + a = mat; + return a; } // Operates "to the left" on row-vector a @@ -380,24 +380,24 @@ inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b) // due to software skinning in LLViewerJointMesh::updateGeometry(). JC inline const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b) { - // This is better than making a temporary LLVector3. This eliminates an - // unnecessary LLVector3() constructor and also helps the compiler to - // realize that the output floats do not alias the input floats, hence - // eliminating redundant loads of a.mV[0], etc. JC - return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + - a.mV[VY] * b.mMatrix[VY][VX] + - a.mV[VZ] * b.mMatrix[VZ][VX] + - b.mMatrix[VW][VX], - - a.mV[VX] * b.mMatrix[VX][VY] + - a.mV[VY] * b.mMatrix[VY][VY] + - a.mV[VZ] * b.mMatrix[VZ][VY] + - b.mMatrix[VW][VY], - - a.mV[VX] * b.mMatrix[VX][VZ] + - a.mV[VY] * b.mMatrix[VY][VZ] + - a.mV[VZ] * b.mMatrix[VZ][VZ] + - b.mMatrix[VW][VZ]); + // This is better than making a temporary LLVector3. This eliminates an + // unnecessary LLVector3() constructor and also helps the compiler to + // realize that the output floats do not alias the input floats, hence + // eliminating redundant loads of a.mV[0], etc. JC + return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + + a.mV[VY] * b.mMatrix[VY][VX] + + a.mV[VZ] * b.mMatrix[VZ][VX] + + b.mMatrix[VW][VX], + + a.mV[VX] * b.mMatrix[VX][VY] + + a.mV[VY] * b.mMatrix[VY][VY] + + a.mV[VZ] * b.mMatrix[VZ][VY] + + b.mMatrix[VW][VY], + + a.mV[VX] * b.mMatrix[VX][VZ] + + a.mV[VY] * b.mMatrix[VY][VZ] + + a.mV[VZ] * b.mMatrix[VZ][VZ] + + b.mMatrix[VW][VZ]); } #endif |