| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- /*
- ** Command & Conquer Generals Zero Hour(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/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WWMath *
- * *
- * $Archive:: /Commando/Code/Tools/max2w3d/WWmatrix3.cpp $*
- * *
- * Author:: Greg_h *
- * *
- * $Modtime:: 2/02/00 2:05p $*
- * *
- * $Revision:: 17 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "wwmatrix3.h"
- #include "matrix3d.h"
- #include "matrix4.h"
- #include "w3dquat.h"
- /*
- ** Some pre-initialized Matrix3's
- */
- const Matrix3 Matrix3::Identity
- (
- 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 0.0, 0.0, 1.0
- );
- const Matrix3 Matrix3::RotateX90
- (
- 1.0, 0.0, 0.0,
- 0.0, 0.0, -1.0,
- 0.0, 1.0, 0.0
- );
- const Matrix3 Matrix3::RotateX180
- (
- 1.0, 0.0, 0.0,
- 0.0, -1.0, 0.0,
- 0.0, 0.0, -1.0
- );
- const Matrix3 Matrix3::RotateX270
- (
- 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0,
- 0.0, -1.0, 0.0
- );
- const Matrix3 Matrix3::RotateY90
- (
- 0.0, 0.0, 1.0,
- 0.0, 1.0, 0.0,
- -1.0, 0.0, 0.0
- );
- const Matrix3 Matrix3::RotateY180
- (
- -1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 0.0, 0.0, -1.0
- );
- const Matrix3 Matrix3::RotateY270
- (
- 0.0, 0.0, -1.0,
- 0.0, 1.0, 0.0,
- 1.0, 0.0, 0.0
- );
- const Matrix3 Matrix3::RotateZ90
- (
- 0.0, -1.0, 0.0,
- 1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0
- );
- const Matrix3 Matrix3::RotateZ180
- (
- -1.0, 0.0, 0.0,
- 0.0, -1.0, 0.0,
- 0.0, 0.0, 1.0
- );
- const Matrix3 Matrix3::RotateZ270
- (
- 0.0, 1.0, 0.0,
- -1.0, 0.0, 0.0,
- 0.0, 0.0, 1.0
- );
- /***********************************************************************************************
- * Matrix3::Matrix3 -- Convert a Matrix3D (fake 4x4) to a Matrix3 *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 06/02/1997 GH : Created. *
- *=============================================================================================*/
- Matrix3::Matrix3(const Matrix3D & m)
- {
- Row[0].Set(m[0][0],m[0][1],m[0][2]);
- Row[1].Set(m[1][0],m[1][1],m[1][2]);
- Row[2].Set(m[2][0],m[2][1],m[2][2]);
- }
- Matrix3::Matrix3(const Matrix4 & m)
- {
- Row[0].Set(m[0][0],m[0][1],m[0][2]);
- Row[1].Set(m[1][0],m[1][1],m[1][2]);
- Row[2].Set(m[2][0],m[2][1],m[2][2]);
- }
- void Matrix3::Set(const Matrix3D & m)
- {
- Row[0].Set(m[0][0],m[0][1],m[0][2]);
- Row[1].Set(m[1][0],m[1][1],m[1][2]);
- Row[2].Set(m[2][0],m[2][1],m[2][2]);
- }
- void Matrix3::Set(const Matrix4 & m)
- {
- Row[0].Set(m[0][0],m[0][1],m[0][2]);
- Row[1].Set(m[1][0],m[1][1],m[1][2]);
- Row[2].Set(m[2][0],m[2][1],m[2][2]);
- }
- void Matrix3::Set(const Quaternion & q)
- {
- Row[0][0] = (float)(1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]));
- Row[0][1] = (float)(2.0 * (q[0] * q[1] - q[2] * q[3]));
- Row[0][2] = (float)(2.0 * (q[2] * q[0] + q[1] * q[3]));
- Row[1][0] = (float)(2.0 * (q[0] * q[1] + q[2] * q[3]));
- Row[1][1] = (float)(1.0 - 2.0f * (q[2] * q[2] + q[0] * q[0]));
- Row[1][2] = (float)(2.0 * (q[1] * q[2] - q[0] * q[3]));
- Row[2][0] = (float)(2.0 * (q[2] * q[0] - q[1] * q[3]));
- Row[2][1] = (float)(2.0 * (q[1] * q[2] + q[0] * q[3]));
- Row[2][2] =(float)(1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]));
- }
- Matrix3 & Matrix3::operator = (const Matrix3D & m)
- {
- Row[0].Set(m[0][0],m[0][1],m[0][2]);
- Row[1].Set(m[1][0],m[1][1],m[1][2]);
- Row[2].Set(m[2][0],m[2][1],m[2][2]);
- return *this;
- }
- Matrix3 & Matrix3::operator = (const Matrix4 & m)
- {
- Row[0].Set(m[0][0],m[0][1],m[0][2]);
- Row[1].Set(m[1][0],m[1][1],m[1][2]);
- Row[2].Set(m[2][0],m[2][1],m[2][2]);
- return *this;
- }
- void Matrix3::Multiply(const Matrix3D & a, const Matrix3 & b,Matrix3 * res)
- {
- #define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
-
- (*res)[0][0] = ROWCOL(0,0);
- (*res)[0][1] = ROWCOL(0,1);
- (*res)[0][2] = ROWCOL(0,2);
- (*res)[1][0] = ROWCOL(1,0);
- (*res)[1][1] = ROWCOL(1,1);
- (*res)[1][2] = ROWCOL(1,2);
- (*res)[2][0] = ROWCOL(2,0);
- (*res)[2][1] = ROWCOL(2,1);
- (*res)[2][2] = ROWCOL(2,2);
- #undef ROWCOL
- }
- void Matrix3::Multiply(const Matrix3 & a, const Matrix3D & b,Matrix3 * res)
- {
- #define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
-
- (*res)[0][0] = ROWCOL(0,0);
- (*res)[0][1] = ROWCOL(0,1);
- (*res)[0][2] = ROWCOL(0,2);
- (*res)[1][0] = ROWCOL(1,0);
- (*res)[1][1] = ROWCOL(1,1);
- (*res)[1][2] = ROWCOL(1,2);
- (*res)[2][0] = ROWCOL(2,0);
- (*res)[2][1] = ROWCOL(2,1);
- (*res)[2][2] = ROWCOL(2,2);
- #undef ROWCOL
- }
- Matrix3 operator * (const Matrix3D & 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
- }
- Matrix3 operator * (const Matrix3 & a, const Matrix3D & 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
- }
- #if 0
- void Matrix3::Compute_Jacobi_Rotation(int i,int j,Matrix3 * r,Matrix3 * rinv)
- {
- }
- void Matrix3::Symmetric_Eigen_Solve(void)
- {
- Matrix3 eigen_vals = *this;
- Matrix3 eigen_vecs(1);
- Matrix3 jr,jrinv;
- while (!done) {
- eigen_vals.Compute_Jacobi_Rotation(i,j,&jr,&jrinv);
- eigen_vals = jr * (eigenvals) * jrinv;
- eigen_vecs = eigen_vecs * jr;
- }
- /*
- ** Done! Eigen values are the diagonals of
- ** the eigen_vals matrix and the eigen vectors
- ** are the columns of the eigen_vecs matrix
- */
- }
- #endif
- void Matrix3::Multiply(const Matrix3 & A,const Matrix3 & B,Matrix3 * set_res)
- {
- Matrix3 tmp;
- Matrix3 * Aptr;
- float tmp1,tmp2,tmp3;
- // Check for aliased parameters, copy the 'A' matrix into a temporary if the
- // result is going into 'A'. (in this case, this function is no better than
- // the overloaded C++ operator...)
- if (set_res == &A) {
- tmp = A;
- Aptr = &tmp;
- } else {
- Aptr = (Matrix3 *)&A;
- }
- tmp1 = B[0][0];
- tmp2 = B[1][0];
- tmp3 = B[2][0];
- (*set_res)[0][0] = (float)((*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3);
- (*set_res)[1][0] = (float)((*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3);
- (*set_res)[2][0] = (float)((*Aptr)[2][0]*tmp1 + (*Aptr)[2][1]*tmp2 + (*Aptr)[2][2]*tmp3);
- tmp1 = B[0][1];
- tmp2 = B[1][1];
- tmp3 = B[2][1];
- (*set_res)[0][1] = (float)((*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3);
- (*set_res)[1][1] = (float)((*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3);
- (*set_res)[2][1] = (float)((*Aptr)[2][0]*tmp1 + (*Aptr)[2][1]*tmp2 + (*Aptr)[2][2]*tmp3);
- tmp1 = B[0][2];
- tmp2 = B[1][2];
- tmp3 = B[2][2];
- (*set_res)[0][2] = (float)((*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3);
- (*set_res)[1][2] = (float)((*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3);
- (*set_res)[2][2] = (float)((*Aptr)[2][0]*tmp1 + (*Aptr)[2][1]*tmp2 + (*Aptr)[2][2]*tmp3);
- }
- int Matrix3::Is_Orthogonal(void) const
- {
- Vector3 x(Row[0].X,Row[0].Y,Row[0].Z);
- Vector3 y(Row[1].X,Row[1].Y,Row[1].Z);
- Vector3 z(Row[2].X,Row[2].Y,Row[2].Z);
-
- if (Vector3::Dot_Product(x,y) > WWMATH_EPSILON) return 0;
- if (Vector3::Dot_Product(y,z) > WWMATH_EPSILON) return 0;
- if (Vector3::Dot_Product(z,x) > WWMATH_EPSILON) return 0;
- if (WWMath::Fabs(x.Length() - 1.0f) > WWMATH_EPSILON) return 0;
- if (WWMath::Fabs(y.Length() - 1.0f) > WWMATH_EPSILON) return 0;
- if (WWMath::Fabs(z.Length() - 1.0f) > WWMATH_EPSILON) return 0;
- return 1;
- }
- void Matrix3::Re_Orthogonalize(void)
- {
- Vector3 x(Row[0][0],Row[0][1],Row[0][2]);
- Vector3 y(Row[1][0],Row[1][1],Row[1][2]);
- Vector3 z;
- Vector3::Cross_Product(x,y,&z);
- Vector3::Cross_Product(z,x,&y);
- float len = x.Length();
- if (len < WWMATH_EPSILON) {
- Make_Identity();
- return;
- } else {
- x /= len;
- }
- len = y.Length();
- if (len < WWMATH_EPSILON) {
- Make_Identity();
- return;
- } else {
- y /= len;
- }
- len = z.Length();
- if (len < WWMATH_EPSILON) {
- Make_Identity();
- return;
- } else {
- z /= len;
- }
- Row[0][0] = x.X;
- Row[0][1] = x.Y;
- Row[0][2] = x.Z;
- Row[1][0] = y.X;
- Row[1][1] = y.Y;
- Row[1][2] = y.Z;
-
- Row[2][0] = z.X;
- Row[2][1] = z.Y;
- Row[2][2] = z.Z;
- }
- void Matrix3::Rotate_AABox_Extent(const Vector3 & extent,Vector3 * set_extent)
- {
- // push each extent out to the projections of the original extents
- for (int i=0; i<3; i++) {
- // start the center out at the translation portion of the matrix
- // and the extent at zero
- (*set_extent)[i] = 0.0f;
- for (int j=0; j<3; j++) {
- (*set_extent)[i] += WWMath::Fabs(Row[i][j] * extent[j]);
- }
- }
- }
|