1011 lines
No EOL
43 KiB
C++
1011 lines
No EOL
43 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program 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 General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/* $Header: /Commando/Code/Tools/max2w3d/WWmatrix3.h 33 2/03/00 4:55p Jason_a $ */
|
|
/***********************************************************************************************
|
|
*** Confidential - Westwood Studios ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : WW3D *
|
|
* *
|
|
* File Name : MATRIX3.H *
|
|
* *
|
|
* Programmer : Greg Hjelstrom *
|
|
* *
|
|
* Start Date : 06/02/97 *
|
|
* *
|
|
* Last Update : June 2, 1997 [GH] *
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* Matrix3::Matrix3 -- Constructor, optionally initialize to Identitiy matrix *
|
|
* Matrix3::Matrix3 -- Copy Constructor *
|
|
* Matrix3::Matrix3 -- Convert a Matrix3D (fake 4x4) to a Matrix3 *
|
|
* Matrix3::Matrix3 -- Constructor *
|
|
* Matrix3::Transpose -- Returns transpose of the matrix *
|
|
* Matrix3::Inverse -- returns the inverse of the matrix *
|
|
* Matrix3::Determinant -- returns the determinant of the matrix *
|
|
* Matrix3::operator = -- assignment operator *
|
|
* Matrix3::operator += -- "plus equals" operator *
|
|
* Matrix3::operator-= -- "minus equals" operator *
|
|
* Matrix3::operator *= -- "times equals" operator *
|
|
* Matrix3::operator /= -- "divide equals" operator *
|
|
* Create_X_Rotation_Matrix3 -- creates a matrix3 which is a rotation about X *
|
|
* Create_Y_Rotation_Matrix3 -- Creates a Matrix3 which is a rotation about Y *
|
|
* Create_Z_Rotation_Matrix3 -- Creates a matrix3 which is a rotation about Z *
|
|
* Matrix3::Rotate_X -- Post-mutiplies an x rotation onto the current matrix *
|
|
* Matrix3::Rotate_Y -- Post-multiplies the matrix with a rotation about Y *
|
|
* Matrix3::Rotate_Z -- Post-multiplies the matrix with a rotation about Z *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifndef Matrix3_H
|
|
#define Matrix3_H
|
|
|
|
#include "always.h"
|
|
#include "vector3.h"
|
|
//#include "wwdebug.h"
|
|
|
|
|
|
class Matrix3D;
|
|
class Matrix4;
|
|
class Quaternion;
|
|
|
|
class Matrix3
|
|
{
|
|
public:
|
|
|
|
/*
|
|
** Constructors
|
|
*/
|
|
Matrix3(void) {};
|
|
Matrix3(const Matrix3 & m);
|
|
|
|
explicit Matrix3(bool identity);
|
|
explicit Matrix3(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2);
|
|
explicit Matrix3(const Matrix3D & m);
|
|
explicit Matrix3(const Matrix4 & m);
|
|
explicit Matrix3(
|
|
float m11,float m12,float m13,
|
|
float m21,float m22,float m23,
|
|
float m31,float m32,float m33
|
|
);
|
|
explicit Matrix3(const Vector3 & axis,float angle);
|
|
explicit Matrix3(const Vector3 & axis,float s_angle,float c_angle);
|
|
explicit Matrix3(const Quaternion & q);
|
|
|
|
/*
|
|
** 'Set' functions
|
|
*/
|
|
void Set(const Matrix3D & m);
|
|
void Set(const Matrix4 & m);
|
|
void Set(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2);
|
|
void Set(
|
|
float m11,float m12,float m13,
|
|
float m21,float m22,float m23,
|
|
float m31,float m32,float m33
|
|
);
|
|
void Set(const Vector3 & axis,float angle);
|
|
void Set(const Vector3 & axis,float s_angle,float c_angle);
|
|
void Set(const Quaternion & q);
|
|
|
|
/*
|
|
** Access operators
|
|
*/
|
|
Vector3 & operator [] (int i) { return Row[i]; }
|
|
const Vector3 & operator [] (int i) const { return Row[i]; }
|
|
|
|
/*
|
|
** Transpose and Inverse
|
|
*/
|
|
Matrix3 Transpose (void) const;
|
|
Matrix3 Inverse (void) const;
|
|
float Determinant (void) const;
|
|
|
|
/*
|
|
** Assignment operators
|
|
*/
|
|
Matrix3 & operator = (const Matrix3 & m);
|
|
Matrix3 & operator = (const Matrix3D & m);
|
|
Matrix3 & operator = (const Matrix4 & m);
|
|
|
|
Matrix3 & operator += (const Matrix3 & m);
|
|
Matrix3 & operator -= (const Matrix3 & m);
|
|
Matrix3 & operator *= (float d);
|
|
Matrix3 & operator /= (float d);
|
|
|
|
void Make_Identity(void);
|
|
|
|
/*
|
|
** Automatically concatenate a rotation onto the current matrix
|
|
*/
|
|
void Rotate_X(float theta);
|
|
void Rotate_X(float s,float c);
|
|
|
|
void Rotate_Y(float theta);
|
|
void Rotate_Y(float s,float c);
|
|
|
|
void Rotate_Z(float theta);
|
|
void Rotate_Z(float s,float c);
|
|
|
|
/*
|
|
** These functions will give you the approximate amount that the
|
|
** matrix has been rotated about a given axis. These functions
|
|
** cannot be used to re-build a matrx. Use the EulerAnglesClass
|
|
** to convert a matrix into a set of three Euler angles.
|
|
*/
|
|
float Get_X_Rotation(void) const;
|
|
float Get_Y_Rotation(void) const;
|
|
float Get_Z_Rotation(void) const;
|
|
|
|
/*
|
|
** These functions return a vector representing the direction an
|
|
** axis is pointing.
|
|
*/
|
|
Vector3 Get_X_Vector(void) const;
|
|
Vector3 Get_Y_Vector(void) const;
|
|
Vector3 Get_Z_Vector(void) const;
|
|
void Get_X_Vector(Vector3 * set_x) const;
|
|
void Get_Y_Vector(Vector3 * set_y) const;
|
|
void Get_Z_Vector(Vector3 * set_z) const;
|
|
|
|
/*
|
|
** Negation
|
|
*/
|
|
friend Matrix3 operator - (const Matrix3& a);
|
|
|
|
/*
|
|
** Scalar multiplication and division
|
|
*/
|
|
friend Matrix3 operator * (const Matrix3& a,float d);
|
|
friend Matrix3 operator * (float d,const Matrix3& a);
|
|
friend Matrix3 operator / (const Matrix3& a,float d);
|
|
|
|
/*
|
|
** matrix addition
|
|
*/
|
|
friend Matrix3 operator + (const Matrix3& a, const Matrix3& b);
|
|
static void Add(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
|
|
|
|
/*
|
|
** matrix subtraction
|
|
*/
|
|
friend Matrix3 operator - (const Matrix3 & a, const Matrix3 & b);
|
|
static void Subtract(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
|
|
|
|
/*
|
|
** matrix multiplication
|
|
*/
|
|
friend Matrix3 operator * (const Matrix3 & a, const Matrix3 & b);
|
|
friend Matrix3 operator * (const Matrix3D & a, const Matrix3 & b);
|
|
friend Matrix3 operator * (const Matrix3 & a, const Matrix3D & b);
|
|
|
|
static void Multiply(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
|
|
static void Multiply(const Matrix3D & a, const Matrix3 & b,Matrix3 * res);
|
|
static void Multiply(const Matrix3 & a, const Matrix3D & b,Matrix3 * res);
|
|
|
|
/*
|
|
** Matrix-Vector multiplication
|
|
*/
|
|
friend Vector3 operator * (const Matrix3 & a, const Vector3 & v);
|
|
static void Rotate_Vector(const Matrix3 & tm,const Vector3 & in,Vector3 * out);
|
|
static void Transpose_Rotate_Vector(const Matrix3 & tm,const Vector3 & in,Vector3 * out);
|
|
|
|
/*
|
|
** Comparison operators
|
|
*/
|
|
friend int operator == (const Matrix3 & a, const Matrix3 & b);
|
|
friend int operator != (const Matrix3 & a, const Matrix3 & b);
|
|
|
|
/*
|
|
** Swap two matrices in place
|
|
*/
|
|
friend void Swap(Matrix3 & a,Matrix3 & b);
|
|
|
|
/*
|
|
** Check whether a matrix is orthogonal, make it orthogonal
|
|
*/
|
|
int Is_Orthogonal(void) const;
|
|
void Re_Orthogonalize(void);
|
|
|
|
/*
|
|
** Miscellaneous
|
|
*/
|
|
void Rotate_AABox_Extent(const Vector3 & extent,Vector3 * new_extent);
|
|
|
|
/*
|
|
** Some useful pre-initialized Matrix3's
|
|
*/
|
|
static const Matrix3 Identity;
|
|
static const Matrix3 RotateX90;
|
|
static const Matrix3 RotateX180;
|
|
static const Matrix3 RotateX270;
|
|
static const Matrix3 RotateY90;
|
|
static const Matrix3 RotateY180;
|
|
static const Matrix3 RotateY270;
|
|
static const Matrix3 RotateZ90;
|
|
static const Matrix3 RotateZ180;
|
|
static const Matrix3 RotateZ270;
|
|
|
|
protected:
|
|
|
|
Vector3 Row[3];
|
|
|
|
};
|
|
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Matrix3 -- Constructor, optionally initialize to Identitiy matrix *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3::Matrix3(bool identity)
|
|
{
|
|
if (identity) {
|
|
Row[0].Set(1.0,0.0,0.0);
|
|
Row[1].Set(0.0,1.0,0.0);
|
|
Row[2].Set(0.0,0.0,1.0);
|
|
}
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Matrix3 -- Copy Constructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3::Matrix3(const Matrix3 & m)
|
|
{
|
|
Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2];
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Matrix3 -- Constructor *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3::Matrix3(const Vector3 & r0, const Vector3 & r1, const Vector3 & r2)
|
|
{
|
|
Row[0] = r0;
|
|
Row[1] = r1;
|
|
Row[2] = r2;
|
|
}
|
|
|
|
inline void Matrix3::Set(const Vector3 & r0, const Vector3 & r1, const Vector3 & r2)
|
|
{
|
|
Row[0] = r0;
|
|
Row[1] = r1;
|
|
Row[2] = r2;
|
|
}
|
|
|
|
inline void Matrix3::Make_Identity(void)
|
|
{
|
|
Row[0].Set(1.0f,0.0f,0.0f);
|
|
Row[1].Set(0.0f,1.0f,0.0f);
|
|
Row[2].Set(0.0f,0.0f,1.0f);
|
|
}
|
|
|
|
|
|
inline Matrix3::Matrix3
|
|
(
|
|
float m11,float m12,float m13,
|
|
float m21,float m22,float m23,
|
|
float m31,float m32,float m33
|
|
)
|
|
{
|
|
Row[0].Set(m11,m12,m13);
|
|
Row[1].Set(m21,m22,m23);
|
|
Row[2].Set(m31,m32,m33);
|
|
}
|
|
|
|
inline void Matrix3::Set
|
|
(
|
|
float m11,float m12,float m13,
|
|
float m21,float m22,float m23,
|
|
float m31,float m32,float m33
|
|
)
|
|
{
|
|
Row[0].Set(m11,m12,m13);
|
|
Row[1].Set(m21,m22,m23);
|
|
Row[2].Set(m31,m32,m33);
|
|
}
|
|
|
|
inline Matrix3::Matrix3(const Vector3 & axis,float angle)
|
|
{
|
|
Set(axis,angle);
|
|
}
|
|
|
|
inline Matrix3::Matrix3(const Vector3 & axis,float s_angle,float c_angle)
|
|
{
|
|
Set(axis,s_angle,c_angle);
|
|
}
|
|
|
|
inline void Matrix3::Set(const Vector3 & axis,float angle)
|
|
{
|
|
Set(axis,sinf(angle),cosf(angle));
|
|
}
|
|
|
|
inline void Matrix3::Set(const Vector3 & axis,float s,float c)
|
|
{
|
|
assert(WWMath::Fabs(axis.Length2() - 1.0f) < 0.001f);
|
|
|
|
Row[0].Set(
|
|
(float)(axis[0]*axis[0] + c*(1.0f - axis[0]*axis[0])),
|
|
(float)(axis[0]*axis[1]*(1.0f - c) - axis[2]*s),
|
|
(float)(axis[2]*axis[0]*(1.0f - c) + axis[1]*s)
|
|
);
|
|
|
|
Row[1].Set(
|
|
(float)(axis[0]*axis[1]*(1.0f - c) + axis[2]*s),
|
|
(float)(axis[1]*axis[1] + c*(1.0f - axis[1]*axis[1])),
|
|
(float)(axis[1]*axis[2]*(1.0f - c) - axis[0]*s)
|
|
);
|
|
|
|
Row[2].Set(
|
|
(float)(axis[2]*axis[0]*(1.0f - c) - axis[1]*s),
|
|
(float)(axis[1]*axis[2]*(1.0f - c) + axis[0]*s),
|
|
(float)(axis[2]*axis[2] + c*(1 - axis[2]*axis[2]))
|
|
);
|
|
}
|
|
|
|
inline Matrix3::Matrix3(const Quaternion & q)
|
|
{
|
|
this->Set(q);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Transpose -- Returns transpose of the matrix *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3 Matrix3::Transpose() const
|
|
{
|
|
return Matrix3(
|
|
Vector3(Row[0][0], Row[1][0], Row[2][0]),
|
|
Vector3(Row[0][1], Row[1][1], Row[2][1]),
|
|
Vector3(Row[0][2], Row[1][2], Row[2][2])
|
|
);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Inverse -- returns the inverse of the matrix *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3 Matrix3::Inverse() const // Gauss-Jordan elimination with partial pivoting
|
|
{
|
|
Matrix3 a(*this); // As a evolves from original mat into identity
|
|
Matrix3 b(true); // b evolves from identity into inverse(a)
|
|
int i, j, i1;
|
|
|
|
// Loop over cols of a from left to right, eliminating above and below diagonal
|
|
for (j=0; j<3; j++) {
|
|
|
|
// Find largest pivot in column j among rows j..3
|
|
i1 = j;
|
|
for (i=j+1; i<3; i++) {
|
|
if (WWMath::Fabs(a[i][j]) > WWMath::Fabs(a[i1][j])) {
|
|
i1 = i;
|
|
}
|
|
}
|
|
|
|
// Swap rows i1 and j in a and b to put pivot on diagonal
|
|
Swap(a.Row[i1], a.Row[j]);
|
|
Swap(b.Row[i1], b.Row[j]);
|
|
|
|
// Scale row j to have a unit diagonal
|
|
if (a[j][j]==0.) {
|
|
//Matrix3::inverse: singular matrix; can't invert
|
|
}
|
|
b.Row[j] /= a.Row[j][j];
|
|
a.Row[j] /= a.Row[j][j];
|
|
|
|
// Eliminate off-diagonal elems in col j of a, doing identical ops to b
|
|
for (i=0; i<3; i++) {
|
|
if (i != j) {
|
|
b.Row[i] -= a[i][j] * b.Row[j];
|
|
a.Row[i] -= a[i][j] * a.Row[j];
|
|
}
|
|
}
|
|
}
|
|
return b;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Determinant -- returns the determinant of the matrix *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 1/7/20 DRM : Created. *
|
|
*=============================================================================================*/
|
|
inline float Matrix3::Determinant(void) const
|
|
{
|
|
return Row[0][0] * (Row[1][1] * Row[2][2] - Row[1][2] * Row[2][1])
|
|
- Row[0][1] * (Row[1][0] * Row[2][2] - Row[1][2] * Row[2][0])
|
|
- Row[0][2] * (Row[1][0] * Row[2][1] - Row[1][1] * Row[2][0]);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::operator = -- assignment operator *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3 & Matrix3::operator = (const Matrix3 & m)
|
|
{
|
|
Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2];
|
|
return *this;
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::operator += -- "plus equals" operator *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3& Matrix3::operator += (const Matrix3 & m)
|
|
{
|
|
Row[0] += m.Row[0]; Row[1] += m.Row[1]; Row[2] += m.Row[2];
|
|
return *this;
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::operator-= -- "minus equals" operator *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3& Matrix3::operator -= (const Matrix3 & m)
|
|
{
|
|
Row[0] -= m.Row[0]; Row[1] -= m.Row[1]; Row[2] -= m.Row[2];
|
|
return *this;
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::operator *= -- "times equals" operator *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3& Matrix3::operator *= (float d)
|
|
{
|
|
Row[0] *= d; Row[1] *= d; Row[2] *= d;
|
|
return *this;
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::operator /= -- "divide equals" operator *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 06/02/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3& Matrix3::operator /= (float d)
|
|
{
|
|
Row[0] /= d; Row[1] /= d; Row[2] /= d;
|
|
return *this;
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Get_X_Rotation -- approximates the rotation about the X axis *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline float Matrix3::Get_X_Rotation(void) const
|
|
{
|
|
Vector3 v = (*this) * Vector3(0.0,1.0,0.0);
|
|
return atan2(v[2], v[1]);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Get_Y_Rotation -- approximates the rotation about the Y axis *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline float Matrix3::Get_Y_Rotation(void) const
|
|
{
|
|
Vector3 v = (*this) * Vector3(0.0,0.0,1.0);
|
|
return atan2(v[0],v[2]);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Get_Z_Rotation -- approximates the rotation about the Z axis *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/11/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline float Matrix3::Get_Z_Rotation(void) const
|
|
{
|
|
Vector3 v = (*this) * Vector3(1.0,0.0,0.0);
|
|
return atan2(v[1],v[0]);
|
|
}
|
|
|
|
inline Vector3 Matrix3::Get_X_Vector(void) const
|
|
{
|
|
return Vector3(Row[0][0], Row[1][0], Row[2][0]);
|
|
}
|
|
|
|
inline Vector3 Matrix3::Get_Y_Vector(void) const
|
|
{
|
|
return Vector3(Row[0][1], Row[1][1], Row[2][1]);
|
|
}
|
|
|
|
inline Vector3 Matrix3::Get_Z_Vector(void) const
|
|
{
|
|
return Vector3(Row[0][2], Row[1][2], Row[2][2]);
|
|
}
|
|
|
|
inline void Matrix3::Get_X_Vector(Vector3 * set) const
|
|
{
|
|
set->Set(Row[0][0], Row[1][0], Row[2][0]);
|
|
}
|
|
|
|
inline void Matrix3::Get_Y_Vector(Vector3 * set) const
|
|
{
|
|
set->Set(Row[0][1], Row[1][1], Row[2][1]);
|
|
}
|
|
|
|
inline void Matrix3::Get_Z_Vector(Vector3 * set) const
|
|
{
|
|
set->Set(Row[0][2], Row[1][2], Row[2][2]);
|
|
}
|
|
|
|
inline Matrix3 operator - (const Matrix3 & a)
|
|
{
|
|
return Matrix3(-a.Row[0], -a.Row[1], -a.Row[2]);
|
|
}
|
|
|
|
inline Matrix3 operator * (const Matrix3 & a, float d)
|
|
{
|
|
return Matrix3(a.Row[0] * d, a.Row[1] * d, a.Row[2] * d);
|
|
}
|
|
|
|
inline Matrix3 operator * (float d, const Matrix3 & a)
|
|
{
|
|
return a*d;
|
|
}
|
|
|
|
inline Matrix3 operator / (const Matrix3 & a, float d)
|
|
{
|
|
float ood = 1.0f / d;
|
|
return Matrix3(a.Row[0] * ood, a.Row[1] * ood, a.Row[2] * ood);
|
|
}
|
|
|
|
/*
|
|
** matrix addition
|
|
*/
|
|
inline Matrix3 operator + (const Matrix3 & a, const Matrix3 & b)
|
|
{
|
|
return Matrix3(
|
|
a.Row[0] + b.Row[0],
|
|
a.Row[1] + b.Row[1],
|
|
a.Row[2] + b.Row[2]
|
|
);
|
|
}
|
|
|
|
inline void Matrix3::Add(const Matrix3 & a, const Matrix3 & b,Matrix3 * c)
|
|
{
|
|
assert(c);
|
|
Vector3::Add(a.Row[0],b.Row[0],&(c->Row[0]));
|
|
Vector3::Add(a.Row[1],b.Row[1],&(c->Row[1]));
|
|
Vector3::Add(a.Row[2],b.Row[2],&(c->Row[2]));
|
|
}
|
|
|
|
/*
|
|
** matrix subtraction
|
|
*/
|
|
inline Matrix3 operator - (const Matrix3 & a, const Matrix3 & b)
|
|
{
|
|
return Matrix3(
|
|
a.Row[0] - b.Row[0],
|
|
a.Row[1] - b.Row[1],
|
|
a.Row[2] - b.Row[2]
|
|
);
|
|
}
|
|
|
|
inline void Matrix3::Subtract(const Matrix3 & a, const Matrix3 & b,Matrix3 * c)
|
|
{
|
|
assert(c);
|
|
Vector3::Subtract(a.Row[0],b.Row[0],&(c->Row[0]));
|
|
Vector3::Subtract(a.Row[1],b.Row[1],&(c->Row[1]));
|
|
Vector3::Subtract(a.Row[2],b.Row[2],&(c->Row[2]));
|
|
}
|
|
|
|
/*
|
|
** matrix multiplication
|
|
*/
|
|
inline Matrix3 operator * (const Matrix3 & a, const Matrix3 & b)
|
|
{
|
|
#define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
|
|
|
|
return Matrix3(
|
|
Vector3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2) ),
|
|
Vector3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2) ),
|
|
Vector3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2) )
|
|
);
|
|
|
|
#undef ROWCOL
|
|
}
|
|
|
|
|
|
/*
|
|
** Multiply a Matrix3 by a Vector3. Yeilds a Vector3 result
|
|
*/
|
|
inline Vector3 operator * (const Matrix3 & a, const Vector3 & v)
|
|
{
|
|
return Vector3(
|
|
a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2],
|
|
a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2],
|
|
a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2]
|
|
);
|
|
}
|
|
|
|
|
|
inline int operator == (const Matrix3 & a, const Matrix3 & b)
|
|
{
|
|
return ((a [0] == b [0]) && (a [1] == b [1]) && (a [2] == b [2]));
|
|
}
|
|
|
|
|
|
inline int operator != (const Matrix3 & a, const Matrix3 & b)
|
|
{
|
|
return (!(a == b));
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Rotate_X -- Post-mutiplies an x rotation onto the current matrix *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/26/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline void Matrix3::Rotate_X(float theta)
|
|
{
|
|
Rotate_X(sinf(theta),cosf(theta));
|
|
}
|
|
|
|
inline void Matrix3::Rotate_X(float s,float c)
|
|
{
|
|
float tmp1,tmp2;
|
|
|
|
tmp1 = Row[0][1]; tmp2 = Row[0][2];
|
|
Row[0][1] = (float)( c*tmp1 + s*tmp2);
|
|
Row[0][2] = (float)(-s*tmp1 + c*tmp2);
|
|
|
|
tmp1 = Row[1][1]; tmp2 = Row[1][2];
|
|
Row[1][1] = (float)( c*tmp1 + s*tmp2);
|
|
Row[1][2] = (float)(-s*tmp1 + c*tmp2);
|
|
|
|
tmp1 = Row[2][1]; tmp2 = Row[2][2];
|
|
Row[2][1] = (float)( c*tmp1 + s*tmp2);
|
|
Row[2][2] = (float)(-s*tmp1 + c*tmp2);
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Rotate_Y -- Post-multiplies the matrix with a rotation about Y *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/26/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline void Matrix3::Rotate_Y(float theta)
|
|
{
|
|
Rotate_Y(sinf(theta),cosf(theta));
|
|
}
|
|
|
|
inline void Matrix3::Rotate_Y(float s,float c)
|
|
{
|
|
float tmp1,tmp2;
|
|
|
|
tmp1 = Row[0][0]; tmp2 = Row[0][2];
|
|
Row[0][0] = (float)(c*tmp1 - s*tmp2);
|
|
Row[0][2] = (float)(s*tmp1 + c*tmp2);
|
|
|
|
tmp1 = Row[1][0]; tmp2 = Row[1][2];
|
|
Row[1][0] = (float)(c*tmp1 - s*tmp2);
|
|
Row[1][2] = (float)(s*tmp1 + c*tmp2);
|
|
|
|
tmp1 = Row[2][0]; tmp2 = Row[2][2];
|
|
Row[2][0] = (float)(c*tmp1 - s*tmp2);
|
|
Row[2][2] = (float)(s*tmp1 + c*tmp2);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* Matrix3::Rotate_Z -- Post-multiplies the matrix with a rotation about Z *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/26/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline void Matrix3::Rotate_Z(float theta)
|
|
{
|
|
Rotate_Z(sinf(theta),cosf(theta));
|
|
}
|
|
|
|
inline void Matrix3::Rotate_Z(float s,float c)
|
|
{
|
|
float tmp1,tmp2;
|
|
|
|
tmp1 = Row[0][0]; tmp2 = Row[0][1];
|
|
Row[0][0] = (float)( c*tmp1 + s*tmp2);
|
|
Row[0][1] = (float)(-s*tmp1 + c*tmp2);
|
|
|
|
tmp1 = Row[1][0]; tmp2 = Row[1][1];
|
|
Row[1][0] = (float)( c*tmp1 + s*tmp2);
|
|
Row[1][1] = (float)(-s*tmp1 + c*tmp2);
|
|
|
|
tmp1 = Row[2][0]; tmp2 = Row[2][1];
|
|
Row[2][0] = (float)( c*tmp1 + s*tmp2);
|
|
Row[2][1] = (float)(-s*tmp1 + c*tmp2);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* Create_X_Rotation_Matrix3 -- creates a matrix3 which is a rotation about X *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/26/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3 Create_X_Rotation_Matrix3(float s,float c)
|
|
{
|
|
Matrix3 mat;
|
|
|
|
mat[0][0] = 1.0f;
|
|
mat[0][1] = 0.0f;
|
|
mat[0][2] = 0.0f;
|
|
|
|
mat[1][0] = 0.0f;
|
|
mat[1][1] = c;
|
|
mat[1][2] = -s;
|
|
|
|
mat[2][0] = 0.0f;
|
|
mat[2][1] = s;
|
|
mat[2][2] = c;
|
|
|
|
return mat;
|
|
}
|
|
|
|
inline Matrix3 Create_X_Rotation_Matrix3(float rad)
|
|
{
|
|
return Create_X_Rotation_Matrix3(sinf(rad),cosf(rad));
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Create_Y_Rotation_Matrix3 -- Creates a Matrix3 which is a rotation about Y *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/26/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3 Create_Y_Rotation_Matrix3(float s,float c)
|
|
{
|
|
Matrix3 mat;
|
|
|
|
mat[0][0] = c;
|
|
mat[0][1] = 0.0f;
|
|
mat[0][2] = s;
|
|
|
|
mat[1][0] = 0.0f;
|
|
mat[1][1] = 1.0f;
|
|
mat[1][2] = 0.0f;
|
|
|
|
mat[2][0] = -s;
|
|
mat[2][1] = 0.0f;
|
|
mat[2][2] = c;
|
|
|
|
return mat;
|
|
}
|
|
|
|
inline Matrix3 Create_Y_Rotation_Matrix3(float rad)
|
|
{
|
|
return Create_Y_Rotation_Matrix3(sinf(rad),cosf(rad));
|
|
}
|
|
|
|
/***********************************************************************************************
|
|
* Create_Z_Rotation_Matrix3 -- Creates a matrix3 which is a rotation about Z *
|
|
* *
|
|
* INPUT: *
|
|
* *
|
|
* OUTPUT: *
|
|
* *
|
|
* WARNINGS: *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/26/1997 GH : Created. *
|
|
*=============================================================================================*/
|
|
inline Matrix3 Create_Z_Rotation_Matrix3(float s,float c)
|
|
{
|
|
Matrix3 mat;
|
|
|
|
mat[0][0] = c;
|
|
mat[0][1] = -s;
|
|
mat[0][2] = 0.0f;
|
|
|
|
mat[1][0] = s;
|
|
mat[1][1] = c;
|
|
mat[1][2] = 0.0f;
|
|
|
|
mat[2][0] = 0.0f;
|
|
mat[2][1] = 0.0f;
|
|
mat[2][2] = 1.0f;
|
|
|
|
return mat;
|
|
}
|
|
|
|
inline Matrix3 Create_Z_Rotation_Matrix3(float rad)
|
|
{
|
|
return Create_Z_Rotation_Matrix3(sinf(rad),cosf(rad));
|
|
}
|
|
|
|
inline void Matrix3::Rotate_Vector(const Matrix3 & A,const Vector3 & in,Vector3 * out)
|
|
{
|
|
Vector3 tmp;
|
|
Vector3 * v;
|
|
|
|
// check for aliased parameters
|
|
if (out == &in) {
|
|
tmp = in;
|
|
v = &tmp;
|
|
} else {
|
|
v = (Vector3 *)∈ // whats the right way to do this...
|
|
}
|
|
|
|
out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z);
|
|
out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z);
|
|
out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z);
|
|
}
|
|
|
|
inline void Matrix3::Transpose_Rotate_Vector(const Matrix3 & A,const Vector3 & in,Vector3 * out)
|
|
{
|
|
Vector3 tmp;
|
|
Vector3 * v;
|
|
|
|
// check for aliased parameters
|
|
if (out == &in) {
|
|
tmp = in;
|
|
v = &tmp;
|
|
} else {
|
|
v = (Vector3 *)∈
|
|
}
|
|
out->X = (A[0][0] * v->X + A[1][0] * v->Y + A[2][0] * v->Z);
|
|
out->Y = (A[0][1] * v->X + A[1][1] * v->Y + A[2][1] * v->Z);
|
|
out->Z = (A[0][2] * v->X + A[1][2] * v->Y + A[2][2] * v->Z);
|
|
}
|
|
|
|
#endif /*Matrix3_H*/ |