diff options
Diffstat (limited to 'src/Runtime/ogl-runtime/src/system/Qt3DSMatrix.cpp')
m--------- | src/Runtime/ogl-runtime | 0 | ||||
-rw-r--r-- | src/Runtime/ogl-runtime/src/system/Qt3DSMatrix.cpp | 897 |
2 files changed, 0 insertions, 897 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime new file mode 160000 +Subproject 2025912174c4cf99270b7439ec3b021e1d089ae diff --git a/src/Runtime/ogl-runtime/src/system/Qt3DSMatrix.cpp b/src/Runtime/ogl-runtime/src/system/Qt3DSMatrix.cpp deleted file mode 100644 index b5310d0e..00000000 --- a/src/Runtime/ogl-runtime/src/system/Qt3DSMatrix.cpp +++ /dev/null @@ -1,897 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 1993-2009 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "SystemPrefix.h" - -//============================================================================== -// Includes -//============================================================================== -#include "Qt3DSMatrix.h" -#include "Qt3DSVector3.h" -#include "Qt3DSEulerAngles.h" -#include "Qt3DSDataLogger.h" -#include <math.h> - -//============================================================================== -// Namespace -//============================================================================== -namespace Q3DStudio { - -//============================================================================== -// Constants -//============================================================================== -FLOAT g_IdentityInit[4][4] = { { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } }; - -const RuntimeMatrix RuntimeMatrix::IDENTITY = RuntimeMatrix(g_IdentityInit); -extern const FLOAT RUNTIME_EPSILON; - -//============================================================================== -/** - * Empty constructor. - * Initializes this matrix to the identity matrix. - */ -RuntimeMatrix::RuntimeMatrix(const BOOL inInitializeIdentity /*= true*/) -{ - if (inInitializeIdentity) - Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); -} - -//============================================================================== -/** - * Copy constructor. - * @param inMatrix the source matrix to copy - */ -RuntimeMatrix::RuntimeMatrix(const RuntimeMatrix &inMatrix) -{ - Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); -} - -//============================================================================== -/** - * Assignment constructor. - * Initializes the matrix from an array. - * @param inComponents an array of 16 values - */ -RuntimeMatrix::RuntimeMatrix(const FLOAT inComponents[4][4]) -{ - if (inComponents) - Q3DStudio_memcpy(&m_Data, inComponents, sizeof(m_Data)); -} - -//============================================================================== -/** - * Sets this matrix to a NULL matrix with all values at zero. - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Zero() -{ - Q3DStudio_memset(&m_Data, 0, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Sets the matrix to the identity matrix. - * @return reference to this matrix - */ -RuntimeMatrix &RuntimeMatrix::Identity() -{ - Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Copies the elements from another matrix. - * @param inMatrix the source matrix - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Set(const RuntimeMatrix &inMatrix) -{ - Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Copies the given components to this matrix. - * @param inComponents an array of 16 components - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Set(const FLOAT inComponents[4][4]) -{ - if (inComponents) - Q3DStudio_memcpy(&m_Data, inComponents, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Heavily optimized assignment method. This has the same result as creating - * four full 4x4 matrices and multiplying them together. - * @todo Look into optimized code. - * @param inTranslation translation coordinates - * @param inRotation Euler angle rotations - * @param inScale scaling dimensions - * @param inPivot pivot offset vector - * @param inRotationOrder rotation order - * @param inCoordinateSystem the coordindate system - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Set(const RuntimeVector3 &inTranslation, const RuntimeVector3 &inRotation, - const RuntimeVector3 &inScale, const RuntimeVector3 &inPivot, const UINT8 inRotationOrder, - const UINT8 inCoordinateSystem) -{ - // *this = m_ScaleMatrix * m_PivotMatrix * m_RotMatrix * m_TransMatrix; // Distributed - //original - plain speak - - RuntimeVector3 theScaledPivot; - theScaledPivot.m_X = -inPivot.m_X * inScale.m_X; - theScaledPivot.m_Y = -inPivot.m_Y * inScale.m_Y; - theScaledPivot.m_Z = -inPivot.m_Z * inScale.m_Z; - - // This would take care of rotation in the right order - RuntimeMatrix theRotation; - theRotation.SetRotate(inRotation, inRotationOrder, inCoordinateSystem); - - Q3DStudio_memcpy(&m_Data, &IDENTITY, sizeof(m_Data)); - m_Data[0][0] = inScale.m_X; - m_Data[1][1] = inScale.m_Y; - m_Data[2][2] = inScale.m_Z; - - m_Data[3][0] = theScaledPivot.m_X; - m_Data[3][1] = theScaledPivot.m_Y; - - if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) - m_Data[3][2] = theScaledPivot.m_Z; - else - m_Data[3][2] = -theScaledPivot.m_Z; - - MultiplyAffine(theRotation); // This could be optimized to only 9 multiplications instead of 16 - // if you do them by hand - - m_Data[3][0] += inTranslation.m_X; - m_Data[3][1] += inTranslation.m_Y; - - if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) - m_Data[3][2] += inTranslation.m_Z; - else - m_Data[3][2] += -inTranslation.m_Z; - - if (inCoordinateSystem == ORIENTATION_LEFT_HANDED) - return FlipCoordinateSystem(); - - return *this; -} - -//============================================================================== -/** - * Sets the translation portion of the matrix without affecting the rest. - * - * If you want a pure translation matrix you must make sure to start with - * the identity matrix. - * @param inTranslate a translation vector - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::SetTranslate(const RuntimeVector3 &inTranslate) -{ - m_Data[3][0] = inTranslate.m_X; - m_Data[3][1] = inTranslate.m_Y; - m_Data[3][2] = inTranslate.m_Z; - return *this; -} - -//============================================================================== -/** - * Sets the rotation portion of the matrix without affecting the rest. - * - * FYI: The rotate and scale portions overlap. If you want a pure scale matrix - * you must make sure to start with the identity matrix. - * @param inRotation a quaternion describing the rotation - * @return reference to this modified matrix - */ -// CMatrix& CMatrix::SetRotate( const CQuaternion& inRotation ) -//{ -// inRotation.ToMatrix( *this ); -// return *this; -//} - -//============================================================================== -/** - * Sets the rotation portion of the matrix without affecting the rest. - * - * FYI: The rotate and scale portions overlap. If you want a pure rotation matrix - * you must make sure to start with the identity matrix. - * @param inRotation Euler angle rotation - * @param inRotationOrder rotation order - * @param inCoordinateSystem the coordindate system - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::SetRotate(const RuntimeVector3 &inRotation, const UINT8 inRotationOrder, - const UINT8 inCoordinateSystem) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - Q3DStudio_UNREFERENCED_PARAMETER(inCoordinateSystem); - - EulerAngles theEulerAngles; - switch (inRotationOrder) { - case ROTATIONORDER_XYZ: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdXYZs; - break; - case ROTATIONORDER_XYZR: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdXYZr; - break; - case ROTATIONORDER_YZX: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdYZXs; - break; - case ROTATIONORDER_YZXR: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdYZXr; - break; - case ROTATIONORDER_ZXY: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdZXYs; - break; - case ROTATIONORDER_ZXYR: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdZXYr; - break; - case ROTATIONORDER_XZY: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdXZYs; - break; - case ROTATIONORDER_XZYR: - theEulerAngles.x = inRotation.m_X; - theEulerAngles.y = inRotation.m_Z; - theEulerAngles.z = inRotation.m_Y; - theEulerAngles.w = EulOrdXZYr; - break; - case ROTATIONORDER_YXZ: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdYXZs; - break; - case ROTATIONORDER_YXZR: - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdYXZr; - break; - case ROTATIONORDER_ZYX: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdZYXs; - break; - case ROTATIONORDER_ZYXR: - theEulerAngles.x = inRotation.m_Z; - theEulerAngles.y = inRotation.m_Y; - theEulerAngles.z = inRotation.m_X; - theEulerAngles.w = EulOrdZYXr; - break; - default: // defaults to Studio's rotation type - theEulerAngles.x = inRotation.m_Y; - theEulerAngles.y = inRotation.m_X; - theEulerAngles.z = inRotation.m_Z; - theEulerAngles.w = EulOrdYXZs; - break; - } - - theEulerAngles.x *= -1; - theEulerAngles.y *= -1; - theEulerAngles.z *= -1; - - CEulerAngleConverter theConverter; - theConverter.Eul_ToHMatrix(theEulerAngles, m_Data); - - return *this; -} - -//============================================================================== -/** - * Sets the scale portion of the matrix without affecting the rest. - * - * FYI: The rotate and scale portions overlap. If you want a pure scale matrix - * you must make sure to start with the identity matrix. - * @param inScale scale vector - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::SetScale(const RuntimeVector3 &inScale) -{ - m_Data[0][0] = inScale.m_X; - m_Data[1][1] = inScale.m_Y; - m_Data[2][2] = inScale.m_Z; - return *this; -} - -//============================================================================== -/** - * Check this matrix against the identity matrix. - * @return true if this matrix is equivalent to the identity matrix - */ -BOOL RuntimeMatrix::IsIdentity() const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - return *this == IDENTITY; -} - -//============================================================================== -/** - * Checks to see if this matrix is affine. - * An affine matrix has the last row being [ 0 0 0 1 ] - * @return true if the matrix is affine - */ -BOOL RuntimeMatrix::IsAffine() const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - return m_Data[0][3] == 0 && m_Data[1][3] == 0 && m_Data[2][3] == 0 && m_Data[3][3] == 1.0f; -} - -//============================================================================== -/** - * Appends the matrix to include a translation. Equivalent to post-multiplying - * this matrix with a transformation matrix derived from the given vector. - * @param inTranslation transformation vector applied - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Translate(const RuntimeVector3 &inTranslation) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - m_Data[3][0] += inTranslation.m_X; - m_Data[3][1] += inTranslation.m_Y; - m_Data[3][2] += inTranslation.m_Z; - return *this; -} - -//============================================================================== -/** - * Appends the matrix to include a rotation. Equivalent to post-multiplying - * this matrix with a rotation matrix derived from the given quaternion. - * @param inRotation the rotation quaternion applied - * @return reference to this modified matrix - */ -// CMatrix& CMatrix::Rotate( const CQuaternion& inRotation ) -//{ -// CMatrix theRotation; -// return MultiplyAffine( inRotation.ToMatrix( theRotation ) ); -//} - -//============================================================================== -/** - * Appends the matrix to include scaling. Equivalent to post-multiplying - * this matrix with a scale matrix derived from the given vector. - * @param inScale the scale vector applied - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Scale(const RuntimeVector3 &inScale) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - m_Data[0][0] *= inScale.m_X; - m_Data[0][1] *= inScale.m_X; - m_Data[0][2] *= inScale.m_X; - - m_Data[1][0] *= inScale.m_Y; - m_Data[1][1] *= inScale.m_Y; - m_Data[1][2] *= inScale.m_Y; - - m_Data[2][0] *= inScale.m_Z; - m_Data[2][1] *= inScale.m_Z; - m_Data[2][2] *= inScale.m_Z; - return *this; -} - -//============================================================================== -/** - * Flips the matrix elements around the identity diagonal. - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::Transpose() -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theSwap = m_Data[1][0]; - m_Data[1][0] = m_Data[0][1]; - m_Data[0][1] = theSwap; - - theSwap = m_Data[2][0]; - m_Data[2][0] = m_Data[0][2]; - m_Data[0][2] = theSwap; - - theSwap = m_Data[3][0]; - m_Data[3][0] = m_Data[0][3]; - m_Data[0][3] = theSwap; - - theSwap = m_Data[2][1]; - m_Data[2][1] = m_Data[1][2]; - m_Data[1][2] = theSwap; - - theSwap = m_Data[3][1]; - m_Data[3][1] = m_Data[1][3]; - m_Data[1][3] = theSwap; - - theSwap = m_Data[3][2]; - m_Data[3][2] = m_Data[2][3]; - m_Data[2][3] = theSwap; - - return *this; -} - -//============================================================================== -/** - * Compute the inverse of a 3D affine matrix; i.e. a matrix with a - * dimensionality of 4 where the bottom row has the entries (0, 0, 0, 1). - * - * This procedure treats the 4 by 4 matrix as a block matrix and - * calculates the inverse of one submatrix for a significant performance - * improvement over a general procedure that can invert any non-singular matrix: -@code - | | -1 | -1 -1 | - | A C | | A -C A | - -1 | | | | - M = | | = | | - | 0 1 | | 0 1 | - | | | | -@endcode - * where M is a 4 by 4 matrix, - * A is the 3 by 3 upper left submatrix of M, - * C is the 3 by 1 upper right submatrix of M. - * - * @return the determinant of matrix - */ -FLOAT RuntimeMatrix::Invert() -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - const FLOAT PRECISIONLIMIT = 1.0e-07f; - FLOAT thePositiveDet = 0.0f; - FLOAT theNegativeDet = 0.0f; - FLOAT theTempDet; - - // Calculate the determinant of submatrix A and determine if the - // the matrix is singular as limited by the float precision. - theTempDet = m_Data[0][0] * m_Data[1][1] * m_Data[2][2]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = m_Data[0][1] * m_Data[1][2] * m_Data[2][0]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = m_Data[0][2] * m_Data[1][0] * m_Data[2][1]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = -m_Data[0][2] * m_Data[1][1] * m_Data[2][0]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = -m_Data[0][1] * m_Data[1][0] * m_Data[2][2]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - theTempDet = -m_Data[0][0] * m_Data[1][2] * m_Data[2][1]; - if (theTempDet >= 0.0f) - thePositiveDet += theTempDet; - else - theNegativeDet += theTempDet; - - // Is the submatrix A nonsingular? (i.e. there is an inverse?) - FLOAT theDeterminant = thePositiveDet + theNegativeDet; - if (theDeterminant != 0 - || ::fabs(theDeterminant / (thePositiveDet - theNegativeDet)) >= PRECISIONLIMIT) { - RuntimeMatrix theInverse; - FLOAT theInvDeterminant = 1.0f / theDeterminant; - - // Calculate inverse(A) = adj(A) / det(A) - theInverse.m_Data[0][0] = - (m_Data[1][1] * m_Data[2][2] - m_Data[1][2] * m_Data[2][1]) * theInvDeterminant; - theInverse.m_Data[1][0] = - -(m_Data[1][0] * m_Data[2][2] - m_Data[1][2] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[2][0] = - (m_Data[1][0] * m_Data[2][1] - m_Data[1][1] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[0][1] = - -(m_Data[0][1] * m_Data[2][2] - m_Data[0][2] * m_Data[2][1]) * theInvDeterminant; - theInverse.m_Data[1][1] = - (m_Data[0][0] * m_Data[2][2] - m_Data[0][2] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[2][1] = - -(m_Data[0][0] * m_Data[2][1] - m_Data[0][1] * m_Data[2][0]) * theInvDeterminant; - theInverse.m_Data[0][2] = - (m_Data[0][1] * m_Data[1][2] - m_Data[0][2] * m_Data[1][1]) * theInvDeterminant; - theInverse.m_Data[1][2] = - -(m_Data[0][0] * m_Data[1][2] - m_Data[0][2] * m_Data[1][0]) * theInvDeterminant; - theInverse.m_Data[2][2] = - (m_Data[0][0] * m_Data[1][1] - m_Data[0][1] * m_Data[1][0]) * theInvDeterminant; - - // Calculate -C * inverse(A) - theInverse.m_Data[3][0] = - -(m_Data[3][0] * theInverse.m_Data[0][0] + m_Data[3][1] * theInverse.m_Data[1][0] - + m_Data[3][2] * theInverse.m_Data[2][0]); - theInverse.m_Data[3][1] = - -(m_Data[3][0] * theInverse.m_Data[0][1] + m_Data[3][1] * theInverse.m_Data[1][1] - + m_Data[3][2] * theInverse.m_Data[2][1]); - theInverse.m_Data[3][2] = - -(m_Data[3][0] * theInverse.m_Data[0][2] + m_Data[3][1] * theInverse.m_Data[1][2] - + m_Data[3][2] * theInverse.m_Data[2][2]); - - // assign ourselves to the inverse - *this = theInverse; - } - - return theDeterminant; -} - -//============================================================================== -/** - * Fast multiplication of two affine 4x4 matrices. No affine pre-check. - * @todo MF - Convert to SSE Assembly Code - * @param inMatrix the source matrix - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::MultiplyAffine(const RuntimeMatrix &inMatrix) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theMult[4][4]; - - theMult[0][0] = m_Data[0][0] * inMatrix.m_Data[0][0] + m_Data[0][1] * inMatrix.m_Data[1][0] - + m_Data[0][2] * inMatrix.m_Data[2][0]; - theMult[0][1] = m_Data[0][0] * inMatrix.m_Data[0][1] + m_Data[0][1] * inMatrix.m_Data[1][1] - + m_Data[0][2] * inMatrix.m_Data[2][1]; - theMult[0][2] = m_Data[0][0] * inMatrix.m_Data[0][2] + m_Data[0][1] * inMatrix.m_Data[1][2] - + m_Data[0][2] * inMatrix.m_Data[2][2]; - theMult[0][3] = 0; - - theMult[1][0] = m_Data[1][0] * inMatrix.m_Data[0][0] + m_Data[1][1] * inMatrix.m_Data[1][0] - + m_Data[1][2] * inMatrix.m_Data[2][0]; - theMult[1][1] = m_Data[1][0] * inMatrix.m_Data[0][1] + m_Data[1][1] * inMatrix.m_Data[1][1] - + m_Data[1][2] * inMatrix.m_Data[2][1]; - theMult[1][2] = m_Data[1][0] * inMatrix.m_Data[0][2] + m_Data[1][1] * inMatrix.m_Data[1][2] - + m_Data[1][2] * inMatrix.m_Data[2][2]; - theMult[1][3] = 0; - - theMult[2][0] = m_Data[2][0] * inMatrix.m_Data[0][0] + m_Data[2][1] * inMatrix.m_Data[1][0] - + m_Data[2][2] * inMatrix.m_Data[2][0]; - theMult[2][1] = m_Data[2][0] * inMatrix.m_Data[0][1] + m_Data[2][1] * inMatrix.m_Data[1][1] - + m_Data[2][2] * inMatrix.m_Data[2][1]; - theMult[2][2] = m_Data[2][0] * inMatrix.m_Data[0][2] + m_Data[2][1] * inMatrix.m_Data[1][2] - + m_Data[2][2] * inMatrix.m_Data[2][2]; - theMult[2][3] = 0; - - theMult[3][0] = m_Data[3][0] * inMatrix.m_Data[0][0] + m_Data[3][1] * inMatrix.m_Data[1][0] - + m_Data[3][2] * inMatrix.m_Data[2][0] + inMatrix.m_Data[3][0]; - theMult[3][1] = m_Data[3][0] * inMatrix.m_Data[0][1] + m_Data[3][1] * inMatrix.m_Data[1][1] - + m_Data[3][2] * inMatrix.m_Data[2][1] + inMatrix.m_Data[3][1]; - theMult[3][2] = m_Data[3][0] * inMatrix.m_Data[0][2] + m_Data[3][1] * inMatrix.m_Data[1][2] - + m_Data[3][2] * inMatrix.m_Data[2][2] + inMatrix.m_Data[3][2]; - theMult[3][3] = 1.0f; - - return Set(theMult); -} - -//============================================================================== -/** - * Standard matrix multiplication - * @todo MF - Convert to SSE Assembly Code - * @param inMatrix matrix to multiply with - */ -RuntimeMatrix &RuntimeMatrix::Multiply(const RuntimeMatrix &inMatrix) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theMult[4][4]; - - theMult[0][0] = m_Data[0][0] * inMatrix.m_Data[0][0] + m_Data[1][0] * inMatrix.m_Data[0][1] - + m_Data[2][0] * inMatrix.m_Data[0][2] + m_Data[3][0] * inMatrix.m_Data[0][3]; - theMult[0][1] = m_Data[0][1] * inMatrix.m_Data[0][0] + m_Data[1][1] * inMatrix.m_Data[0][1] - + m_Data[2][1] * inMatrix.m_Data[0][2] + m_Data[3][1] * inMatrix.m_Data[0][3]; - theMult[0][2] = m_Data[0][2] * inMatrix.m_Data[0][0] + m_Data[1][2] * inMatrix.m_Data[0][1] - + m_Data[2][2] * inMatrix.m_Data[0][2] + m_Data[3][2] * inMatrix.m_Data[0][3]; - theMult[0][3] = m_Data[0][3] * inMatrix.m_Data[0][0] + m_Data[1][3] * inMatrix.m_Data[0][1] - + m_Data[2][3] * inMatrix.m_Data[0][2] + m_Data[3][3] * inMatrix.m_Data[0][3]; - theMult[1][0] = m_Data[0][0] * inMatrix.m_Data[1][0] + m_Data[1][0] * inMatrix.m_Data[1][1] - + m_Data[2][0] * inMatrix.m_Data[1][2] + m_Data[3][0] * inMatrix.m_Data[1][3]; - theMult[1][1] = m_Data[0][1] * inMatrix.m_Data[1][0] + m_Data[1][1] * inMatrix.m_Data[1][1] - + m_Data[2][1] * inMatrix.m_Data[1][2] + m_Data[3][1] * inMatrix.m_Data[1][3]; - theMult[1][2] = m_Data[0][2] * inMatrix.m_Data[1][0] + m_Data[1][2] * inMatrix.m_Data[1][1] - + m_Data[2][2] * inMatrix.m_Data[1][2] + m_Data[3][2] * inMatrix.m_Data[1][3]; - theMult[1][3] = m_Data[0][3] * inMatrix.m_Data[1][0] + m_Data[1][3] * inMatrix.m_Data[1][1] - + m_Data[2][3] * inMatrix.m_Data[1][2] + m_Data[3][3] * inMatrix.m_Data[1][3]; - theMult[2][0] = m_Data[0][0] * inMatrix.m_Data[2][0] + m_Data[1][0] * inMatrix.m_Data[2][1] - + m_Data[2][0] * inMatrix.m_Data[2][2] + m_Data[3][0] * inMatrix.m_Data[2][3]; - theMult[2][1] = m_Data[0][1] * inMatrix.m_Data[2][0] + m_Data[1][1] * inMatrix.m_Data[2][1] - + m_Data[2][1] * inMatrix.m_Data[2][2] + m_Data[3][1] * inMatrix.m_Data[2][3]; - theMult[2][2] = m_Data[0][2] * inMatrix.m_Data[2][0] + m_Data[1][2] * inMatrix.m_Data[2][1] - + m_Data[2][2] * inMatrix.m_Data[2][2] + m_Data[3][2] * inMatrix.m_Data[2][3]; - theMult[2][3] = m_Data[0][3] * inMatrix.m_Data[2][0] + m_Data[1][3] * inMatrix.m_Data[2][1] - + m_Data[2][3] * inMatrix.m_Data[2][2] + m_Data[3][3] * inMatrix.m_Data[2][3]; - - theMult[3][0] = m_Data[0][0] * inMatrix.m_Data[3][0] + m_Data[1][0] * inMatrix.m_Data[3][1] - + m_Data[2][0] * inMatrix.m_Data[3][2] + m_Data[3][0] * inMatrix.m_Data[3][3]; - theMult[3][1] = m_Data[0][1] * inMatrix.m_Data[3][0] + m_Data[1][1] * inMatrix.m_Data[3][1] - + m_Data[2][1] * inMatrix.m_Data[3][2] + m_Data[3][1] * inMatrix.m_Data[3][3]; - theMult[3][2] = m_Data[0][2] * inMatrix.m_Data[3][0] + m_Data[1][2] * inMatrix.m_Data[3][1] - + m_Data[2][2] * inMatrix.m_Data[3][2] + m_Data[3][2] * inMatrix.m_Data[3][3]; - theMult[3][3] = m_Data[0][3] * inMatrix.m_Data[3][0] + m_Data[1][3] * inMatrix.m_Data[3][1] - + m_Data[2][3] * inMatrix.m_Data[3][2] + m_Data[3][3] * inMatrix.m_Data[3][3]; - - return Set(theMult); -} - -//============================================================================== -/** - * Toggle between left-hand and right-hand coordinate system - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::FlipCoordinateSystem() -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - // rotation conversion - m_Data[0][2] *= -1; - m_Data[1][2] *= -1; - m_Data[2][0] *= -1; - m_Data[2][1] *= -1; - - // translation conversion - m_Data[3][2] *= -1; - - return *this; -} - -//============================================================================== -/** - * Rotate this matrix to align with the rotation of the specified matrix. - * - * @param inMatrix the maxtrix we are cloning. - * @param inMirrorFlag flag indicating that we should flip the z and face the opposite - *direction. - * @return This matrix after the rotation. - */ -RuntimeMatrix &RuntimeMatrix::CloneRotation(const RuntimeMatrix &inMatrix, BOOL inMirrorFlag /*= false*/) -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - // Create the axes - RuntimeVector3 theZ(inMatrix.Get(2, 0), inMatrix.Get(2, 1), inMatrix.Get(2, 2)); - if (inMirrorFlag) - theZ *= -1; - RuntimeVector3 theY(inMatrix.Get(1, 0), inMatrix.Get(1, 1), inMatrix.Get(1, 2)); - RuntimeVector3 theX(theY); - theX.CrossProduct(theZ); - - // Normalize - theX.Normalize(); - theY.Normalize(); - theZ.Normalize(); - - // Copy it into the matrix - m_Data[0][0] = theX.m_X; - m_Data[0][1] = theX.m_Y; - m_Data[0][2] = theX.m_Z; - - m_Data[1][0] = theY.m_X; - m_Data[1][1] = theY.m_Y; - m_Data[1][2] = theY.m_Z; - - m_Data[2][0] = theZ.m_X; - m_Data[2][1] = theZ.m_Y; - m_Data[2][2] = theZ.m_Z; - - return *this; -} - -//============================================================================== -/** - * Compute the square distance between the position vectors of two transforms. - * @param inMatrix the other transform, signifying a global object position for example - * @return the square of the "distance" between the two transforms - */ -FLOAT RuntimeMatrix::SquareDistance(const RuntimeMatrix &inMatrix) const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - FLOAT theResult = 0; - FLOAT theFactor; - - theFactor = m_Data[3][0] - inMatrix.m_Data[3][0]; - theFactor *= theFactor; - theResult += theFactor; - - theFactor = m_Data[3][1] - inMatrix.m_Data[3][1]; - theFactor *= theFactor; - theResult += theFactor; - - theFactor = m_Data[3][2] - inMatrix.m_Data[3][2]; - theFactor *= theFactor; - theResult += theFactor; - - return theResult; -} - -//============================================================================== -/** - * Simple assignment operator. - * @param inMatrix new matrix being assigned - * @return reference to this modified matrix - */ -RuntimeMatrix &RuntimeMatrix::operator=(const RuntimeMatrix &inMatrix) -{ - Q3DStudio_memcpy(&m_Data, &inMatrix.m_Data, sizeof(m_Data)); - return *this; -} - -//============================================================================== -/** - * Compares this matrix's elements with another matrix's and returns true - * if the matrices are equivalent. - * @param inMatrix the matrix we are comparing against - * @return true if all elements are within EPSILON of each other. - */ -BOOL RuntimeMatrix::operator==(const RuntimeMatrix &inMatrix) const -{ - PerfLogMathEvent1(DATALOGGER_MATRIX); - - for (INT32 iRow = 0; iRow < 4; ++iRow) { - for (INT32 iCol = 0; iCol < 4; ++iCol) { - if (::fabs(m_Data[iRow][iCol] - inMatrix.m_Data[iRow][iCol]) > RUNTIME_EPSILON) - return false; - } - } - return true; -} - -//============================================================================== -/** - * Compares this matrix's elements with another matrix's and returns true - * if the matrices are not equivalent. - * @param inMatrix the matrix we are comparing against - * @return true if one or more elements are more than EPSILON from each other - */ -BOOL RuntimeMatrix::operator!=(const RuntimeMatrix &inMatrix) const -{ - // Reuse same code path.. - return !(*this == inMatrix); -} - -//============================================================================== -/** - * Standardized conversion to string. - * @param outString string becoming a representation for the matrix - */ -// void CMatrix::ToString( AK_STRING& outString ) const -//{ -// INT8 theBuffer[ 256 ]; -// -// Q3DStudio_sprintf -// ( -// theBuffer, 255, -// "%.2f %.2f %.2f %.2f " -// "%.2f %.2f %.2f %.2f " -// "%.2f %.2f %.2f %.2f " -// "%.2f %.2f %.2f %.2f", -// -// m_Data.m[ 0 ][ 0 ], -// m_Data.m[ 0 ][ 1 ], -// m_Data.m[ 0 ][ 2 ], -// m_Data.m[ 0 ][ 3 ], -// -// m_Data.m[ 1 ][ 0 ], -// m_Data.m[ 1 ][ 1 ], -// m_Data.m[ 1 ][ 2 ], -// m_Data.m[ 1 ][ 3 ], -// -// m_Data.m[ 2 ][ 0 ], -// m_Data.m[ 2 ][ 1 ], -// m_Data.m[ 2 ][ 2 ], -// m_Data.m[ 2 ][ 3 ], -// -// m_Data.m[ 3 ][ 0 ], -// m_Data.m[ 3 ][ 1 ], -// m_Data.m[ 3 ][ 2 ], -// m_Data.m[ 3 ][ 3 ] -// ); -// -// outString = theBuffer; -//} -// -////============================================================================== -///** -// * Standardized conversion from string. -// * @param inString string being a representation for the matrix -// */ -// void CMatrix::FromString( const AK_STRING& inString ) -//{ -// std::sscanf -// ( -// inString.c_str( ), -// -// "%f %f %f %f " -// "%f %f %f %f " -// "%f %f %f %f " -// "%f %f %f %f", -// -// &m_Data.m[ 0 ][ 0 ], -// &m_Data.m[ 0 ][ 1 ], -// &m_Data.m[ 0 ][ 2 ], -// &m_Data.m[ 0 ][ 3 ], -// -// &m_Data.m[ 1 ][ 0 ], -// &m_Data.m[ 1 ][ 1 ], -// &m_Data.m[ 1 ][ 2 ], -// &m_Data.m[ 1 ][ 3 ], -// -// &m_Data.m[ 2 ][ 0 ], -// &m_Data.m[ 2 ][ 1 ], -// &m_Data.m[ 2 ][ 2 ], -// &m_Data.m[ 2 ][ 3 ], -// -// &m_Data.m[ 3 ][ 0 ], -// &m_Data.m[ 3 ][ 1 ], -// &m_Data.m[ 3 ][ 2 ], -// &m_Data.m[ 3 ][ 3 ] -// ); -//} - -} // namespace Q3DStudio |