mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 23:51:41 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
46
Code/Tools/pluglib/BITTYPE.H
Normal file
46
Code/Tools/pluglib/BITTYPE.H
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/*****************************************************************
|
||||
*
|
||||
* Project: 3DTEST1 (3d Test Program)
|
||||
*
|
||||
* File: bittype.h
|
||||
*
|
||||
* Start Date: Dec 18, 1996
|
||||
*
|
||||
* Programmer: Greg Hjelstrom
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#ifndef BITTYPE_H
|
||||
#define BITTYPE_H
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned long uint32;
|
||||
|
||||
typedef signed char sint8;
|
||||
typedef signed short sint16;
|
||||
typedef signed long sint32;
|
||||
|
||||
typedef float float32;
|
||||
typedef double float64;
|
||||
|
||||
|
||||
#endif //BITTYPE_H
|
||||
334
Code/Tools/pluglib/EULER.CPP
Normal file
334
Code/Tools/pluglib/EULER.CPP
Normal file
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
** 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/EULER.CPP 5 12/02/97 10:14p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G 3D Engine *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/max2w3d/EULER.CPP $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 11/13/97 7:16p $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "euler.h"
|
||||
#include <float.h>
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
There are 24 possible conventions for Euler angles. They can
|
||||
be designated by:
|
||||
|
||||
EulerAxis = Axis used initially
|
||||
EulerParity = parity of axis permutation (even = x,y,z)
|
||||
EulerRepeat = is last axis a repeat of the initial axis?
|
||||
EulerFrame = frame from which axes are taken (rotating or static)
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#define EULER_FRAME_STATIC 0x00000000
|
||||
#define EULER_FRAME_ROTATING 0x00000001
|
||||
#define EULER_FRAME(order) ((unsigned)(order) & 1)
|
||||
|
||||
#define EULER_REPEAT_NO 0x00000000
|
||||
#define EULER_REPEAT_YES 0x00000001
|
||||
#define EULER_REPEAT(order) (((unsigned)(order) >> 1) & 1)
|
||||
|
||||
#define EULER_PARITY_EVEN 0x00000000
|
||||
#define EULER_PARITY_ODD 0x00000001
|
||||
#define EULER_PARITY(order) (((unsigned)(order) >> 2) & 1)
|
||||
|
||||
#define EULER_BUILD_ORDER(i,p,r,f) (((((((i) << 1) + (p)) << 1) + (r)) << 1) + (f))
|
||||
|
||||
|
||||
/* static axes */
|
||||
int EulerOrderXYZs = EULER_BUILD_ORDER(0, EULER_PARITY_EVEN, EULER_REPEAT_NO, EULER_FRAME_STATIC);
|
||||
int EulerOrderXYXs = EULER_BUILD_ORDER(0, EULER_PARITY_EVEN, EULER_REPEAT_YES, EULER_FRAME_STATIC);
|
||||
int EulerOrderXZYs = EULER_BUILD_ORDER(0, EULER_PARITY_ODD, EULER_REPEAT_NO, EULER_FRAME_STATIC);
|
||||
int EulerOrderXZXs = EULER_BUILD_ORDER(0, EULER_PARITY_ODD, EULER_REPEAT_YES, EULER_FRAME_STATIC);
|
||||
int EulerOrderYZXs = EULER_BUILD_ORDER(1, EULER_PARITY_EVEN, EULER_REPEAT_NO, EULER_FRAME_STATIC);
|
||||
int EulerOrderYZYs = EULER_BUILD_ORDER(1, EULER_PARITY_EVEN, EULER_REPEAT_YES, EULER_FRAME_STATIC);
|
||||
int EulerOrderYXZs = EULER_BUILD_ORDER(1, EULER_PARITY_ODD, EULER_REPEAT_NO, EULER_FRAME_STATIC);
|
||||
int EulerOrderYXYs = EULER_BUILD_ORDER(1, EULER_PARITY_ODD, EULER_REPEAT_YES, EULER_FRAME_STATIC);
|
||||
int EulerOrderZXYs = EULER_BUILD_ORDER(2, EULER_PARITY_EVEN, EULER_REPEAT_NO, EULER_FRAME_STATIC);
|
||||
int EulerOrderZXZs = EULER_BUILD_ORDER(2, EULER_PARITY_EVEN, EULER_REPEAT_YES, EULER_FRAME_STATIC);
|
||||
int EulerOrderZYXs = EULER_BUILD_ORDER(2, EULER_PARITY_ODD, EULER_REPEAT_NO, EULER_FRAME_STATIC);
|
||||
int EulerOrderZYZs = EULER_BUILD_ORDER(2, EULER_PARITY_ODD, EULER_REPEAT_YES, EULER_FRAME_STATIC);
|
||||
|
||||
/* rotating axes */
|
||||
int EulerOrderZYXr = EULER_BUILD_ORDER(0, EULER_PARITY_EVEN, EULER_REPEAT_NO, EULER_FRAME_ROTATING);
|
||||
int EulerOrderXYXr = EULER_BUILD_ORDER(0, EULER_PARITY_EVEN, EULER_REPEAT_YES, EULER_FRAME_ROTATING);
|
||||
int EulerOrderYZXr = EULER_BUILD_ORDER(0, EULER_PARITY_ODD, EULER_REPEAT_NO, EULER_FRAME_ROTATING);
|
||||
int EulerOrderXZXr = EULER_BUILD_ORDER(0, EULER_PARITY_ODD, EULER_REPEAT_YES, EULER_FRAME_ROTATING);
|
||||
int EulerOrderXZYr = EULER_BUILD_ORDER(1, EULER_PARITY_EVEN, EULER_REPEAT_NO, EULER_FRAME_ROTATING);
|
||||
int EulerOrderYZYr = EULER_BUILD_ORDER(1, EULER_PARITY_EVEN, EULER_REPEAT_YES, EULER_FRAME_ROTATING);
|
||||
int EulerOrderZXYr = EULER_BUILD_ORDER(1, EULER_PARITY_ODD, EULER_REPEAT_NO, EULER_FRAME_ROTATING);
|
||||
int EulerOrderYXYr = EULER_BUILD_ORDER(1, EULER_PARITY_ODD, EULER_REPEAT_YES, EULER_FRAME_ROTATING);
|
||||
int EulerOrderYXZr = EULER_BUILD_ORDER(2, EULER_PARITY_EVEN, EULER_REPEAT_NO, EULER_FRAME_ROTATING);
|
||||
int EulerOrderZXZr = EULER_BUILD_ORDER(2, EULER_PARITY_EVEN, EULER_REPEAT_YES, EULER_FRAME_ROTATING);
|
||||
int EulerOrderXYZr = EULER_BUILD_ORDER(2, EULER_PARITY_ODD, EULER_REPEAT_NO, EULER_FRAME_ROTATING);
|
||||
int EulerOrderZYZr = EULER_BUILD_ORDER(2, EULER_PARITY_ODD, EULER_REPEAT_YES, EULER_FRAME_ROTATING);
|
||||
|
||||
/* local functions */
|
||||
static void _euler_unpack_order(int order,int &i,int &j,int &k,int &h,int &n,int &s,int &f);
|
||||
static int _euler_axis_i(int order);
|
||||
static int _euler_axis_j(int order);
|
||||
static int _euler_axis_k(int order);
|
||||
static int _euler_axis_h(int order);
|
||||
static void _mat_to_array(const Matrix3 & tm, float M[3][4]);
|
||||
static void _array_to_mat(float M[3][4], Matrix3 & tm);
|
||||
|
||||
|
||||
|
||||
EulerAnglesClass::EulerAnglesClass(const Matrix3 & M,int order)
|
||||
{
|
||||
this->From_Matrix(M,order);
|
||||
}
|
||||
|
||||
double EulerAnglesClass::Get_Angle(int i)
|
||||
{
|
||||
return Angle[i];
|
||||
}
|
||||
|
||||
void EulerAnglesClass::From_Matrix(const Matrix3 & tm, int order)
|
||||
{
|
||||
float M[3][4];
|
||||
_mat_to_array(tm,M);
|
||||
|
||||
int i,j,k,h,n,s,f;
|
||||
|
||||
Order = order;
|
||||
_euler_unpack_order(order,i,j,k,h,n,s,f);
|
||||
|
||||
if (s == EULER_REPEAT_YES) {
|
||||
double sy = sqrt(M[i][j]*M[i][j] + M[i][k]*M[i][k]);
|
||||
|
||||
if (sy > 16*FLT_EPSILON) {
|
||||
|
||||
Angle[0] = atan2(M[i][j],M[i][k]);
|
||||
Angle[1] = atan2(sy,M[i][i]);
|
||||
Angle[2] = atan2(M[j][i],-M[k][i]);
|
||||
|
||||
} else {
|
||||
|
||||
Angle[0] = atan2(-M[j][k],M[j][j]);
|
||||
Angle[1] = atan2(sy,M[i][i]);
|
||||
Angle[2] = 0.0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]);
|
||||
|
||||
if (cy > 16*FLT_EPSILON) {
|
||||
|
||||
Angle[0] = atan2(M[k][j],M[k][k]);
|
||||
Angle[1] = atan2(-M[k][i],cy);
|
||||
Angle[2] = atan2(M[j][i],M[i][i]);
|
||||
|
||||
} else {
|
||||
|
||||
Angle[0] = atan2(-M[j][k],M[j][j]);
|
||||
Angle[1] = atan2(-M[k][i],cy);
|
||||
Angle[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (n==EULER_PARITY_ODD) { Angle[0] = -Angle[0]; Angle[1] = -Angle[1]; Angle[2] = -Angle[2]; }
|
||||
if (f==EULER_FRAME_ROTATING) { double t = Angle[0]; Angle[0] = Angle[2]; Angle[2] = t; }
|
||||
|
||||
// Trying to "clean" up the eulers, special cased for XYZr
|
||||
if (order == EulerOrderXYZr) {
|
||||
|
||||
double x2 = PI + Angle[0];
|
||||
double y2 = PI - Angle[1];
|
||||
double z2 = PI + Angle[2];
|
||||
|
||||
if (x2 > PI) {
|
||||
x2 = x2 - 2*PI;
|
||||
}
|
||||
|
||||
if (y2 > PI) {
|
||||
y2 = y2 - 2*PI;
|
||||
}
|
||||
|
||||
if (z2 > PI) {
|
||||
z2 = z2 - 2*PI;
|
||||
}
|
||||
|
||||
double mag0 = Angle[0]*Angle[0] + Angle[1]*Angle[1] + Angle[2]*Angle[2];
|
||||
double mag1 = x2*x2 + y2*y2 + z2*z2;
|
||||
|
||||
if (mag1 < mag0) {
|
||||
Angle[0] = x2;
|
||||
Angle[1] = y2;
|
||||
Angle[2] = z2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EulerAnglesClass::To_Matrix(Matrix3 & tm)
|
||||
{
|
||||
float M[3][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 }
|
||||
};
|
||||
|
||||
double a0,a1,a2;
|
||||
double ti,tj,th,ci,cj,ch,si,sj,sh,cc,cs,sc,ss;
|
||||
int i,j,k,h,n,s,f;
|
||||
|
||||
a0 = Angle[0];
|
||||
a1 = Angle[1];
|
||||
a2 = Angle[2];
|
||||
|
||||
_euler_unpack_order(Order,i,j,k,h,n,s,f);
|
||||
if (f == EULER_FRAME_ROTATING) {
|
||||
double t = a0; a0 = a2; a2 = t;
|
||||
}
|
||||
|
||||
if (n == EULER_PARITY_ODD) {
|
||||
a0 = -a0; a1 = -a1; a2 = -a2;
|
||||
}
|
||||
|
||||
ti = a0; tj = a1; th = a2;
|
||||
ci = cos(ti); cj = cos(tj); ch = cos(th);
|
||||
si = sin(ti); sj = sin(tj); sh = sin(th);
|
||||
|
||||
cc = ci*ch;
|
||||
cs = ci*sh;
|
||||
sc = si*ch;
|
||||
ss = si*sh;
|
||||
|
||||
if (s == EULER_REPEAT_YES) {
|
||||
|
||||
M[i][i] = (float)(cj); M[i][j] = (float)(sj*si); M[i][k] = (float)(sj*ci);
|
||||
M[j][i] = (float)(sj*sh); M[j][j] = (float)(-cj*ss+cc); M[j][k] = (float)(-cj*cs-sc);
|
||||
M[k][i] = (float)(-sj*ch); M[k][j] = (float)(cj*sc+cs); M[k][k] = (float)(cj*cc-ss);
|
||||
|
||||
} else {
|
||||
|
||||
M[i][i] = (float)(cj*ch); M[i][j] = (float)(sj*sc-cs); M[i][k] = (float)(sj*cc+ss);
|
||||
M[j][i] = (float)(cj*sh); M[j][j] = (float)(sj*ss+cc); M[j][k] = (float)(sj*cs-sc);
|
||||
M[k][i] = (float)(-sj); M[k][j] = (float)(cj*si); M[k][k] = (float)(cj*ci);
|
||||
|
||||
}
|
||||
_array_to_mat(M,tm);
|
||||
}
|
||||
|
||||
|
||||
static int _euler_safe[] = { 0,1,2,0 };
|
||||
static int _euler_next[] = { 1,2,0,1 };
|
||||
|
||||
int _euler_axis_i(int order)
|
||||
{
|
||||
return _euler_safe[ (order>>3) & 3 ];
|
||||
}
|
||||
|
||||
int _euler_axis_j(int order)
|
||||
{
|
||||
int index = _euler_axis_i(order);
|
||||
if (EULER_PARITY(order) == 1) {
|
||||
index++;
|
||||
}
|
||||
|
||||
return _euler_next[ index ];
|
||||
}
|
||||
|
||||
int _euler_axis_k(int order)
|
||||
{
|
||||
int index = _euler_axis_i(order);
|
||||
if (EULER_PARITY(order) != 1) {
|
||||
index++;
|
||||
}
|
||||
|
||||
return _euler_next[ index ];
|
||||
}
|
||||
|
||||
int _euler_axis_h(int order)
|
||||
{
|
||||
if (EULER_REPEAT(order) == 1) {
|
||||
return _euler_axis_k(order);
|
||||
} else {
|
||||
return _euler_axis_i(order);
|
||||
}
|
||||
}
|
||||
|
||||
void _euler_unpack_order(int order,int &i,int &j,int &k,int &h,int &n,int &s,int &f)
|
||||
{
|
||||
|
||||
f = order & 1;
|
||||
order >>= 1;
|
||||
|
||||
s = order & 1;
|
||||
order >>= 1;
|
||||
|
||||
n = order & 1;
|
||||
order >>= 1;
|
||||
|
||||
i = _euler_safe[order & 3];
|
||||
j = _euler_next[i+n];
|
||||
k = _euler_next[i+1-n];
|
||||
h = (s ? k : i);
|
||||
}
|
||||
|
||||
void _mat_to_array(const Matrix3 & tm, float M[3][4])
|
||||
{
|
||||
// Translation vector
|
||||
Point3 trans = tm.GetRow(3);
|
||||
M[0][3] = trans.x;
|
||||
M[1][3] = trans.y;
|
||||
M[2][3] = trans.z;
|
||||
|
||||
// Rotation matrix
|
||||
for (int k=0; k<3; k++) {
|
||||
Point3 v = tm.GetRow(k);
|
||||
M[0][k] = v.x;
|
||||
M[1][k] = v.y;
|
||||
M[2][k] = v.z;
|
||||
}
|
||||
}
|
||||
|
||||
void _array_to_mat(float M[3][4], Matrix3 & tm)
|
||||
{
|
||||
// translation
|
||||
Point3 row(M[3][0],M[3][1],M[3][2]);
|
||||
tm.SetRow(3, row);
|
||||
|
||||
// rotation
|
||||
for (int k=0; k<3; k++) {
|
||||
row = Point3(M[0][k],M[1][k],M[2][k]);
|
||||
tm.SetRow(k, row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
119
Code/Tools/pluglib/EULER.H
Normal file
119
Code/Tools/pluglib/EULER.H
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
** 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/EULER.H 3 10/28/97 6:08p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G 3D Engine *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/max2w3d/EULER.H $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 10/14/97 3:08p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#ifndef EULER_H
|
||||
#define EULER_H
|
||||
|
||||
#include <Max.h>
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
Euler Order Types
|
||||
|
||||
When creating an EulerAngles object, use one of the below
|
||||
constants to describe the axis convention.
|
||||
|
||||
XYZ - order of the axes
|
||||
s/r - whether the rotations are applied to the static or
|
||||
rotating frame.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
/* static axes */
|
||||
extern int EulerOrderXYZs;
|
||||
extern int EulerOrderXYXs;
|
||||
extern int EulerOrderXZYs;
|
||||
extern int EulerOrderXZXs;
|
||||
extern int EulerOrderYZXs;
|
||||
extern int EulerOrderYZYs;
|
||||
extern int EulerOrderYXZs;
|
||||
extern int EulerOrderYXYs;
|
||||
extern int EulerOrderZXYs;
|
||||
extern int EulerOrderZXZs;
|
||||
extern int EulerOrderZYXs;
|
||||
extern int EulerOrderZYZs;
|
||||
|
||||
/* rotating axes */
|
||||
extern int EulerOrderXYZr;
|
||||
extern int EulerOrderXYXr;
|
||||
extern int EulerOrderXZYr;
|
||||
extern int EulerOrderXZXr;
|
||||
extern int EulerOrderYZXr;
|
||||
extern int EulerOrderYZYr;
|
||||
extern int EulerOrderYXZr;
|
||||
extern int EulerOrderYXYr;
|
||||
extern int EulerOrderZXYr;
|
||||
extern int EulerOrderZXZr;
|
||||
extern int EulerOrderZYXr;
|
||||
extern int EulerOrderZYZr;
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
EulerAnglesClass
|
||||
|
||||
The purpose for this class is mainly for conversion. You can
|
||||
choose a convention for the order of your rotations and then
|
||||
convert matrices into a set of euler angles.
|
||||
|
||||
This implementation is based on the code in Graphics Gems IV
|
||||
by Ken Shoemake. The original article is on page 222.
|
||||
|
||||
*********************************************************************/
|
||||
class EulerAnglesClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
EulerAnglesClass(void) : Order(0) { Angle[0] = 0.0; Angle[1] = 0.0; Angle[2] = 0.0; };
|
||||
EulerAnglesClass(const Matrix3 & from,int order);
|
||||
void From_Matrix(const Matrix3 & from,int order);
|
||||
void To_Matrix(Matrix3 & M);
|
||||
|
||||
double Get_Angle(int i);
|
||||
|
||||
private:
|
||||
|
||||
double Angle[3];
|
||||
int Order;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif /*EULER_H*/
|
||||
125
Code/Tools/pluglib/PROGRESS.H
Normal file
125
Code/Tools/pluglib/PROGRESS.H
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
** 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/PROGRESS.H 5 10/28/97 6:08p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G 3D engine *
|
||||
* *
|
||||
* File Name : PROGRESS.H *
|
||||
* *
|
||||
* Programmer : James McNeil *
|
||||
* *
|
||||
* Start Date : 06/19/97 *
|
||||
* *
|
||||
* Last Update : June 19, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef PROGRESS_H
|
||||
#define PROGRESS_H
|
||||
|
||||
#include "always.h"
|
||||
|
||||
class Progress_Meter_Class
|
||||
{
|
||||
public:
|
||||
|
||||
Progress_Meter_Class
|
||||
(
|
||||
Interface * gi,
|
||||
float base,
|
||||
float range
|
||||
):
|
||||
Max ( gi ),
|
||||
Base ( base ),
|
||||
Range ( range ),
|
||||
Amount_Done ( 0.0f ),
|
||||
Increment ( 0.0f ),
|
||||
Accum( 0.0f ),
|
||||
Cancel_Requested ( FALSE )
|
||||
{
|
||||
}
|
||||
|
||||
Progress_Meter_Class ( Progress_Meter_Class & other, float sub_amount ):
|
||||
Max ( other.Max ),
|
||||
Base ( other.Base + other.Amount_Done * other.Range ),
|
||||
Range ( other.Range * sub_amount ),
|
||||
Amount_Done ( 0.0f ),
|
||||
Increment ( 0.0f ),
|
||||
Accum ( other.Accum ),
|
||||
Cancel_Requested ( other.Cancel_Requested )
|
||||
{
|
||||
}
|
||||
|
||||
void Finish_In_Steps ( int number_of_steps )
|
||||
{
|
||||
Increment = (1.0f - Amount_Done) / number_of_steps;
|
||||
}
|
||||
|
||||
void Add_Increment ()
|
||||
{
|
||||
Set_Amount_Done ( Amount_Done + Increment );
|
||||
}
|
||||
|
||||
void Set_Amount_Done ( float percentage )
|
||||
{
|
||||
Accum += percentage;
|
||||
Amount_Done = percentage;
|
||||
if (Accum > 0.01f) {
|
||||
Max->ProgressUpdate ( (int) (Amount_Done * Range + Base) );
|
||||
Accum = 0.0f;
|
||||
}
|
||||
|
||||
if (Max->GetCancel())
|
||||
{
|
||||
int choice = MessageBox
|
||||
(
|
||||
Max->GetMAXHWnd(),
|
||||
_T("Do you really want to cancel the export?"),
|
||||
_T("Cancel Export?"), MB_ICONQUESTION | MB_YESNO
|
||||
);
|
||||
|
||||
if ( choice == IDYES )
|
||||
Cancel_Requested = TRUE;
|
||||
else
|
||||
Max->SetCancel ( FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
BOOL Cancelled () { return Cancel_Requested; }
|
||||
|
||||
float Increment;
|
||||
|
||||
private:
|
||||
|
||||
Interface * Max;
|
||||
|
||||
float Base;
|
||||
float Range;
|
||||
float Amount_Done;
|
||||
float Accum;
|
||||
|
||||
BOOL Cancel_Requested;
|
||||
};
|
||||
|
||||
#endif /* PROGRESS_H */
|
||||
355
Code/Tools/pluglib/Vector.CPP
Normal file
355
Code/Tools/pluglib/Vector.CPP
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/pluglib/Vector.CPP $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 3/29/98 10:42a $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* BooleanVectorClass::BooleanVectorClass -- Copy constructor for boolean array. *
|
||||
* BooleanVectorClass::BooleanVectorClass -- Explicit data buffer constructor. *
|
||||
* BooleanVectorClass::Clear -- Resets boolean vector to empty state. *
|
||||
* BooleanVectorClass::Fixup -- Updates the boolean vector to a known state. *
|
||||
* BooleanVectorClass::Reset -- Clear all boolean values in array. *
|
||||
* BooleanVectorClass::Resize -- Resizes a boolean vector object. *
|
||||
* BooleanVectorClass::Set -- Forces all boolean elements to true. *
|
||||
* BooleanVectorClass::operator = -- Assignment operator. *
|
||||
* BooleanVectorClass::operator == -- Comparison operator for boolean vector. *
|
||||
* VectorClass<T>::Clear -- Frees and clears the vector. *
|
||||
* VectorClass<T>::ID -- Finds object ID based on value. *
|
||||
* VectorClass<T>::ID -- Pointer based conversion to index number. *
|
||||
* VectorClass<T>::Resize -- Changes the size of the vector. *
|
||||
* VectorClass<T>::VectorClass -- Constructor for vector class. *
|
||||
* VectorClass<T>::VectorClass -- Copy constructor for vector object. *
|
||||
* VectorClass<T>::operator = -- The assignment operator. *
|
||||
* VectorClass<T>::operator == -- Equality operator for vector objects. *
|
||||
* VectorClass<T>::~VectorClass -- Default destructor for vector class. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "always.h"
|
||||
#include "vector.h"
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** The following template function can be located here ONLY if all the instantiations are
|
||||
** declared in a header file this module includes. By placing the template functions here,
|
||||
** it speeds up compiler operation and reduces object module size.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::BooleanVectorClass -- Explicit data buffer constructor. *
|
||||
* *
|
||||
* This is the constructor for a boolean array. This constructor takes the memory pointer *
|
||||
* provided as assigns that as the array data pointer. *
|
||||
* *
|
||||
* INPUT: size -- The size of the array (in bits). *
|
||||
* *
|
||||
* array -- Pointer to the memory that the array is to use. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: You must make sure that the memory specified is large enough to contain the *
|
||||
* bits specified. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
BooleanVectorClass::BooleanVectorClass(unsigned size, unsigned char * array) :
|
||||
BitCount(size),
|
||||
Copy(false),
|
||||
LastIndex(-1),
|
||||
BitArray(0, 0)
|
||||
{
|
||||
BitArray.Resize(((size + (8-1)) / 8), array);
|
||||
// LastIndex = -1;
|
||||
// BitCount = size;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::BooleanVectorClass -- Copy constructor of boolean array. *
|
||||
* *
|
||||
* This is the copy constructor for a boolean array. It is used to make a duplicate of the *
|
||||
* boolean array. *
|
||||
* *
|
||||
* INPUT: vector -- Reference to the vector to be duplicated. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
BooleanVectorClass::BooleanVectorClass(BooleanVectorClass const & vector)
|
||||
{
|
||||
LastIndex = -1;
|
||||
*this = vector;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::operator = -- Assignment operator. *
|
||||
* *
|
||||
* This routine will make a copy of the specified boolean vector array. The vector is *
|
||||
* copied into an already constructed existing vector. The values from the existing vector *
|
||||
* are destroyed by this copy. *
|
||||
* *
|
||||
* INPUT: vector -- Reference to the vector to make a copy of. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
BooleanVectorClass & BooleanVectorClass::operator =(BooleanVectorClass const & vector)
|
||||
{
|
||||
Fixup();
|
||||
Copy = vector.Copy;
|
||||
LastIndex = vector.LastIndex;
|
||||
BitArray = vector.BitArray;
|
||||
BitCount = vector.BitCount;
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::operator == -- Comparison operator for boolean vector. *
|
||||
* *
|
||||
* This is the comparison operator for a boolean vector class. Boolean vectors are equal *
|
||||
* if the bit count and bit values are identical. *
|
||||
* *
|
||||
* INPUT: vector -- Reference to the vector to compare to. *
|
||||
* *
|
||||
* OUTPUT: Are the boolean vectors identical? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
bool BooleanVectorClass::operator == (const BooleanVectorClass & vector)
|
||||
{
|
||||
Fixup(LastIndex);
|
||||
return(BitCount == vector.BitCount && BitArray == vector.BitArray);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::Resize -- Resizes a boolean vector object. *
|
||||
* *
|
||||
* This routine will resize the boolean vector object. An index value used with a boolean *
|
||||
* vector must be less than the value specified in as the new size. *
|
||||
* *
|
||||
* INPUT: size -- The new maximum size of this boolean vector. *
|
||||
* *
|
||||
* OUTPUT: Was the boolean vector sized successfully? *
|
||||
* *
|
||||
* WARNINGS: The boolean array might be reallocated or even deleted by this routine. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int BooleanVectorClass::Resize(unsigned size)
|
||||
{
|
||||
Fixup();
|
||||
|
||||
if (size > 0) {
|
||||
|
||||
/*
|
||||
** Record the previous bit count of the boolean vector. This is used
|
||||
** to determine if the array has grown in size and thus clearing is
|
||||
** necessary.
|
||||
*/
|
||||
unsigned oldsize = BitCount;
|
||||
|
||||
/*
|
||||
** Actually resize the bit array. Since this is a bit packed array,
|
||||
** there are 8 elements per byte (rounded up).
|
||||
*/
|
||||
int success = BitArray.Resize(((size + (8-1)) / 8));
|
||||
|
||||
/*
|
||||
** Since there is no default constructor for bit packed integers, a manual
|
||||
** clearing of the bits is required.
|
||||
*/
|
||||
BitCount = size;
|
||||
if (success && oldsize < size) {
|
||||
for (unsigned index = oldsize; index < size; index++) {
|
||||
(*this)[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return(success);
|
||||
}
|
||||
|
||||
/*
|
||||
** Resizing to zero is the same as clearing and deallocating the array.
|
||||
** This is always successful.
|
||||
*/
|
||||
Clear();
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::Clear -- Resets boolean vector to empty state. *
|
||||
* *
|
||||
* This routine will clear out the boolean array. This will free any allocated memory and *
|
||||
* result in the boolean vector being unusable until the Resize function is subsequently *
|
||||
* called. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: The boolean vector cannot be used until it is resized to a non null condition. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void BooleanVectorClass::Clear(void)
|
||||
{
|
||||
Fixup();
|
||||
BitCount = 0;
|
||||
BitArray.Clear();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::Reset -- Clear all boolean values in array. *
|
||||
* *
|
||||
* This is the preferred (and quick) method to clear the boolean array to a false condition.*
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void BooleanVectorClass::Reset(void)
|
||||
{
|
||||
LastIndex = -1;
|
||||
if (BitArray.Length() > 0) {
|
||||
memset(&BitArray[0], '\0', BitArray.Length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::Set -- Forces all boolean elements to true. *
|
||||
* *
|
||||
* This is the preferred (and fast) way to set all boolean elements to true. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void BooleanVectorClass::Set(void)
|
||||
{
|
||||
LastIndex = -1;
|
||||
if (BitArray.Length() > 0) {
|
||||
memset(&BitArray[0], '\xFF', BitArray.Length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* BooleanVectorClass::Fixup -- Updates the boolean vector to a known state. *
|
||||
* *
|
||||
* Use this routine to set the boolean value copy to match the appropriate bit in the *
|
||||
* boolean array. The boolean array will be updated with any changes from the last time *
|
||||
* a value was fetched from the boolean vector. By using this update method, the boolean *
|
||||
* array can be treated as a normal array even though the elements are composed of *
|
||||
* otherwise inaccessible bits. *
|
||||
* *
|
||||
* INPUT: index -- The index to set the new copy value to. If the index is -1, then the *
|
||||
* previous value will be updated into the vector array, but no new value *
|
||||
* will be fetched from it. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: Always call this routine with "-1" if any direct manipulation of the bit *
|
||||
* array is to occur. This ensures that the bit array is accurate. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/18/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void BooleanVectorClass::Fixup(int index) const
|
||||
{
|
||||
/*
|
||||
** If the requested index value is illegal, then force the index
|
||||
** to be -1. This is the default non-index value.
|
||||
*/
|
||||
if ((unsigned)index >= (unsigned)BitCount) {
|
||||
index = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the new index is different than the previous index, there might
|
||||
** be some fixing up required.
|
||||
*/
|
||||
if (index != LastIndex) {
|
||||
|
||||
/*
|
||||
** If the previously fetched boolean value was changed, then update
|
||||
** the boolean array accordingly.
|
||||
*/
|
||||
if (LastIndex != -1) {
|
||||
assert(unsigned(LastIndex) < unsigned(BitCount));
|
||||
Set_Bit((void*)&BitArray[0], LastIndex, Copy);
|
||||
}
|
||||
|
||||
/*
|
||||
** If this new current index is valid, then fill in the reference boolean
|
||||
** value with the appropriate data from the bit array.
|
||||
*/
|
||||
if (index != -1) {
|
||||
assert(unsigned(index) < unsigned(BitCount));
|
||||
((unsigned char &)Copy) = (unsigned char)Get_Bit((void*)&BitArray[0], index);
|
||||
// ((unsigned char&)Copy) = Get_Bit((void*)&BitArray[0], index);
|
||||
}
|
||||
|
||||
((BooleanVectorClass *)this)->LastIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
999
Code/Tools/pluglib/Vector.H
Normal file
999
Code/Tools/pluglib/Vector.H
Normal file
@@ -0,0 +1,999 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Library/Vector.H $*
|
||||
* *
|
||||
* $Author:: Byon_g $*
|
||||
* *
|
||||
* $Modtime:: 3/12/98 2:09p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* VectorClass<T>::VectorClass -- Constructor for vector class. *
|
||||
* VectorClass<T>::~VectorClass -- Default destructor for vector class. *
|
||||
* VectorClass<T>::VectorClass -- Copy constructor for vector object. *
|
||||
* VectorClass<T>::operator = -- The assignment operator. *
|
||||
* VectorClass<T>::operator == -- Equality operator for vector objects. *
|
||||
* VectorClass<T>::Clear -- Frees and clears the vector. *
|
||||
* VectorClass<T>::Resize -- Changes the size of the vector. *
|
||||
* DynamicVectorClass<T>::DynamicVectorClass -- Constructor for dynamic vector. *
|
||||
* DynamicVectorClass<T>::Resize -- Changes the size of a dynamic vector. *
|
||||
* DynamicVectorClass<T>::Add -- Add an element to the vector. *
|
||||
* DynamicVectorClass<T>::Delete -- Remove the specified object from the vector. *
|
||||
* DynamicVectorClass<T>::Delete -- Deletes the specified index from the vector. *
|
||||
* VectorClass<T>::ID -- Pointer based conversion to index number. *
|
||||
* VectorClass<T>::ID -- Finds object ID based on value. *
|
||||
* DynamicVectorClass<T>::ID -- Find matching value in the dynamic vector. *
|
||||
* DynamicVectorClass<T>::Uninitialized_Add -- Add an empty place to the vector. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef VECTOR_H
|
||||
#define VECTOR_H
|
||||
|
||||
#include "noinit.h"
|
||||
#include <assert.h>
|
||||
#include <new.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
** This is a general purpose vector class. A vector is defined by this
|
||||
** class, as an array of arbitrary objects where the array can be dynamically
|
||||
** sized. Because is deals with arbitrary object types, it can handle everything.
|
||||
** As a result of this, it is not terribly efficient for integral objects (such
|
||||
** as char or int). It will function correctly, but the copy constructor and
|
||||
** equality operator could be highly optimized if the integral type were known.
|
||||
** This efficiency can be implemented by deriving an integral vector template
|
||||
** from this one in order to supply more efficient routines.
|
||||
*/
|
||||
|
||||
// Why, oh why does Visual C need this!!! It's bugged. <sigh>
|
||||
#pragma warning(disable : 4505)
|
||||
|
||||
|
||||
template<class T>
|
||||
class VectorClass
|
||||
{
|
||||
public:
|
||||
VectorClass(NoInitClass const &) {};
|
||||
VectorClass(int size=0, T const * array=0);
|
||||
VectorClass(VectorClass<T> const &); // Copy constructor.
|
||||
virtual ~VectorClass(void);
|
||||
|
||||
T & operator[](int index) {assert(unsigned(index) < unsigned(VectorMax));return(Vector[index]);};
|
||||
T const & operator[](int index) const {assert(unsigned(index) < unsigned(VectorMax));return(Vector[index]);};
|
||||
VectorClass<T> & operator = (VectorClass<T> const &); // Assignment operator.
|
||||
|
||||
virtual bool operator == (VectorClass<T> const &) const; // Equality operator.
|
||||
|
||||
virtual bool Resize(int newsize, T const * array=0);
|
||||
virtual void Clear(void);
|
||||
int Length(void) const {return VectorMax;};
|
||||
virtual int ID(T const * ptr); // Pointer based identification.
|
||||
virtual int ID(T const & ptr); // Value based identification.
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
** This is a pointer to the allocated vector array of elements.
|
||||
*/
|
||||
T * Vector;
|
||||
|
||||
/*
|
||||
** This is the maximum number of elements allowed in this vector.
|
||||
*/
|
||||
int VectorMax;
|
||||
|
||||
/*
|
||||
** This indicates if the vector is in a valid (even if empty) state.
|
||||
*/
|
||||
bool IsValid;
|
||||
|
||||
/*
|
||||
** Does the vector data pointer refer to memory that this class has manually
|
||||
** allocated? If so, then this class is responsible for deleting it.
|
||||
*/
|
||||
bool IsAllocated;
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::VectorClass -- Constructor for vector class. *
|
||||
* *
|
||||
* This constructor for the vector class is passed the initial size of the vector and an *
|
||||
* optional pointer to a preallocated block of memory that the vector will be placed in. *
|
||||
* If this optional pointer is NULL (or not provided), then the vector is allocated out *
|
||||
* of free store (with the "new" operator). *
|
||||
* *
|
||||
* INPUT: size -- The number of elements to initialize this vector to. *
|
||||
* *
|
||||
* array -- Optional pointer to a previously allocated memory block to hold the *
|
||||
* vector. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
VectorClass<T>::VectorClass(int size, T const * array) :
|
||||
Vector(0),
|
||||
VectorMax(size),
|
||||
IsValid(true),
|
||||
IsAllocated(false)
|
||||
{
|
||||
/*
|
||||
** Allocate the vector. The default constructor will be called for every
|
||||
** object in this vector.
|
||||
*/
|
||||
if (size) {
|
||||
if (array) {
|
||||
Vector = new((void*)array) T[size];
|
||||
} else {
|
||||
Vector = new T[size];
|
||||
IsAllocated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::~VectorClass -- Default destructor for vector class. *
|
||||
* *
|
||||
* This is the default destructor for the vector class. It will deallocate any memory *
|
||||
* that it may have allocated. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
VectorClass<T>::~VectorClass(void)
|
||||
{
|
||||
VectorClass<T>::Clear();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::VectorClass -- Copy constructor for vector object. *
|
||||
* *
|
||||
* This is the copy constructor for the vector class. It will duplicate the provided *
|
||||
* vector into the new vector being created. *
|
||||
* *
|
||||
* INPUT: vector -- Reference to the vector to use as a copy. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
VectorClass<T>::VectorClass(VectorClass<T> const & vector) :
|
||||
Vector(0),
|
||||
VectorMax(0),
|
||||
IsValid(true),
|
||||
IsAllocated(false)
|
||||
{
|
||||
*this = vector;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::operator = -- The assignment operator. *
|
||||
* *
|
||||
* This the the assignment operator for vector objects. It will alter the existing lvalue *
|
||||
* vector to duplicate the rvalue one. *
|
||||
* *
|
||||
* INPUT: vector -- The rvalue vector to copy into the lvalue one. *
|
||||
* *
|
||||
* OUTPUT: Returns with reference to the newly copied vector. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
VectorClass<T> & VectorClass<T>::operator =(VectorClass<T> const & vector)
|
||||
{
|
||||
if (this != &vector) {
|
||||
Clear();
|
||||
VectorMax = vector.Length();
|
||||
if (VectorMax) {
|
||||
Vector = new T[VectorMax];
|
||||
if (Vector) {
|
||||
IsAllocated = true;
|
||||
for (int index = 0; index < VectorMax; index++) {
|
||||
Vector[index] = vector[index];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vector = 0;
|
||||
IsAllocated = false;
|
||||
}
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::operator == -- Equality operator for vector objects. *
|
||||
* *
|
||||
* This operator compares two vectors for equality. It does this by performing an object *
|
||||
* by object comparison between the two vectors. *
|
||||
* *
|
||||
* INPUT: vector -- The right vector expression. *
|
||||
* *
|
||||
* OUTPUT: bool; Are the two vectors essentially equal? (do they contain comparable elements *
|
||||
* in the same order?) *
|
||||
* *
|
||||
* WARNINGS: The equality operator must exist for the objects that this vector contains. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool VectorClass<T>::operator == (VectorClass<T> const & vector) const
|
||||
{
|
||||
if (VectorMax == vector.Length()) {
|
||||
for (int index = 0; index < VectorMax; index++) {
|
||||
if (Vector[index] != vector[index]) {
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::ID -- Pointer based conversion to index number. *
|
||||
* *
|
||||
* Use this routine to convert a pointer to an element in the vector back into the index *
|
||||
* number of that object. This routine ONLY works with actual pointers to object within *
|
||||
* the vector. For "equivalent" object index number (such as with similar integral values) *
|
||||
* then use the "by value" index number ID function. *
|
||||
* *
|
||||
* INPUT: pointer -- Pointer to an actual object in the vector. *
|
||||
* *
|
||||
* OUTPUT: Returns with the index number for the object pointed to by the parameter. *
|
||||
* *
|
||||
* WARNINGS: This routine is only valid for actual pointers to object that exist within *
|
||||
* the vector. All other object pointers will yield undefined results. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/13/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
inline int VectorClass<T>::ID(T const * ptr)
|
||||
{
|
||||
if (!IsValid) return(0);
|
||||
return(((unsigned long)ptr - (unsigned long)&(*this)[0]) / sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::ID -- Finds object ID based on value. *
|
||||
* *
|
||||
* Use this routine to find the index value of an object with equivalent value in the *
|
||||
* vector. Typical use of this would be for integral types. *
|
||||
* *
|
||||
* INPUT: object -- Reference to the object that is to be looked up in the vector. *
|
||||
* *
|
||||
* OUTPUT: Returns with the index number of the object that is equivalent to the one *
|
||||
* specified. If no matching value could be found then -1 is returned. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/13/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
int VectorClass<T>::ID(T const & object)
|
||||
{
|
||||
if (!IsValid) return(0);
|
||||
|
||||
for (int index = 0; index < VectorMax; index++) {
|
||||
if ((*this)[index] == object) {
|
||||
return(index);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::Clear -- Frees and clears the vector. *
|
||||
* *
|
||||
* Use this routine to reset the vector to an empty (non-allocated) state. A vector will *
|
||||
* free all allocated memory when this routine is called. In order for the vector to be *
|
||||
* useful after this point, the Resize function must be called to give it element space. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
void VectorClass<T>::Clear(void)
|
||||
{
|
||||
if (Vector && IsAllocated) {
|
||||
delete[] Vector;
|
||||
Vector = 0;
|
||||
}
|
||||
IsAllocated = false;
|
||||
VectorMax = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VectorClass<T>::Resize -- Changes the size of the vector. *
|
||||
* *
|
||||
* This routine is used to change the size (usually to increase) the size of a vector. This *
|
||||
* is the only way to increase the vector's working room (number of elements). *
|
||||
* *
|
||||
* INPUT: newsize -- The desired size of the vector. *
|
||||
* *
|
||||
* array -- Optional pointer to a previously allocated memory block that the *
|
||||
* array will be located in. If this parameter is not supplied, then *
|
||||
* the array will be allocated from free store. *
|
||||
* *
|
||||
* OUTPUT: bool; Was the array resized successfully? *
|
||||
* *
|
||||
* WARNINGS: Failure to succeed could be the result of running out of memory. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool VectorClass<T>::Resize(int newsize, T const * array)
|
||||
{
|
||||
if (newsize) {
|
||||
|
||||
/*
|
||||
** Allocate a new vector of the size specified. The default constructor
|
||||
** will be called for every object in this vector.
|
||||
*/
|
||||
T * newptr;
|
||||
|
||||
/*
|
||||
** Either create a new memory block for the object array or initialize
|
||||
** an existing block as indicated by the array parameter. When creating a new
|
||||
** memory block, flag that the vector object is currently in an invalid
|
||||
** state. This is necessary because the default constructor for the object
|
||||
** elements may look to the vector to fetch their ID number.
|
||||
*/
|
||||
IsValid = false;
|
||||
if (!array) {
|
||||
newptr = new T[newsize];
|
||||
} else {
|
||||
newptr = new((void*)array) T[newsize];
|
||||
}
|
||||
IsValid = true;
|
||||
if (!newptr) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*
|
||||
** If there is an old vector, then it must be copied (as much as is feasible)
|
||||
** to the new vector.
|
||||
*/
|
||||
if (Vector != NULL) {
|
||||
|
||||
/*
|
||||
** Copy as much of the old vector into the new vector as possible. This
|
||||
** presumes that there is a functional assignment operator for each
|
||||
** of the objects in the vector.
|
||||
*/
|
||||
int copycount = (newsize < VectorMax) ? newsize : VectorMax;
|
||||
for (int index = 0; index < copycount; index++) {
|
||||
newptr[index] = Vector[index];
|
||||
}
|
||||
|
||||
/*
|
||||
** Delete the old vector. This might cause the destructors to be called
|
||||
** for all of the old elements. This makes the implementation of suitable
|
||||
** assignment operator very important. The default assignment operator will
|
||||
** only work for the simplest of objects.
|
||||
*/
|
||||
if (IsAllocated) {
|
||||
delete[] Vector;
|
||||
Vector = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Assign the new vector data to this class.
|
||||
*/
|
||||
Vector = newptr;
|
||||
VectorMax = newsize;
|
||||
IsAllocated = (Vector && !array);
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Resizing to zero is the same as clearing the vector.
|
||||
*/
|
||||
Clear();
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
** This derivative vector class adds the concept of adding and deleting
|
||||
** objects. The objects are packed to the beginning of the vector array.
|
||||
** If this is instantiated for a class object, then the assignment operator
|
||||
** and the equality operator must be supported. If the vector allocates its
|
||||
** own memory, then the vector can grow if it runs out of room adding items.
|
||||
** The growth rate is controlled by setting the growth step rate. A growth
|
||||
** step rate of zero disallows growing.
|
||||
*/
|
||||
template<class T>
|
||||
class DynamicVectorClass : public VectorClass<T>
|
||||
{
|
||||
public:
|
||||
DynamicVectorClass(unsigned size=0, T const * array=0);
|
||||
|
||||
// Change maximum size of vector.
|
||||
virtual bool Resize(int newsize, T const * array=0);
|
||||
|
||||
// Resets and frees the vector array.
|
||||
virtual void Clear(void) {ActiveCount = 0;VectorClass<T>::Clear();};
|
||||
|
||||
// Fetch number of "allocated" vector objects.
|
||||
int Count(void) const {return(ActiveCount);};
|
||||
|
||||
// Add object to vector (growing as necessary).
|
||||
bool Add(T const & object);
|
||||
bool Add_Head(T const & object);
|
||||
|
||||
// Delete object just like this from vector.
|
||||
bool Delete(T const & object);
|
||||
|
||||
// Delete object at this vector index.
|
||||
bool Delete(int index);
|
||||
|
||||
// Deletes all objects in the vector.
|
||||
void Delete_All(void) {ActiveCount = 0;};
|
||||
|
||||
// Set amount that vector grows by.
|
||||
int Set_Growth_Step(int step) {return(GrowthStep = step);};
|
||||
|
||||
// Fetch current growth step rate.
|
||||
int Growth_Step(void) {return GrowthStep;};
|
||||
|
||||
virtual int ID(T const * ptr) {return(VectorClass<T>::ID(ptr));};
|
||||
virtual int ID(T const & ptr);
|
||||
|
||||
DynamicVectorClass<T> & operator =(DynamicVectorClass<T> const & rvalue) {
|
||||
VectorClass<T>::operator = (rvalue);
|
||||
ActiveCount = rvalue.ActiveCount;
|
||||
GrowthStep = rvalue.GrowthStep;
|
||||
return(*this);
|
||||
}
|
||||
|
||||
// Uninitialized Add - does everything an Add does, except copying an
|
||||
// object into the 'new' spot in the array. It returns a pointer to
|
||||
// the 'new' spot. (NULL if the Add failed). NOTE - you must then fill
|
||||
// this memory area with a valid object (e.g. by using placement new),
|
||||
// or chaos will result!
|
||||
T * Uninitialized_Add(void);
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
** This is a count of the number of active objects in this
|
||||
** vector. The memory array often times is bigger than this
|
||||
** value.
|
||||
*/
|
||||
int ActiveCount;
|
||||
|
||||
/*
|
||||
** If there is insufficient room in the vector array for a new
|
||||
** object to be added, then the vector will grow by the number
|
||||
** of objects specified by this value. This is controlled by
|
||||
** the Set_Growth_Step() function.
|
||||
*/
|
||||
int GrowthStep;
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::DynamicVectorClass -- Constructor for dynamic vector. *
|
||||
* *
|
||||
* This is the normal constructor for the dynamic vector class. It is similar to the normal *
|
||||
* vector class constructor. The vector is initialized to contain the number of elements *
|
||||
* specified in the "size" parameter. The memory is allocated from free store unless the *
|
||||
* optional array parameter is provided. In this case it will place the vector at the *
|
||||
* memory location specified. *
|
||||
* *
|
||||
* INPUT: size -- The maximum number of objects allowed in this vector. *
|
||||
* *
|
||||
* array -- Optional pointer to the memory area to place the vector at. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
DynamicVectorClass<T>::DynamicVectorClass(unsigned size, T const * array)
|
||||
: VectorClass<T>(size, array)
|
||||
{
|
||||
GrowthStep = 10;
|
||||
ActiveCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::Resize -- Changes the size of a dynamic vector. *
|
||||
* *
|
||||
* Use this routine to change the size of the vector. The size changed is the maximum *
|
||||
* number of allocated objects within this vector. If a memory buffer is provided, then *
|
||||
* the vector will be located there. Otherwise, the memory will be allocated out of free *
|
||||
* store. *
|
||||
* *
|
||||
* INPUT: newsize -- The desired maximum size of this vector. *
|
||||
* *
|
||||
* array -- Optional pointer to a previously allocated memory array. *
|
||||
* *
|
||||
* OUTPUT: bool; Was vector successfully resized according to specifications? *
|
||||
* *
|
||||
* WARNINGS: Failure to resize the vector could be the result of lack of free store. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool DynamicVectorClass<T>::Resize(int newsize, T const * array)
|
||||
{
|
||||
if (VectorClass<T>::Resize(newsize, array)) {
|
||||
if (Length() < ActiveCount) ActiveCount = Length();
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::ID -- Find matching value in the dynamic vector. *
|
||||
* *
|
||||
* Use this routine to find a matching object (by value) in the vector. Unlike the base *
|
||||
* class ID function of similar name, this one restricts the scan to the current number *
|
||||
* of valid objects. *
|
||||
* *
|
||||
* INPUT: object -- A reference to the object that a match is to be found in the *
|
||||
* vector. *
|
||||
* *
|
||||
* OUTPUT: Returns with the index number of the object that is equivalent to the one *
|
||||
* specified. If no equivalent object could be found then -1 is returned. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/13/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
int DynamicVectorClass<T>::ID(T const & object)
|
||||
{
|
||||
for (int index = 0; index < Count(); index++) {
|
||||
if ((*this)[index] == object) return(index);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::Add -- Add an element to the vector. *
|
||||
* *
|
||||
* Use this routine to add an element to the vector. The vector will automatically be *
|
||||
* resized to accomodate the new element IF the vector was allocated previously and the *
|
||||
* growth rate is not zero. *
|
||||
* *
|
||||
* INPUT: object -- Reference to the object that will be added to the vector. *
|
||||
* *
|
||||
* OUTPUT: bool; Was the object added successfully? If so, the object is added to the end *
|
||||
* of the vector. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool DynamicVectorClass<T>::Add(T const & object)
|
||||
{
|
||||
if (ActiveCount >= Length()) {
|
||||
if ((IsAllocated || !VectorMax) && GrowthStep > 0) {
|
||||
if (!Resize(Length() + GrowthStep)) {
|
||||
|
||||
/*
|
||||
** Failure to increase the size of the vector is an error condition.
|
||||
** Return with the error flag.
|
||||
*/
|
||||
return(false);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Increasing the size of this vector is not allowed! Bail this
|
||||
** routine with the error code.
|
||||
*/
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** There is room for the new object now. Add it to the end of the object vector.
|
||||
*/
|
||||
(*this)[ActiveCount++] = object;
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::Add_Head -- Adds element to head of the list. *
|
||||
* *
|
||||
* This routine will add the specified element to the head of the vector. If necessary, *
|
||||
* the vector will be expanded accordingly. *
|
||||
* *
|
||||
* INPUT: object -- Reference to the object to add to the head of this vector. *
|
||||
* *
|
||||
* OUTPUT: bool; Was the object added without error? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 09/21/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool DynamicVectorClass<T>::Add_Head(T const & object)
|
||||
{
|
||||
if (ActiveCount >= Length()) {
|
||||
if ((IsAllocated || !VectorMax) && GrowthStep > 0) {
|
||||
if (!Resize(Length() + GrowthStep)) {
|
||||
|
||||
/*
|
||||
** Failure to increase the size of the vector is an error condition.
|
||||
** Return with the error flag.
|
||||
*/
|
||||
return(false);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Increasing the size of this vector is not allowed! Bail this
|
||||
** routine with the error code.
|
||||
*/
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** There is room for the new object now. Add it to the end of the object vector.
|
||||
*/
|
||||
if (ActiveCount) {
|
||||
memmove(&(*this)[1], &(*this)[0], ActiveCount * sizeof(T));
|
||||
}
|
||||
(*this)[0] = object;
|
||||
ActiveCount++;
|
||||
// (*this)[ActiveCount++] = object;
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::Delete -- Remove the specified object from the vector. *
|
||||
* *
|
||||
* This routine will delete the object referenced from the vector. All objects in the *
|
||||
* vector that follow the one deleted will be moved "down" to fill the hole. *
|
||||
* *
|
||||
* INPUT: object -- Reference to the object in this vector that is to be deleted. *
|
||||
* *
|
||||
* OUTPUT: bool; Was the object deleted successfully? This should always be true. *
|
||||
* *
|
||||
* WARNINGS: Do no pass a reference to an object that is NOT part of this vector. The *
|
||||
* results of this are undefined and probably catastrophic. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool DynamicVectorClass<T>::Delete(T const & object)
|
||||
{
|
||||
int id = ID(object);
|
||||
if (id != -1) {
|
||||
return(Delete(id));
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::Delete -- Deletes the specified index from the vector. *
|
||||
* *
|
||||
* Use this routine to delete the object at the specified index from the objects in the *
|
||||
* vector. This routine will move all the remaining objects "down" in order to fill the *
|
||||
* hole. *
|
||||
* *
|
||||
* INPUT: index -- The index number of the object in the vector that is to be deleted. *
|
||||
* *
|
||||
* OUTPUT: bool; Was the object index deleted successfully? Failure might mean that the index *
|
||||
* specified was out of bounds. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/10/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
bool DynamicVectorClass<T>::Delete(int index)
|
||||
{
|
||||
if (index < ActiveCount) {
|
||||
ActiveCount--;
|
||||
|
||||
/*
|
||||
** If there are any objects past the index that was deleted, copy those
|
||||
** objects down in order to fill the hole. A simple memory copy is
|
||||
** not sufficient since the vector could contain class objects that
|
||||
** need to use the assignment operator for movement.
|
||||
*/
|
||||
for (int i = index; i < ActiveCount; i++) {
|
||||
(*this)[i] = (*this)[i+1];
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* DynamicVectorClass<T>::Uninitialized_Add -- Add an empty place to the vector. *
|
||||
* *
|
||||
* To avoid copying when creating an object and adding it to the vector, use this and *
|
||||
* immediately fill the area that the return value points to with a valid object (by hand *
|
||||
* for a struct or by using placement new for a class object). *
|
||||
* This function does everything Add does except copying an object into the new space, *
|
||||
* thus leaving an uninitialized area of memory. *
|
||||
* *
|
||||
* INPUT: none. *
|
||||
* *
|
||||
* OUTPUT: T *; Points to the empty space where the new object is to be created. (If the *
|
||||
* space was not added succesfully, returns NULL). *
|
||||
* *
|
||||
* WARNINGS: If memory area is left uninitialized, Very Bad Things will happen. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 03/04/1998 NH : Created. *
|
||||
*=============================================================================================*/
|
||||
template<class T>
|
||||
T * DynamicVectorClass<T>::Uninitialized_Add(void)
|
||||
{
|
||||
if (ActiveCount >= Length()) {
|
||||
if ((IsAllocated || !VectorMax) && GrowthStep > 0) {
|
||||
if (!Resize(Length() + GrowthStep)) {
|
||||
|
||||
/*
|
||||
** Failure to increase the size of the vector is an error condition.
|
||||
** Return with the error value.
|
||||
*/
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
** Increasing the size of this vector is not allowed! Bail this
|
||||
** routine with the error value.
|
||||
*/
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** There is room for the new space now. Add it to the end of the object
|
||||
** vector. and return a pointer to it.
|
||||
*/
|
||||
return &((*this)[ActiveCount++]);
|
||||
}
|
||||
|
||||
|
||||
void Set_Bit(void * array, int bit, int value);
|
||||
int Get_Bit(void const * array, int bit);
|
||||
int First_True_Bit(void const * array);
|
||||
int First_False_Bit(void const * array);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
** This is a derivative of a vector class that supports boolean flags. Since
|
||||
** a boolean flag can be represented by a single bit, this class packs the
|
||||
** array of boolean flags into an array of bytes containing 8 boolean values
|
||||
** each. For large boolean arrays, this results in an 87.5% savings. Although
|
||||
** the indexing "[]" operator is supported, DO NOT pass pointers to sub elements
|
||||
** of this bit vector class. A pointer derived from the indexing operator is
|
||||
** only valid until the next call. Because of this, only simple
|
||||
** direct use of the "[]" operator is allowed.
|
||||
*/
|
||||
class BooleanVectorClass
|
||||
{
|
||||
public:
|
||||
BooleanVectorClass(unsigned size=0, unsigned char * array=0);
|
||||
BooleanVectorClass(BooleanVectorClass const & vector);
|
||||
|
||||
// Assignment operator.
|
||||
BooleanVectorClass & operator =(BooleanVectorClass const & vector);
|
||||
|
||||
// Equivalency operator.
|
||||
bool operator == (BooleanVectorClass const & vector);
|
||||
|
||||
// Fetch number of boolean objects in vector.
|
||||
int Length(void) {return BitCount;};
|
||||
|
||||
// Set all boolean values to false;
|
||||
void Reset(void);
|
||||
|
||||
// Set all boolean values to true.
|
||||
void Set(void);
|
||||
|
||||
// Resets vector to zero length (frees memory).
|
||||
void Clear(void);
|
||||
|
||||
// Change size of this boolean vector.
|
||||
int Resize(unsigned size);
|
||||
|
||||
// Fetch reference to specified index.
|
||||
bool const & operator[](int index) const {
|
||||
if (LastIndex != index) Fixup(index);
|
||||
return(Copy);
|
||||
};
|
||||
bool & operator[](int index) {
|
||||
if (LastIndex != index) Fixup(index);
|
||||
return(Copy);
|
||||
};
|
||||
|
||||
// Quick check on boolean state.
|
||||
bool Is_True(int index) const {
|
||||
if (index == LastIndex) return(Copy);
|
||||
return(Get_Bit(&BitArray[0], index) != 0);
|
||||
};
|
||||
|
||||
// Find first index that is false.
|
||||
int First_False(void) const {
|
||||
if (LastIndex != -1) Fixup(-1);
|
||||
|
||||
int retval = First_False_Bit(&BitArray[0]);
|
||||
if (retval < BitCount) return(retval);
|
||||
|
||||
/*
|
||||
** Failure to find a false boolean value in the vector. Return this
|
||||
** fact in the form of an invalid index number.
|
||||
*/
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// Find first index that is true.
|
||||
int First_True(void) const {
|
||||
if (LastIndex != -1) Fixup(-1);
|
||||
|
||||
int retval = First_True_Bit(&BitArray[0]);
|
||||
if (retval < BitCount) return(retval);
|
||||
|
||||
/*
|
||||
** Failure to find a true boolean value in the vector. Return this
|
||||
** fact in the form of an invalid index number.
|
||||
*/
|
||||
return(-1);
|
||||
}
|
||||
|
||||
private:
|
||||
void Fixup(int index=-1) const;
|
||||
|
||||
/*
|
||||
** This is the number of boolean values in the vector. This value is
|
||||
** not necessarily a multiple of 8, even though the underlying character
|
||||
** vector contains a multiple of 8 bits.
|
||||
*/
|
||||
int BitCount;
|
||||
|
||||
/*
|
||||
** This is a referential copy of an element in the bit vector. The
|
||||
** purpose of this copy is to allow normal reference access to this
|
||||
** object (for speed reasons). This hides the bit packing scheme from
|
||||
** the user of this class.
|
||||
*/
|
||||
bool Copy;
|
||||
|
||||
/*
|
||||
** This records the index of the value last fetched into the reference
|
||||
** boolean variable. This index is used to properly restore the value
|
||||
** when the reference copy needs updating.
|
||||
*/
|
||||
int LastIndex;
|
||||
|
||||
/*
|
||||
** This points to the allocated bitfield array.
|
||||
*/
|
||||
VectorClass<unsigned char> BitArray;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
int Pointer_Vector_Add(T * ptr, VectorClass<T *> & vec)
|
||||
{
|
||||
int id = 0;
|
||||
bool foundspot = false;
|
||||
for (int index = 0; index < vec.Length(); index++) {
|
||||
if (vec[index] == NULL) {
|
||||
id = index;
|
||||
foundspot = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundspot) {
|
||||
id = vec.Length();
|
||||
vec.Resize((vec.Length()+1) * 2);
|
||||
for (int index = id; index < vec.Length(); index++) {
|
||||
vec[index] = NULL;
|
||||
}
|
||||
}
|
||||
vec[id] = ptr;
|
||||
return(id);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Pointer_Vector_Remove(T const * ptr, VectorClass<T *> & vec)
|
||||
{
|
||||
int id = vec.ID((T *)ptr);
|
||||
if (id != -1) {
|
||||
vec[id] = NULL;
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
404
Code/Tools/pluglib/WWmatrix3.cpp
Normal file
404
Code/Tools/pluglib/WWmatrix3.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
1011
Code/Tools/pluglib/WWmatrix3.h
Normal file
1011
Code/Tools/pluglib/WWmatrix3.h
Normal file
File diff suppressed because it is too large
Load Diff
83
Code/Tools/pluglib/aaplane.h
Normal file
83
Code/Tools/pluglib/aaplane.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/aaplane.h $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 5/19/00 3:12p $*
|
||||
* *
|
||||
* $Revision:: 8 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef AAPLANE_H
|
||||
#define AAPLANE_H
|
||||
|
||||
#include "always.h"
|
||||
#include "vector3.h"
|
||||
|
||||
|
||||
/*
|
||||
** This class is used to describe an "axis-aligned" plane. I.e, the normal
|
||||
** of the plane is one of the three coordinate axes.
|
||||
*/
|
||||
class AAPlaneClass
|
||||
{
|
||||
public:
|
||||
|
||||
enum AxisEnum { XNORMAL = 0, YNORMAL = 1, ZNORMAL = 2 };
|
||||
|
||||
AAPlaneClass(void) { }
|
||||
AAPlaneClass(AxisEnum normal,float dist) : Normal(normal),Dist(dist) { }
|
||||
|
||||
void Set(AxisEnum normal,float dist);
|
||||
void Get_Normal(Vector3 * normal) const;
|
||||
|
||||
public:
|
||||
|
||||
AxisEnum Normal;
|
||||
float Dist;
|
||||
|
||||
};
|
||||
|
||||
inline void AAPlaneClass::Set(AxisEnum normal,float dist)
|
||||
{
|
||||
Normal = normal;
|
||||
Dist = dist;
|
||||
}
|
||||
|
||||
inline void AAPlaneClass::Get_Normal(Vector3 * normal) const
|
||||
{
|
||||
normal->Set(0,0,0);
|
||||
(*normal)[Normal] = 1.0f;
|
||||
}
|
||||
|
||||
#endif
|
||||
170
Code/Tools/pluglib/always.h
Normal file
170
Code/Tools/pluglib/always.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/always.h $*
|
||||
* *
|
||||
* $Author:: Steve_t $*
|
||||
* *
|
||||
* $Modtime:: 8/28/01 3:21p $*
|
||||
* *
|
||||
* $Revision:: 13 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef ALWAYS_H
|
||||
#define ALWAYS_H
|
||||
|
||||
// Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
|
||||
#pragma warning(disable : 4530)
|
||||
|
||||
/*
|
||||
** Define for debug memory allocation to include __FILE__ and __LINE__ for every memory allocation.
|
||||
** This helps find leaks.
|
||||
*/
|
||||
//#define STEVES_NEW_CATCHER
|
||||
#ifdef _DEBUG
|
||||
#ifdef _MSC_VER
|
||||
#ifdef STEVES_NEW_CATCHER
|
||||
|
||||
#include <crtdbg.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
|
||||
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
|
||||
#define _msize(p) _msize_dbg(p, _NORMAL_BLOCK)
|
||||
|
||||
void* __cdecl operator new(unsigned int s);
|
||||
|
||||
#endif //STEVES_NEW_CATCHER
|
||||
#endif //_MSC_VER
|
||||
#endif //_DEBUG
|
||||
|
||||
|
||||
// Jani: Intel's C++ compiler issues too many warnings in WW libraries when using warning level 4
|
||||
#if defined (__ICL) // Detect Intel compiler
|
||||
#pragma warning (3)
|
||||
#pragma warning ( disable: 981 ) // parameters defined in unspecified order
|
||||
#pragma warning ( disable: 279 ) // controlling expressaion is constant
|
||||
#pragma warning ( disable: 271 ) // trailing comma is nonstandard
|
||||
#pragma warning ( disable: 171 ) // invalid type conversion
|
||||
#pragma warning ( disable: 1 ) // last line of file ends without a newline
|
||||
#endif
|
||||
|
||||
// Jani: MSVC doesn't necessarily inline code with inline keyword. Using __forceinline results better inlining
|
||||
// and also prints out a warning if inlining wasn't possible. __forceinline is MSVC specific.
|
||||
#if defined(_MSC_VER)
|
||||
#define WWINLINE __forceinline
|
||||
#else
|
||||
#define WWINLINE inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Define the MIN and MAX macros.
|
||||
** NOTE: Joe used to #include <minmax.h> in the various compiler header files. This
|
||||
** header defines 'min' and 'max' macros which conflict with the surrender code so
|
||||
** I'm relpacing all occurances of 'min' and 'max with 'MIN' and 'MAX'. For code which
|
||||
** is out of our domain (e.g. Max sdk) I'm declaring template functions for 'min' and 'max'
|
||||
*/
|
||||
#define NOMINMAX
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
template <class T> T min(T a,T b)
|
||||
{
|
||||
if (a<b) {
|
||||
return a;
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T> T max(T a,T b)
|
||||
{
|
||||
if (a>b) {
|
||||
return a;
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This includes the minimum set of compiler defines and pragmas in order to bring the
|
||||
** various compilers to a common behavior such that the C&C engine will compile without
|
||||
** error or warning.
|
||||
*/
|
||||
#if defined(__BORLANDC__)
|
||||
#include "borlandc.h"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "visualc.h"
|
||||
#endif
|
||||
|
||||
#if defined(__WATCOMC__)
|
||||
#include "watcom.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
** This macro serves as a general way to determine the number of elements
|
||||
** within an array.
|
||||
*/
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) int(sizeof(x)/sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
#ifndef size_of
|
||||
#define size_of(typ,id) sizeof(((typ*)0)->id)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
64
Code/Tools/pluglib/bool.h
Normal file
64
Code/Tools/pluglib/bool.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/bool.h $*
|
||||
* *
|
||||
* $Author:: Neal_k $*
|
||||
* *
|
||||
* $Modtime:: 9/23/99 1:46p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#if !defined(TRUE_FALSE_DEFINED) && !defined(__BORLANDC__) && (_MSC_VER < 1100) && !defined(__WATCOMC__)
|
||||
#define TRUE_FALSE_DEFINED
|
||||
|
||||
/**********************************************************************
|
||||
** The "bool" integral type was defined by the C++ comittee in
|
||||
** November of '94. Until the compiler supports this, use the following
|
||||
** definition.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#include "yvals.h"
|
||||
#define bool unsigned
|
||||
|
||||
#elif defined(_UNIX)
|
||||
|
||||
/////#define bool unsigned
|
||||
|
||||
#else
|
||||
|
||||
enum {false=0,true=1};
|
||||
typedef int bool;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
48
Code/Tools/pluglib/borlandc.h
Normal file
48
Code/Tools/pluglib/borlandc.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/borlandc.h $*
|
||||
* *
|
||||
* $Author:: Eric_c $*
|
||||
* *
|
||||
* $Modtime:: 4/02/99 11:57a $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#if !defined(BORLANDC_H) && defined(__BORLANDC__)
|
||||
#define BORLANDC_H
|
||||
|
||||
/*
|
||||
** Funny, but there are no required overrides to make Borland C match C++ standards. This
|
||||
** is because Borland C more closely matches the C++ standard than the other compilers.
|
||||
*/
|
||||
|
||||
#endif
|
||||
841
Code/Tools/pluglib/chunkio.cpp
Normal file
841
Code/Tools/pluglib/chunkio.cpp
Normal file
@@ -0,0 +1,841 @@
|
||||
/*
|
||||
** 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/wwlib/chunkio.cpp 12 3/14/02 1:25p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Tiberian Sun / Commando / G Library *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/chunkio.cpp $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 3/04/02 4:00p $*
|
||||
* *
|
||||
* $Revision:: 12 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* ChunkSaveClass::ChunkSaveClass -- Constructor *
|
||||
* ChunkSaveClass::Begin_Chunk -- Begin a new chunk in the file *
|
||||
* ChunkSaveClass::End_Chunk -- Close a chunk, computes the size and adds to the header *
|
||||
* ChunkSaveClass::Begin_Micro_Chunk -- begins a new "micro-chunk" *
|
||||
* ChunkSaveClass::End_Micro_Chunk -- close a micro-chunk *
|
||||
* ChunkSaveClass::Write -- Write data into the current chunk *
|
||||
* ChunkSaveClass::Write -- write an IOVector2Struct *
|
||||
* ChunkSaveClass::Write -- write an IOVector3Struct *
|
||||
* ChunkSaveClass::Write -- write an IOVector4Struct *
|
||||
* ChunkSaveClass::Write -- write an IOQuaternionStruct *
|
||||
* ChunkSaveClass::Cur_Chunk_Depth -- returns the current chunk recursion depth (debugging) *
|
||||
* ChunkLoadClass::ChunkLoadClass -- Constructor *
|
||||
* ChunkLoadClass::Open_Chunk -- Open a chunk in the file, reads in the chunk header *
|
||||
* ChunkLoadClass::Peek_Next_Chunk -- sneak peek into the next chunk that will be opened *
|
||||
* ChunkLoadClass::Close_Chunk -- Close a chunk, seeks to the end if needed *
|
||||
* ChunkLoadClass::Cur_Chunk_ID -- Returns the ID of the current chunk *
|
||||
* ChunkLoadClass::Cur_Chunk_Length -- Returns the current length of the current chunk *
|
||||
* ChunkLoadClass::Cur_Chunk_Depth -- returns the current chunk recursion depth *
|
||||
* ChunkLoadClass::Contains_Chunks -- Test whether the current chunk contains chunks (or dat *
|
||||
* ChunkLoadClass::Open_Micro_Chunk -- reads in a micro-chunk header *
|
||||
* ChunkLoadClass::Close_Micro_Chunk -- closes a micro-chunk *
|
||||
* ChunkLoadClass::Cur_Micro_Chunk_ID -- returns the ID of the current micro-chunk (asserts *
|
||||
* ChunkLoadClass::Cur_Micro_Chunk_Length -- returns the size of the current micro chunk *
|
||||
* ChunkLoadClass::Read -- Read data from the file *
|
||||
* ChunkLoadClass::Read -- read an IOVector2Struct *
|
||||
* ChunkLoadClass::Read -- read an IOVector3Struct *
|
||||
* ChunkLoadClass::Read -- read an IOVector4Struct *
|
||||
* ChunkLoadClass::Read -- read an IOQuaternionStruct *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "chunkio.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::ChunkSaveClass -- Constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* file - pointer to a FileClass object to write to *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
ChunkSaveClass::ChunkSaveClass(FileClass * file) :
|
||||
File(file),
|
||||
StackIndex(0),
|
||||
InMicroChunk(false),
|
||||
MicroChunkPosition(0)
|
||||
{
|
||||
memset(PositionStack,0,sizeof(PositionStack));
|
||||
memset(HeaderStack,0,sizeof(HeaderStack));
|
||||
memset(&MCHeader,0,sizeof(MCHeader));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Begin_Chunk -- Begin a new chunk in the file *
|
||||
* *
|
||||
* INPUT: *
|
||||
* id - id of the chunk *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkSaveClass::Begin_Chunk(uint32 id)
|
||||
{
|
||||
ChunkHeader chunkh;
|
||||
int filepos;
|
||||
|
||||
// If we have a parent chunk, set its 'Contains_Chunks' flag
|
||||
if (StackIndex > 0) {
|
||||
HeaderStack[StackIndex-1].Set_Sub_Chunk_Flag(true);
|
||||
}
|
||||
|
||||
// Save the current file position and chunk header
|
||||
// for the call to End_Chunk.
|
||||
chunkh.Set_Type(id);
|
||||
chunkh.Set_Size(0);
|
||||
filepos = File->Seek(0);
|
||||
|
||||
PositionStack[StackIndex] = filepos;
|
||||
HeaderStack[StackIndex] = chunkh;
|
||||
StackIndex++;
|
||||
|
||||
// write a temporary chunk header (size = 0)
|
||||
if (File->Write(&chunkh,sizeof(chunkh)) != sizeof(chunkh)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::End_Chunk -- Close a chunk, computes the size and adds to the header *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkSaveClass::End_Chunk(void)
|
||||
{
|
||||
// If the user didn't close his micro chunks bad things are gonna happen
|
||||
assert(!InMicroChunk);
|
||||
|
||||
// Save the current position
|
||||
int curpos = File->Seek(0);
|
||||
|
||||
// Pop the position and chunk header off the stacks
|
||||
StackIndex--;
|
||||
int chunkpos = PositionStack[StackIndex];
|
||||
ChunkHeader chunkh = HeaderStack[StackIndex];
|
||||
|
||||
// write the completed header
|
||||
File->Seek(chunkpos,SEEK_SET);
|
||||
if (File->Write(&chunkh,sizeof(chunkh)) != sizeof(chunkh)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the total bytes written to any encompasing chunk
|
||||
if (StackIndex != 0) {
|
||||
HeaderStack[StackIndex-1].Add_Size(chunkh.Get_Size() + sizeof(chunkh));
|
||||
}
|
||||
|
||||
// Go back to the end of the file
|
||||
File->Seek(curpos,SEEK_SET);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Begin_Micro_Chunk -- begins a new "micro-chunk" *
|
||||
* *
|
||||
* Micro chunks are used to wrap individual variables. They aren't hierarchical so if you *
|
||||
* attempt to open a micro chunk while already in one, an assert will occur. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* id - 8bit id *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* id is asserted to be between 0 and 255 *
|
||||
* cannot nest micro chunks so it asserts that you are currently not in another micro-chunk *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/3/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkSaveClass::Begin_Micro_Chunk(uint32 id)
|
||||
{
|
||||
assert(id < 256);
|
||||
assert(!InMicroChunk);
|
||||
|
||||
// Save the current file position and chunk header
|
||||
// for the call to End_Micro_Chunk.
|
||||
MCHeader.Set_Type(id);
|
||||
MCHeader.Set_Size(0);
|
||||
MicroChunkPosition = File->Seek(0);
|
||||
|
||||
// Write a temporary chunk header
|
||||
// NOTE: I'm calling the ChunkSaveClass::Write method so that the bytes for
|
||||
// this header are tracked in the wrapping chunk. This is because micro-chunks
|
||||
// are simply data inside the normal chunks...
|
||||
if (Write(&MCHeader,sizeof(MCHeader)) != sizeof(MCHeader)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InMicroChunk = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::End_Micro_Chunk -- close a micro-chunk *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/3/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkSaveClass::End_Micro_Chunk(void)
|
||||
{
|
||||
assert(InMicroChunk);
|
||||
|
||||
// Save the current position
|
||||
int curpos = File->Seek(0);
|
||||
|
||||
// Seek back and write the micro chunk header
|
||||
File->Seek(MicroChunkPosition,SEEK_SET);
|
||||
if (File->Write(&MCHeader,sizeof(MCHeader)) != sizeof(MCHeader)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Go back to the end of the file
|
||||
File->Seek(curpos,SEEK_SET);
|
||||
InMicroChunk = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Write -- Write data into the current chunk *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkSaveClass::Write(const void * buf, uint32 nbytes)
|
||||
{
|
||||
// If this assert hits, you mixed data and chunks within the same chunk NO NO!
|
||||
assert(HeaderStack[StackIndex-1].Get_Sub_Chunk_Flag() == 0);
|
||||
|
||||
// If this assert hits, you didnt open any chunks yet
|
||||
assert(StackIndex > 0);
|
||||
|
||||
// write the bytes into the file
|
||||
if (File->Write(buf,nbytes) != (int)nbytes) return 0;
|
||||
|
||||
// track them in the wrapping chunk
|
||||
HeaderStack[StackIndex-1].Add_Size(nbytes);
|
||||
|
||||
// track them if you are using a micro-chunk too.
|
||||
if (InMicroChunk) {
|
||||
assert(MCHeader.Get_Size() < 255 - nbytes); // micro chunks can only be 255 bytes
|
||||
MCHeader.Add_Size(nbytes);
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Write -- write an IOVector2Struct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkSaveClass::Write(const IOVector2Struct & v)
|
||||
{
|
||||
return Write(&v,sizeof(v));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Write -- write an IOVector3Struct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkSaveClass::Write(const IOVector3Struct & v)
|
||||
{
|
||||
return Write(&v,sizeof(v));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Write -- write an IOVector4Struct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkSaveClass::Write(const IOVector4Struct & v)
|
||||
{
|
||||
return Write(&v,sizeof(v));
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Write -- write an IOQuaternionStruct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkSaveClass::Write(const IOQuaternionStruct & q)
|
||||
{
|
||||
return Write(&q,sizeof(q));
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkSaveClass::Cur_Chunk_Depth -- returns the current chunk recursion depth (debugging) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
int ChunkSaveClass::Cur_Chunk_Depth(void)
|
||||
{
|
||||
return StackIndex;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::ChunkLoadClass -- Constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
ChunkLoadClass::ChunkLoadClass(FileClass * file) :
|
||||
File(file),
|
||||
StackIndex(0),
|
||||
InMicroChunk(false),
|
||||
MicroChunkPosition(0)
|
||||
{
|
||||
memset(PositionStack,0,sizeof(PositionStack));
|
||||
memset(HeaderStack,0,sizeof(HeaderStack));
|
||||
memset(&MCHeader,0,sizeof(MCHeader));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Open_Chunk -- Open a chunk in the file, reads in the chunk header *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkLoadClass::Open_Chunk()
|
||||
{
|
||||
// if user didn't close any micro chunks that he opened, bad things could happen
|
||||
assert(InMicroChunk == false);
|
||||
|
||||
// check for stack overflow
|
||||
assert(StackIndex < MAX_STACK_DEPTH-1);
|
||||
|
||||
// if the parent chunk has been completely eaten, return false
|
||||
if ((StackIndex > 0) && (PositionStack[StackIndex-1] == HeaderStack[StackIndex-1].Get_Size())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the chunk header
|
||||
if (File->Read(&HeaderStack[StackIndex],sizeof(ChunkHeader)) != sizeof(ChunkHeader)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PositionStack[StackIndex] = 0;
|
||||
StackIndex++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Peek_Next_Chunk -- sneak peek into the next chunk that will be opened *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 3/4/2002 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkLoadClass::Peek_Next_Chunk(uint32 * set_id,uint32 * set_size)
|
||||
{
|
||||
// if user didn't close any micro chunks that he opened, bad things could happen
|
||||
assert(InMicroChunk == false);
|
||||
|
||||
// check for stack overflow
|
||||
assert(StackIndex < MAX_STACK_DEPTH-1);
|
||||
|
||||
// if the parent chunk has been completely eaten, return false
|
||||
if ((StackIndex > 0) && (PositionStack[StackIndex-1] == HeaderStack[StackIndex-1].Get_Size())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// peek at the next chunk header, return false if the read fails
|
||||
ChunkHeader temp_header;
|
||||
if (File->Read(&temp_header,sizeof(ChunkHeader)) != sizeof(ChunkHeader)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int seek_offset = sizeof(ChunkHeader);
|
||||
File->Seek(-seek_offset,SEEK_CUR);
|
||||
|
||||
if (set_id != NULL) {
|
||||
*set_id = temp_header.Get_Type();
|
||||
}
|
||||
if (set_size != NULL) {
|
||||
*set_size = temp_header.Get_Size();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Close_Chunk -- Close a chunk, seeks to the end if needed *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkLoadClass::Close_Chunk()
|
||||
{
|
||||
// if user didn't close any micro chunks that he opened, bad things could happen
|
||||
assert(InMicroChunk == false);
|
||||
|
||||
// check for stack overflow
|
||||
assert(StackIndex > 0);
|
||||
|
||||
int csize = HeaderStack[StackIndex-1].Get_Size();
|
||||
int pos = PositionStack[StackIndex-1];
|
||||
|
||||
if (pos < csize) {
|
||||
File->Seek(csize - pos,SEEK_CUR);
|
||||
}
|
||||
|
||||
StackIndex--;
|
||||
if (StackIndex > 0) {
|
||||
PositionStack[StackIndex - 1] += csize + sizeof(ChunkHeader);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Cur_Chunk_ID -- Returns the ID of the current chunk *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Cur_Chunk_ID()
|
||||
{
|
||||
assert(StackIndex >= 1);
|
||||
return HeaderStack[StackIndex-1].Get_Type();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Cur_Chunk_Length -- Returns the current length of the current chunk *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Cur_Chunk_Length()
|
||||
{
|
||||
assert(StackIndex >= 1);
|
||||
return HeaderStack[StackIndex-1].Get_Size();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Cur_Chunk_Depth -- returns the current chunk recursion depth *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
int ChunkLoadClass::Cur_Chunk_Depth()
|
||||
{
|
||||
return StackIndex;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Contains_Chunks -- Test whether the current chunk contains chunks (or data) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/24/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
int ChunkLoadClass::Contains_Chunks()
|
||||
{
|
||||
return HeaderStack[StackIndex-1].Get_Sub_Chunk_Flag();
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Open_Micro_Chunk -- reads in a micro-chunk header *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/3/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkLoadClass::Open_Micro_Chunk()
|
||||
{
|
||||
assert(!InMicroChunk);
|
||||
|
||||
// read the chunk header
|
||||
// calling the ChunkLoadClass::Read fn so that if we exhaust the chunk, the read will fail
|
||||
if (Read(&MCHeader,sizeof(MCHeader)) != sizeof(MCHeader)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InMicroChunk = true;
|
||||
MicroChunkPosition = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Close_Micro_Chunk -- closes a micro-chunk (seeks to end) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/3/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool ChunkLoadClass::Close_Micro_Chunk()
|
||||
{
|
||||
assert(InMicroChunk);
|
||||
InMicroChunk = false;
|
||||
|
||||
int csize = MCHeader.Get_Size();
|
||||
int pos = MicroChunkPosition;
|
||||
|
||||
// seek the file past this micro chunk
|
||||
if (pos < csize) {
|
||||
|
||||
File->Seek(csize - pos,SEEK_CUR);
|
||||
|
||||
// update the tracking variables for where we are in the normal chunk.
|
||||
if (StackIndex > 0) {
|
||||
PositionStack[StackIndex-1] += csize - pos;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Cur_Micro_Chunk_ID -- returns the ID of the current micro-chunk (asserts if *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Asserts if you are not currently inside a micro-chunk *
|
||||
* Micro chunks have an id between 0 and 255 *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/3/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Cur_Micro_Chunk_ID()
|
||||
{
|
||||
assert(InMicroChunk);
|
||||
return MCHeader.Get_Type();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Cur_Micro_Chunk_Length -- returns the size of the current micro chunk *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Asserts if you are not currently inside a micro-chunk *
|
||||
* Micro chunks have a maximum size of 255 bytes *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/3/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Cur_Micro_Chunk_Length()
|
||||
{
|
||||
assert(InMicroChunk);
|
||||
return MCHeader.Get_Size();
|
||||
}
|
||||
|
||||
// Seek over nbytes in the stream
|
||||
uint32 ChunkLoadClass::Seek(uint32 nbytes)
|
||||
{
|
||||
assert(StackIndex >= 1);
|
||||
|
||||
// Don't seek if we would go past the end of the current chunk
|
||||
if (PositionStack[StackIndex-1] + nbytes > (int)HeaderStack[StackIndex-1].Get_Size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Don't read if we are in a micro chunk and would go past the end of it
|
||||
if (InMicroChunk && MicroChunkPosition + nbytes > MCHeader.Get_Size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 curpos=File->Tell();
|
||||
if (File->Seek(nbytes,SEEK_CUR)-curpos != (int)nbytes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update our position in the chunk
|
||||
PositionStack[StackIndex-1] += nbytes;
|
||||
|
||||
// Update our position in the micro chunk if we are in one
|
||||
if (InMicroChunk) {
|
||||
MicroChunkPosition += nbytes;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Read -- Read data from the file *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/17/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Read(void * buf,uint32 nbytes)
|
||||
{
|
||||
assert(StackIndex >= 1);
|
||||
|
||||
// Don't read if we would go past the end of the current chunk
|
||||
if (PositionStack[StackIndex-1] + nbytes > (int)HeaderStack[StackIndex-1].Get_Size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Don't read if we are in a micro chunk and would go past the end of it
|
||||
if (InMicroChunk && MicroChunkPosition + nbytes > MCHeader.Get_Size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (File->Read(buf,nbytes) != (int)nbytes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Update our position in the chunk
|
||||
PositionStack[StackIndex-1] += nbytes;
|
||||
|
||||
// Update our position in the micro chunk if we are in one
|
||||
if (InMicroChunk) {
|
||||
MicroChunkPosition += nbytes;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Read -- read an IOVector2Struct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Read(IOVector2Struct * v)
|
||||
{
|
||||
assert(v != NULL);
|
||||
return Read(v,sizeof(v));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Read -- read an IOVector3Struct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Read(IOVector3Struct * v)
|
||||
{
|
||||
assert(v != NULL);
|
||||
return Read(v,sizeof(v));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Read -- read an IOVector4Struct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Read(IOVector4Struct * v)
|
||||
{
|
||||
assert(v != NULL);
|
||||
return Read(v,sizeof(v));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* ChunkLoadClass::Read -- read an IOQuaternionStruct *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/4/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
uint32 ChunkLoadClass::Read(IOQuaternionStruct * q)
|
||||
{
|
||||
assert(q != NULL);
|
||||
return Read(q,sizeof(q));
|
||||
}
|
||||
|
||||
384
Code/Tools/pluglib/chunkio.h
Normal file
384
Code/Tools/pluglib/chunkio.h
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
** 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/wwlib/chunkio.h 23 3/14/02 1:25p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Tiberian Sun / Commando / G Library *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/chunkio.h $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 3/04/02 3:41p $*
|
||||
* *
|
||||
* $Revision:: 23 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef CHUNKIO_H
|
||||
#define CHUNKIO_H
|
||||
|
||||
#ifndef ALWAYS_H
|
||||
#include "always.h"
|
||||
#endif
|
||||
|
||||
#ifndef BITTYPE_H
|
||||
#include "bittype.h"
|
||||
#endif
|
||||
|
||||
#ifndef WWFILE_H
|
||||
#include "wwfile.h"
|
||||
#endif
|
||||
|
||||
#ifndef IOSTRUCT_H
|
||||
#include "iostruct.h"
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
|
||||
ChunkIO
|
||||
|
||||
(gth) This module provides classes for reading and writing chunk-based files.
|
||||
For example, all of the w3d files are stored in a hierarchical-chunk format.
|
||||
Basically the format is similar to IFF. All data in the file has chunk headers
|
||||
wrapped around it. A chunk header contains an ID, and a Size. The size
|
||||
is the number of bytes in the chunk (not including the header). The
|
||||
contents of a chunk may be either: more "sub-chunks" or raw data. These classes
|
||||
will automatically keep track of your positions within all of the sub and parent
|
||||
chunks (to some maximum recursion depth).
|
||||
|
||||
Sept 3, 1999
|
||||
(gth) Adding the new concept of "micro-chunks". Instead of filling the contents of a
|
||||
chunk with data, you can fill it with "micro-chunks" which contain a single byte
|
||||
id and a single byte size. Micro-chunks are used for storing simple variables
|
||||
in a form that can survive revisions to the file format without paying the price
|
||||
for a full chunk header. You CANNOT recursively embed micro-chunks due to their
|
||||
size limitations....
|
||||
|
||||
Sept 24, 1999
|
||||
(gth) Using the MSB of the chunksize to indicate whether a chunk contains other
|
||||
chunks or pure data. If the MSB is 0, the chunk contains data (so that the reader
|
||||
I'm going to write doesn't break on older files) and if it is 1 then it is
|
||||
assumed to contain other chunks. This does not apply to micro-chunks as they
|
||||
are considered data.
|
||||
|
||||
**************************************************************************************/
|
||||
|
||||
struct ChunkHeader
|
||||
{
|
||||
// Functions.
|
||||
ChunkHeader() : ChunkType(0), ChunkSize(0) {}
|
||||
ChunkHeader(uint32 type, uint32 size) {ChunkType = type; ChunkSize = size;}
|
||||
|
||||
// Use these accessors to ensure you correctly deal with the data in the chunk header
|
||||
void Set_Type(uint32 type) { ChunkType = type; }
|
||||
uint32 Get_Type(void) { return ChunkType; }
|
||||
void Set_Size(uint32 size) { ChunkSize &= 0x80000000; ChunkSize |= (size & 0x7FFFFFFF); }
|
||||
void Add_Size(uint32 add) { Set_Size(Get_Size() + add); }
|
||||
uint32 Get_Size(void) { return (ChunkSize & 0x7FFFFFFF); }
|
||||
void Set_Sub_Chunk_Flag(bool onoff) { if (onoff) { ChunkSize |= 0x80000000; } else { ChunkSize &= 0x7FFFFFFF; } }
|
||||
int Get_Sub_Chunk_Flag(void) { return (ChunkSize & 0x80000000); }
|
||||
|
||||
// Chunk type and size.
|
||||
// Note: MSB of ChunkSize is used to indicate whether this chunk
|
||||
// contains other chunks or data.
|
||||
uint32 ChunkType;
|
||||
uint32 ChunkSize;
|
||||
};
|
||||
|
||||
struct MicroChunkHeader
|
||||
{
|
||||
MicroChunkHeader() {}
|
||||
MicroChunkHeader(uint8 type, uint8 size) { ChunkType = type, ChunkSize = size; }
|
||||
|
||||
void Set_Type(uint8 type) { ChunkType = type; }
|
||||
uint8 Get_Type(void) { return ChunkType; }
|
||||
void Set_Size(uint8 size) { ChunkSize = size; }
|
||||
void Add_Size(uint8 add) { Set_Size(Get_Size() + add); }
|
||||
uint8 Get_Size(void) { return ChunkSize; }
|
||||
|
||||
uint8 ChunkType;
|
||||
uint8 ChunkSize;
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
**
|
||||
** ChunkSaveClass
|
||||
** Wrap an instance of this class around an opened file for easy chunk
|
||||
** creation.
|
||||
**
|
||||
**************************************************************************************/
|
||||
class ChunkSaveClass
|
||||
{
|
||||
public:
|
||||
ChunkSaveClass(FileClass * file);
|
||||
|
||||
// Chunk methods
|
||||
bool Begin_Chunk(uint32 id);
|
||||
bool End_Chunk();
|
||||
int Cur_Chunk_Depth();
|
||||
|
||||
// Micro chunk methods
|
||||
bool Begin_Micro_Chunk(uint32 id);
|
||||
bool End_Micro_Chunk();
|
||||
|
||||
// Write data into the file
|
||||
uint32 Write(const void *buf, uint32 nbytes);
|
||||
uint32 Write(const IOVector2Struct & v);
|
||||
uint32 Write(const IOVector3Struct & v);
|
||||
uint32 Write(const IOVector4Struct & v);
|
||||
uint32 Write(const IOQuaternionStruct & q);
|
||||
|
||||
private:
|
||||
|
||||
enum { MAX_STACK_DEPTH = 256 };
|
||||
|
||||
FileClass * File;
|
||||
|
||||
// Chunk building support
|
||||
int StackIndex;
|
||||
int PositionStack[MAX_STACK_DEPTH];
|
||||
ChunkHeader HeaderStack[MAX_STACK_DEPTH];
|
||||
|
||||
// MicroChunk building support
|
||||
bool InMicroChunk;
|
||||
int MicroChunkPosition;
|
||||
MicroChunkHeader MCHeader;
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
**
|
||||
** ChunkLoadClass
|
||||
** wrap an instance of one of these objects around an opened file
|
||||
** to easily parse the chunks in the file
|
||||
**
|
||||
**************************************************************************************/
|
||||
class ChunkLoadClass
|
||||
{
|
||||
public:
|
||||
|
||||
ChunkLoadClass(FileClass * file);
|
||||
|
||||
// Chunk methods
|
||||
bool Open_Chunk();
|
||||
bool Close_Chunk();
|
||||
uint32 Cur_Chunk_ID();
|
||||
uint32 Cur_Chunk_Length();
|
||||
int Cur_Chunk_Depth();
|
||||
int Contains_Chunks();
|
||||
|
||||
// Micro Chunk methods
|
||||
bool Open_Micro_Chunk();
|
||||
bool Close_Micro_Chunk();
|
||||
uint32 Cur_Micro_Chunk_ID();
|
||||
uint32 Cur_Micro_Chunk_Length();
|
||||
|
||||
// Read a block of bytes from the output stream.
|
||||
uint32 Read(void *buf, uint32 nbytes);
|
||||
uint32 Read(IOVector2Struct * v);
|
||||
uint32 Read(IOVector3Struct * v);
|
||||
uint32 Read(IOVector4Struct * v);
|
||||
uint32 Read(IOQuaternionStruct * q);
|
||||
|
||||
// Seek over a block of bytes in the stream (same as Read but don't copy the data to a buffer)
|
||||
uint32 Seek(uint32 nbytes);
|
||||
|
||||
// Sneak peek at the next chunk that will be opened. Beware, if you need
|
||||
// this, then you are probably hacking so be careful!
|
||||
bool Peek_Next_Chunk(uint32 * set_id,uint32 * set_size);
|
||||
|
||||
private:
|
||||
|
||||
enum { MAX_STACK_DEPTH = 256 };
|
||||
|
||||
FileClass * File;
|
||||
|
||||
// Chunk reading support
|
||||
int StackIndex;
|
||||
uint32 PositionStack[MAX_STACK_DEPTH];
|
||||
ChunkHeader HeaderStack[MAX_STACK_DEPTH];
|
||||
|
||||
// Micro-chunk reading support
|
||||
bool InMicroChunk;
|
||||
int MicroChunkPosition;
|
||||
MicroChunkHeader MCHeader;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
** WRITE_WWSTRING_CHUNK - use this one-line macro to easily create a chunk to save a potentially
|
||||
** long string. Note: This macro does NOT create a micro chunk...
|
||||
** Example:
|
||||
**
|
||||
** csave.Begin_Chunk(CHUNKID_PARENT);
|
||||
** ParentClass::Save (csave);
|
||||
** csave.End_Chunk();
|
||||
**
|
||||
** WRITE_WWSTRING_CHUNK(csave, CHUNKID_NAME, string);
|
||||
** WRITE_WIDESTRING_CHUNK(csave, CHUNKID_WIDE_NAME, wide_string);
|
||||
**
|
||||
** csave.Begin_Chunk(PHYSGRID_CHUNK_VARIABLES);
|
||||
** WRITE_MICRO_CHUNK(csave,PHYSGRID_VARIABLE_VERSION,version);
|
||||
** WRITE_MICRO_CHUNK(csave,PHYSGRID_VARIABLE_DUMMYVISID,DummyVisId);
|
||||
** WRITE_MICRO_CHUNK(csave,PHYSGRID_VARIABLE_BASEVISID,BaseVisId);
|
||||
** csave.End_Chunk();
|
||||
**
|
||||
*/
|
||||
#define WRITE_WWSTRING_CHUNK(csave,id,var) { \
|
||||
csave.Begin_Chunk(id); \
|
||||
csave.Write((const TCHAR *)var, var.Get_Length () + 1); \
|
||||
csave.End_Chunk(); }
|
||||
|
||||
#define WRITE_WIDESTRING_CHUNK(csave,id,var) { \
|
||||
csave.Begin_Chunk(id); \
|
||||
csave.Write((const WCHAR *)var, (var.Get_Length () + 1) * 2); \
|
||||
csave.End_Chunk(); }
|
||||
|
||||
|
||||
/*
|
||||
** READ_WWSTRING_CHUNK - use this macro in a switch statement to read the contents
|
||||
** of a chunk into a string object.
|
||||
** Example:
|
||||
**
|
||||
** while (cload.Open_Chunk()) {
|
||||
**
|
||||
** switch(cload.Cur_Chunk_ID()) {
|
||||
** READ_WWSTRING_CHUNK(cload,CHUNKID_NAME,string);
|
||||
** READ_WIDESTRING_CHUNK(cload,CHUNKID_WIDE_NAME,wide_string);
|
||||
** }
|
||||
** cload.Close_Chunk();
|
||||
** }
|
||||
**
|
||||
*/
|
||||
#define READ_WWSTRING_CHUNK(cload,id,var) \
|
||||
case (id): cload.Read(var.Get_Buffer(cload.Cur_Chunk_Length()),cload.Cur_Chunk_Length()); break; \
|
||||
|
||||
#define READ_WIDESTRING_CHUNK(cload,id,var) \
|
||||
case (id): cload.Read(var.Get_Buffer((cload.Cur_Chunk_Length()+1)/2),cload.Cur_Chunk_Length()); break; \
|
||||
|
||||
|
||||
/*
|
||||
** WRITE_MICRO_CHUNK - use this one-line macro to easily make a micro chunk for an individual variable.
|
||||
** Note that you should always wrap your micro-chunks inside a normal chunk.
|
||||
** Example:
|
||||
**
|
||||
** csave.Begin_Chunk(PHYSGRID_CHUNK_VARIABLES);
|
||||
** WRITE_MICRO_CHUNK(csave,PHYSGRID_VARIABLE_VERSION,version);
|
||||
** WRITE_MICRO_CHUNK(csave,PHYSGRID_VARIABLE_DUMMYVISID,DummyVisId);
|
||||
** WRITE_MICRO_CHUNK(csave,PHYSGRID_VARIABLE_BASEVISID,BaseVisId);
|
||||
** csave.End_Chunk();
|
||||
*/
|
||||
#define WRITE_MICRO_CHUNK(csave,id,var) { \
|
||||
csave.Begin_Micro_Chunk(id); \
|
||||
csave.Write(&var,sizeof(var)); \
|
||||
csave.End_Micro_Chunk(); }
|
||||
|
||||
#define WRITE_SAFE_MICRO_CHUNK(csave,id,var,type) { \
|
||||
csave.Begin_Micro_Chunk(id); \
|
||||
type data = (type)var; \
|
||||
csave.Write(&data,sizeof(data)); \
|
||||
csave.End_Micro_Chunk(); }
|
||||
|
||||
#define WRITE_MICRO_CHUNK_STRING(csave,id,var) { \
|
||||
csave.Begin_Micro_Chunk(id); \
|
||||
csave.Write(var, strlen(var) + 1); \
|
||||
csave.End_Micro_Chunk(); }
|
||||
|
||||
#define WRITE_MICRO_CHUNK_WWSTRING(csave,id,var) { \
|
||||
csave.Begin_Micro_Chunk(id); \
|
||||
csave.Write((const TCHAR *)var, var.Get_Length () + 1); \
|
||||
csave.End_Micro_Chunk(); }
|
||||
|
||||
#define WRITE_MICRO_CHUNK_WIDESTRING(csave,id,var) { \
|
||||
csave.Begin_Micro_Chunk(id); \
|
||||
csave.Write((const WCHAR *)var, (var.Get_Length () + 1) * 2); \
|
||||
csave.End_Micro_Chunk(); }
|
||||
|
||||
|
||||
/*
|
||||
** READ_MICRO_CHUNK - use this macro in a switch statement to read a micro chunk into a variable
|
||||
** Example:
|
||||
**
|
||||
** while (cload.Open_Micro_Chunk()) {
|
||||
**
|
||||
** switch(cload.Cur_Micro_Chunk_ID()) {
|
||||
** READ_MICRO_CHUNK(cload,PHYSGRID_VARIABLE_VERSION,version);
|
||||
** READ_MICRO_CHUNK(cload,PHYSGRID_VARIABLE_DUMMYVISID,DummyVisId);
|
||||
** READ_MICRO_CHUNK(cload,PHYSGRID_VARIABLE_BASEVISID,BaseVisId);
|
||||
** }
|
||||
** cload.Close_Micro_Chunk();
|
||||
** }
|
||||
*/
|
||||
#define READ_MICRO_CHUNK(cload,id,var) \
|
||||
case (id): cload.Read(&var,sizeof(var)); break; \
|
||||
|
||||
/*
|
||||
** Like READ_MICRO_CHUNK but reads items straight into the data safe.
|
||||
*/
|
||||
#define READ_SAFE_MICRO_CHUNK(cload,id,var,type) \
|
||||
case (id): { \
|
||||
void *temp_read_buffer_on_the_stack = _alloca(sizeof(type)); \
|
||||
cload.Read(temp_read_buffer_on_the_stack, sizeof(type)); \
|
||||
var = *((type*)temp_read_buffer_on_the_stack); \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define READ_MICRO_CHUNK_STRING(cload,id,var,size) \
|
||||
case (id): WWASSERT(cload.Cur_Micro_Chunk_Length() <= size); cload.Read(var,cload.Cur_Micro_Chunk_Length()); break; \
|
||||
|
||||
#define READ_MICRO_CHUNK_WWSTRING(cload,id,var) \
|
||||
case (id): cload.Read(var.Get_Buffer(cload.Cur_Micro_Chunk_Length()),cload.Cur_Micro_Chunk_Length()); break; \
|
||||
|
||||
#define READ_MICRO_CHUNK_WIDESTRING(cload,id,var) \
|
||||
case (id): cload.Read(var.Get_Buffer((cload.Cur_Micro_Chunk_Length()+1)/2),cload.Cur_Micro_Chunk_Length()); break; \
|
||||
|
||||
/*
|
||||
** These load macros make it easier to add extra code to a specifc case
|
||||
*/
|
||||
#define LOAD_MICRO_CHUNK(cload,var) \
|
||||
cload.Read(&var,sizeof(var)); \
|
||||
|
||||
#define LOAD_MICRO_CHUNK_WWSTRING(cload,var) \
|
||||
cload.Read(var.Get_Buffer(cload.Cur_Micro_Chunk_Length()),cload.Cur_Micro_Chunk_Length()); \
|
||||
|
||||
#define LOAD_MICRO_CHUNK_WIDESTRING(cload,var) \
|
||||
cload.Read(var.Get_Buffer((cload.Cur_Micro_Chunk_Length()+1)/2),cload.Cur_Micro_Chunk_Length()); \
|
||||
|
||||
|
||||
/*
|
||||
** OBSOLETE_MICRO_CHUNK - use this macro in a switch statement when you want your code
|
||||
** to skip a given micro chunk but not fall through to your 'default' case statement which
|
||||
** prints an "unrecognized chunk" warning message.
|
||||
*/
|
||||
#define OBSOLETE_MICRO_CHUNK(id) \
|
||||
case (id): break;
|
||||
|
||||
|
||||
|
||||
#endif CHUNKIO_H
|
||||
88
Code/Tools/pluglib/errclass.h
Normal file
88
Code/Tools/pluglib/errclass.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
** 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/pluglib/errclass.h 5 6/25/99 10:46a Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando Tools - W3D export *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/pluglib/errclass.h $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 6/24/99 3:38p $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef ERRCLASS_H
|
||||
#define ERRCLASS_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
class ErrorClass
|
||||
{
|
||||
public:
|
||||
ErrorClass(char * format,...);
|
||||
ErrorClass(const ErrorClass & that);
|
||||
~ErrorClass(void) { if (error_message != NULL) free(error_message); }
|
||||
|
||||
ErrorClass & operator = (const ErrorClass & that);
|
||||
|
||||
char * error_message;
|
||||
};
|
||||
|
||||
inline ErrorClass::ErrorClass(char * format,...)
|
||||
{
|
||||
va_list va;
|
||||
char tmp[1024];
|
||||
va_start(va,format);
|
||||
vsprintf(tmp,format,va);
|
||||
assert(strlen(tmp) < 1024);
|
||||
va_end(va);
|
||||
error_message = strdup(tmp);
|
||||
}
|
||||
|
||||
inline ErrorClass::ErrorClass(const ErrorClass & that) :
|
||||
error_message(NULL)
|
||||
{
|
||||
*this = that;
|
||||
}
|
||||
|
||||
inline ErrorClass & ErrorClass::operator = (const ErrorClass & that)
|
||||
{
|
||||
if (error_message != NULL) {
|
||||
free(error_message);
|
||||
error_message = NULL;
|
||||
}
|
||||
|
||||
if (that.error_message != NULL) {
|
||||
error_message = strdup(that.error_message);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
#endif //ERRCLASS_H
|
||||
74
Code/Tools/pluglib/hashcalc.h
Normal file
74
Code/Tools/pluglib/hashcalc.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Westwood Library *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/hashcalc.h $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 4/02/99 11:59a $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
|
||||
#ifndef HASHCALC_H
|
||||
#define HASHCALC_H
|
||||
|
||||
|
||||
/*
|
||||
** HashCalculatorClass
|
||||
** The hash calculator is used to abstract the process of computing a hash
|
||||
** value for an object. Also, when dealing with floating point values, you
|
||||
** may need to have a fudge factor and therefore have several valid hash
|
||||
** values for a particular object (generated by adding and subtracting an
|
||||
** epsilon to the number(s)). This class lets you define any number
|
||||
** of hash values. This class is used by the UniqueArrayClass and the HashTableClass
|
||||
** templates. Basically, you give one of these to the UniqueArrayClass at
|
||||
** construction time. It will call the Num_Hash_Bits function in order to
|
||||
** properly allocate its hash table. Then, for each object you pass into the
|
||||
** Add function, it will call Compute_Hash, then it will loop through
|
||||
** Num_Hash_Values, calling Get_Hash_Value for each index and see if the object
|
||||
** is found in the indicated slot. Also, when it is checking to see if it has
|
||||
** the object you "Added", the Items_Match function is called. This again
|
||||
** allows you to do epsilon tests. Make sense?
|
||||
*/
|
||||
template <class T> class HashCalculatorClass
|
||||
{
|
||||
public:
|
||||
virtual bool Items_Match(const T & a, const T & b) = 0;
|
||||
virtual void Compute_Hash(const T & item) = 0;
|
||||
virtual int Num_Hash_Bits(void) = 0;
|
||||
virtual int Num_Hash_Values(void) = 0;
|
||||
virtual int Get_Hash_Value(int index = 0) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
191
Code/Tools/pluglib/hsv.cpp
Normal file
191
Code/Tools/pluglib/hsv.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Library/HSV.CPP $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 7/22/97 11:37a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* HSVClass::Adjust -- Adjust an HSV color toward specified color. *
|
||||
* HSVClass::Difference -- Finds the difference between two HSV color objects. *
|
||||
* HSVClass::operator RGBClass -- Conversion operator for RGBClass object. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "always.h"
|
||||
#include "hsv.h"
|
||||
#include "rgb.h"
|
||||
|
||||
HSVClass const HSVClass::BlackColor(0, 0, 0);
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* HSVClass::Adjust -- Adjust an HSV color toward specified color. *
|
||||
* *
|
||||
* This routine will adjust the HSV color object toward the color of the specified HSV *
|
||||
* object. Typical users of this would be palette morphing or fading routines. *
|
||||
* *
|
||||
* INPUT: ratio -- The ratio to move the HSV object toward the color specified. A value *
|
||||
* of zero means no movement at all. A value of 255 means move completely *
|
||||
* toward the specified color (changed completely). *
|
||||
* *
|
||||
* hsv -- A reference to the color that the current HSV object is to change *
|
||||
* toward. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/20/1996 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void HSVClass::Adjust(int ratio, HSVClass const & hsv)
|
||||
{
|
||||
/*
|
||||
** Ratio conversion is limited to 0 through 100%. This is
|
||||
** the range of 0 to 255.
|
||||
*/
|
||||
ratio &= 0x00FF;
|
||||
|
||||
/*
|
||||
** Adjust the color guns by the ratio specified toward the
|
||||
** destination color.
|
||||
*/
|
||||
int value = hsv.Get_Value() - Get_Value();
|
||||
Value = (unsigned char)(Get_Value() + (value * ratio) / 256);
|
||||
|
||||
int saturation = hsv.Get_Saturation() - Get_Saturation();
|
||||
Saturation = (unsigned char)(Get_Saturation() + (saturation * ratio) / 256);
|
||||
|
||||
int hue = hsv.Get_Hue() - Get_Hue();
|
||||
Hue = (unsigned char)(Get_Hue() + (hue * ratio) / 256);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* HSVClass::Difference -- Finds the difference between two HSV color objects. *
|
||||
* *
|
||||
* This routine will determine a color difference between two HSV objects. The difference *
|
||||
* has no particular meaning other that larger numbers meaning greater difference. *
|
||||
* *
|
||||
* INPUT: hsv -- The other HSV object to compare this HSV object to. *
|
||||
* *
|
||||
* OUTPUT: Returns with a relative distance (in arbitrary units) between this HSV object and *
|
||||
* the HSV object supplied. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/20/1996 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int HSVClass::Difference(HSVClass const & hsv) const
|
||||
{
|
||||
int hue = (int)Hue - (int)hsv.Hue;
|
||||
if (hue < 0) hue = -hue;
|
||||
|
||||
int saturation = (int)Saturation - (int)hsv.Saturation;
|
||||
if (saturation < 0) saturation = -saturation;
|
||||
|
||||
int value = (int)Value - (int)hsv.Value;
|
||||
if (value < 0) value = -value;
|
||||
|
||||
return(hue*hue + saturation*saturation + value*value);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* HSVClass::operator RGBClass -- Conversion operator for RGBClass object. *
|
||||
* *
|
||||
* This conversion operator will convert the HSV object into an RGB object. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: Returns with a reference (implied) of the RGBClass object that most closely *
|
||||
* matches this HSVClass object. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/20/1996 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
HSVClass::operator RGBClass (void) const
|
||||
{
|
||||
unsigned int i; // Integer part.
|
||||
unsigned int f; // Fractional or remainder part. f/HSV_BASE gives fraction.
|
||||
unsigned int tmp; // Temporary variable to help with calculations.
|
||||
unsigned int values[7]; // Possible rgb values. Don't use zero.
|
||||
|
||||
int hue = Get_Hue();
|
||||
int saturation = Get_Saturation();
|
||||
int value = Get_Value();
|
||||
int red, green, blue;
|
||||
|
||||
|
||||
hue *= 6;
|
||||
f = hue % 255;
|
||||
|
||||
// Set up possible red, green and blue values.
|
||||
values[1] =
|
||||
values[2] = value;
|
||||
|
||||
//
|
||||
// The following lines of code change
|
||||
// values[3] = (v * (255 - ( (s * f) / 255) )) / 255;
|
||||
// values[4] = values[5] = (v * (255 - s)) / 255;
|
||||
// values[6] = (v * (255 - (s * (255 - f)) / 255)) / 255;
|
||||
// so that the are rounded divides.
|
||||
//
|
||||
|
||||
tmp = (saturation * f) / 255;
|
||||
values[3] = (value * (255 - tmp)) / 255;
|
||||
|
||||
values[4] =
|
||||
values[5] = (value * (255 - saturation)) / 255;
|
||||
|
||||
tmp = 255 - (saturation * (255 - f)) / 255;
|
||||
values[6] = (value * tmp) / 255;
|
||||
|
||||
|
||||
// This should not be rounded.
|
||||
i = hue / 255;
|
||||
|
||||
i += (i > 4) ? -4 : 2;
|
||||
red = values[i];
|
||||
|
||||
i += (i > 4) ? -4 : 2;
|
||||
blue = values[i];
|
||||
|
||||
i += (i > 4) ? -4 : 2;
|
||||
green = values[i];
|
||||
|
||||
RGBClass rgb((unsigned char)red, (unsigned char)green, (unsigned char)blue);
|
||||
return(rgb);
|
||||
}
|
||||
|
||||
|
||||
81
Code/Tools/pluglib/hsv.h
Normal file
81
Code/Tools/pluglib/hsv.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Library/HSV.H $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 7/22/97 11:37a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef HSV_H
|
||||
#define HSV_H
|
||||
|
||||
class RGBClass;
|
||||
class HSVClass;
|
||||
|
||||
/*
|
||||
** Each color entry is represented by this class. It holds the values for the color
|
||||
** attributes. The values are recorded in a range from 0 to 255 with 255 being the
|
||||
** maximum.
|
||||
*/
|
||||
class HSVClass
|
||||
{
|
||||
private:
|
||||
static HSVClass const BlackColor;
|
||||
|
||||
public:
|
||||
HSVClass(void) : Hue(0), Saturation(0), Value(0) {};
|
||||
HSVClass(unsigned char hue, unsigned char saturation, unsigned char value) :
|
||||
Hue(hue),
|
||||
Saturation(saturation),
|
||||
Value(value)
|
||||
{};
|
||||
operator RGBClass (void) const;
|
||||
|
||||
enum {
|
||||
MAX_VALUE=255
|
||||
};
|
||||
|
||||
void Adjust(int ratio, HSVClass const & hsv);
|
||||
int Difference(HSVClass const & hsv) const;
|
||||
int Get_Hue(void) const {return(Hue);};
|
||||
int Get_Saturation(void) const {return(Saturation);};
|
||||
int Get_Value(void) const {return(Value);};
|
||||
void Set_Hue(unsigned char value) {Hue = value;}
|
||||
void Set_Saturation(unsigned char value) {Saturation = value;}
|
||||
void Set_Value(unsigned char value) {Value = value;}
|
||||
|
||||
private:
|
||||
unsigned char Hue;
|
||||
unsigned char Saturation;
|
||||
unsigned char Value;
|
||||
};
|
||||
|
||||
#endif
|
||||
85
Code/Tools/pluglib/iostruct.h
Normal file
85
Code/Tools/pluglib/iostruct.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : WWLib *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/iostruct.h $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 4/02/99 11:59a $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef IOSTRUCT_H
|
||||
#define IOSTRUCT_H
|
||||
|
||||
#ifndef BITTYPE_H
|
||||
#include "bittype.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Some useful structures for writing/writing (safe from changes).
|
||||
** The chunk IO classes contain code for reading and writing these.
|
||||
*/
|
||||
struct IOVector2Struct
|
||||
{
|
||||
float32 X;
|
||||
float32 Y;
|
||||
};
|
||||
|
||||
struct IOVector3Struct
|
||||
{
|
||||
float32 X; // X,Y,Z coordinates
|
||||
float32 Y;
|
||||
float32 Z;
|
||||
};
|
||||
|
||||
struct IOVector4Struct
|
||||
{
|
||||
float32 X;
|
||||
float32 Y;
|
||||
float32 Z;
|
||||
float32 W;
|
||||
};
|
||||
|
||||
struct IOQuaternionStruct
|
||||
{
|
||||
float32 Q[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
162
Code/Tools/pluglib/jshell.cpp
Normal file
162
Code/Tools/pluglib/jshell.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/Tools/pluglib/jshell.cpp $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 11/07/00 2:32p $*
|
||||
* *
|
||||
* $Revision:: 28 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Fatal -- General purpose fatal error handler. *
|
||||
* Set_Bit -- Set bit in a bit array. *
|
||||
* Get_Bit -- Fetch the bit value from a bit array. *
|
||||
* First_True_Bit -- Return with the first true bit index. *
|
||||
* First_False_Bit -- Find the first false bit in the bit array. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "always.h"
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Set_Bit -- Set bit in a bit array. *
|
||||
* *
|
||||
* This routine is used to set (or clear) a bit in a bit array. *
|
||||
* *
|
||||
* INPUT: array -- Pointer to the bit array. *
|
||||
* *
|
||||
* bit -- The bit number to set. I.e., bit 32 is the first bit in the second *
|
||||
* long word of memory. *
|
||||
* *
|
||||
* value -- The value to set the bit. The only values supported are 0 and 1. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: Be sure that the array is big enough to set the specified bit. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/06/1997 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void Set_Bit(void * array, int bit, int value)
|
||||
{
|
||||
unsigned char mask = (unsigned char)(1 << (bit % 8));
|
||||
|
||||
if (value != 0) {
|
||||
*((unsigned char *)array + (bit/8)) |= mask;
|
||||
} else {
|
||||
*((unsigned char *)array + (bit/8)) &= (unsigned char)~mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Get_Bit -- Fetch the bit value from a bit array. *
|
||||
* *
|
||||
* This routine will fetch the specified bit value from the bit array. This is the *
|
||||
* counterpart function to the Set_Bit() function. *
|
||||
* *
|
||||
* INPUT: array -- Pointer to the bit array to fetch the bit value from. *
|
||||
* *
|
||||
* bit -- The bit number to fetch. *
|
||||
* *
|
||||
* OUTPUT: Returns with the value of the bit. This return value will be either 1 or 0. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/06/1997 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int Get_Bit(void const * array, int bit)
|
||||
{
|
||||
unsigned char mask = (unsigned char)(1 << (bit % 8));
|
||||
return((*((unsigned char *)array + (bit/8)) & mask) != 0);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* First_True_Bit -- Return with the first true bit index. *
|
||||
* *
|
||||
* This routine will scan the bit array and return with the index for the first true bit *
|
||||
* in the array. *
|
||||
* *
|
||||
* INPUT: array -- Pointer to the bit array to scan. *
|
||||
* *
|
||||
* OUTPUT: Returns with the index of the first true (set to 1) bit in the array. *
|
||||
* *
|
||||
* WARNINGS: This routine does not stop at the end of the array (it doesn't know where the *
|
||||
* end is) so there must be at least one true bit in the array or else it will *
|
||||
* end up scanning past the end (undefined results in that case). *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/06/1997 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int First_True_Bit(void const * array)
|
||||
{
|
||||
int index = 0;
|
||||
while (*((unsigned char *)array) == 0) {
|
||||
index++;
|
||||
array = ((char*)array) + 1;
|
||||
}
|
||||
int subindex;
|
||||
for (subindex = 0; subindex < 8; subindex++) {
|
||||
if (Get_Bit(array, subindex)) break;
|
||||
}
|
||||
return(index * 8 + subindex);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* First_False_Bit -- Find the first false bit in the bit array. *
|
||||
* *
|
||||
* This routine will scan the bit array and return with the index of the first false (set *
|
||||
* to 0) bit found. *
|
||||
* *
|
||||
* INPUT: array -- Pointer to the bit array to scan. *
|
||||
* *
|
||||
* OUTPUT: Returns with the index of the first false bit found in the array. *
|
||||
* *
|
||||
* WARNINGS: This routine will not stop scanning until a false bit was found. This means *
|
||||
* that there must be at least one false bit in the array or else it will scan *
|
||||
* past the end of the array. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/06/1997 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int First_False_Bit(void const * array)
|
||||
{
|
||||
int index = 0;
|
||||
while (*((unsigned char *)array) == 0xFF) {
|
||||
index++;
|
||||
array = ((char*)array) + 1;
|
||||
}
|
||||
int subindex;
|
||||
for (subindex = 0; subindex < 8; subindex++) {
|
||||
if (!Get_Bit(array, subindex)) break;
|
||||
}
|
||||
return(index * 8 + subindex);
|
||||
}
|
||||
|
||||
841
Code/Tools/pluglib/matrix3d.cpp
Normal file
841
Code/Tools/pluglib/matrix3d.cpp
Normal file
@@ -0,0 +1,841 @@
|
||||
/*
|
||||
** 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/matrix3d.cpp 39 2/03/00 4:55p Jason_a $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Voxel Technology *
|
||||
* *
|
||||
* File Name : MATRIX3D.CPP *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 02/24/97 *
|
||||
* *
|
||||
* Last Update : February 28, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Matrix3D::Set_Rotation -- Sets the rotation part of the matrix *
|
||||
* Matrix3D::Set_Rotation -- Sets the rotation part of the matrix *
|
||||
* Matrix3D::Set -- Init a matrix3D from a matrix3 and a position *
|
||||
* Matrix3D::Set -- Init a matrix3D from a quaternion and a position *
|
||||
* Matrix3D::Get_X_Rotation -- approximates the rotation about the X axis *
|
||||
* Matrix3D::Get_Y_Rotation -- approximates the rotation about the Y axis *
|
||||
* Matrix3D::Get_Z_Rotation -- approximates the rotation about the Z axis *
|
||||
* Matrix3D::Multiply -- matrix multiplication without temporaries. *
|
||||
* Matrix3D::Inverse_Rotate_Vector -- rotates a vector by the inverse of the 3x3 sub-matrix *
|
||||
* Matrix3D::Transform_Min_Max_AABox -- compute transformed axis-aligned box *
|
||||
* Matrix3D::Transform_Center_Extent_AABox -- compute transformed axis-aligned box *
|
||||
* Matrix3D::Get_Inverse -- calculate the inverse of this matrix *
|
||||
* Matrix3D::Get_Orthogonal_Inverse -- Returns the inverse of the matrix *
|
||||
* Matrix3D::Re_Orthogonalize -- makes this matrix orthogonal. *
|
||||
* Matrix3D::Is_Orthogonal -- checks whether this matrix is orthogonal *
|
||||
* Lerp - linearly interpolate matrices (orientation is slerped) *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "matrix3d.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
#include "vector3.h"
|
||||
#include "wwmatrix3.h"
|
||||
#include "matrix4.h"
|
||||
#include "w3dquat.h"
|
||||
|
||||
// some static matrices which are sometimes useful
|
||||
const Matrix3D Matrix3D::Identity
|
||||
(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateX90
|
||||
(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, -1.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateX180
|
||||
(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
0.0, 0.0, -1.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateX270
|
||||
(
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateY90
|
||||
(
|
||||
0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
-1.0, 0.0, 0.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateY180
|
||||
(
|
||||
-1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, -1.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateY270
|
||||
(
|
||||
0.0, 0.0, -1.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateZ90
|
||||
(
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateZ180
|
||||
(
|
||||
-1.0, 0.0, 0.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0
|
||||
);
|
||||
|
||||
const Matrix3D Matrix3D::RotateZ270
|
||||
(
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
-1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0, 0.0
|
||||
);
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Set -- Init a matrix3D from a matrix3 and a position *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Set(const Matrix3 & rot,const Vector3 & pos)
|
||||
{
|
||||
Row[0].Set( rot[0][0], rot[0][1], rot[0][2], pos[0]);
|
||||
Row[1].Set( rot[1][0], rot[1][1], rot[1][2], pos[1]);
|
||||
Row[2].Set( rot[2][0], rot[2][1], rot[2][2], pos[2]);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Set -- Init a matrix3D from a quaternion and a position *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Set(const Quaternion & rot,const Vector3 & pos)
|
||||
{
|
||||
Set_Rotation(rot);
|
||||
Set_Translation(pos);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Set_Rotation -- Sets the rotation part of the matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 5/11/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Set_Rotation(const Matrix3 & m)
|
||||
{
|
||||
Row[0][0] = m[0][0];
|
||||
Row[0][1] = m[0][1];
|
||||
Row[0][2] = m[0][2];
|
||||
|
||||
Row[1][0] = m[1][0];
|
||||
Row[1][1] = m[1][1];
|
||||
Row[1][2] = m[1][2];
|
||||
|
||||
Row[2][0] = m[2][0];
|
||||
Row[2][1] = m[2][1];
|
||||
Row[2][2] = m[2][2];
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Set_Rotation -- Sets the rotation part of the matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 5/11/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Set_Rotation(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]));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Get_X_Rotation -- approximates the rotation about the X axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/11/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
float Matrix3D::Get_X_Rotation(void) const
|
||||
{
|
||||
return atan2(Row[2][1], Row[1][1]);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Get_Y_Rotation -- approximates the rotation about the Y axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/11/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
float Matrix3D::Get_Y_Rotation(void) const
|
||||
{
|
||||
return atan2(Row[0][2], Row[2][2]);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Get_Z_Rotation -- approximates the rotation about the Z axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/11/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
float Matrix3D::Get_Z_Rotation(void) const
|
||||
{
|
||||
return atan2(Row[1][0], Row[0][0]);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* M3DC::Rotate_Vector -- Uses the 3x3 sub-matrix to rotate a vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
Vector3 Matrix3D::Rotate_Vector(const Vector3 &vect) const
|
||||
{
|
||||
return Vector3(
|
||||
(Row[0][0]*vect[0] + Row[0][1]*vect[1] + Row[0][2]*vect[2]),
|
||||
(Row[1][0]*vect[0] + Row[1][1]*vect[1] + Row[1][2]*vect[2]),
|
||||
(Row[2][0]*vect[0] + Row[2][1]*vect[1] + Row[2][2]*vect[2])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Inverse_Rotate_Vector -- rotates a vector by the inverse of the 3x3 sub-matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 4/27/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
Vector3 Matrix3D::Inverse_Rotate_Vector(const Vector3 &vect) const
|
||||
{
|
||||
return Vector3(
|
||||
(Row[0][0]*vect[0] + Row[1][0]*vect[1] + Row[2][0]*vect[2]),
|
||||
(Row[0][1]*vect[0] + Row[1][1]*vect[1] + Row[2][1]*vect[2]),
|
||||
(Row[0][2]*vect[0] + Row[1][2]*vect[1] + Row[2][2]*vect[2])
|
||||
);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* M3DC::Look_At -- Creates a "look at" transformation. *
|
||||
* *
|
||||
* Builds a transformation matrix which positions the origin at p, *
|
||||
* points the negative z-axis towards a target t, and rolls about the z-axis *
|
||||
* by the angle specified by roll. *
|
||||
* *
|
||||
* This can be useful for creating a camera matrix, just invert *
|
||||
* the matrix after initializing it with this function... *
|
||||
* *
|
||||
* INPUT: *
|
||||
* p - position of the coordinate system *
|
||||
* t - target of the coordinate system *
|
||||
* roll - roll angle (in radians) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* This function is written assuming the convention that the "ground" is the X-Y plane and *
|
||||
* Z is altitude. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Look_At(const Vector3 &p,const Vector3 &t,float roll)
|
||||
{
|
||||
float dx,dy,dz; //vector from p to t
|
||||
float len1,len2;
|
||||
float sinp,cosp; //sine and cosine of the pitch ("up-down" tilt about x)
|
||||
float siny,cosy; //sine and cosine of the yaw ("left-right"tilt about z)
|
||||
|
||||
dx = (t[0] - p[0]);
|
||||
dy = (t[1] - p[1]);
|
||||
dz = (t[2] - p[2]);
|
||||
|
||||
len1 = (float)WWMath::Sqrt(dx*dx + dy*dy + dz*dz);
|
||||
len2 = (float)WWMath::Sqrt(dx*dx + dy*dy);
|
||||
|
||||
if (len1 != 0.0f) {
|
||||
sinp = dz/len1;
|
||||
cosp = len2/len1;
|
||||
} else {
|
||||
sinp = 0.0f;
|
||||
cosp = 1.0f;
|
||||
}
|
||||
|
||||
if (len2 != 0.0f) {
|
||||
siny = dy/len2;
|
||||
cosy = dx/len2;
|
||||
} else {
|
||||
siny = 0.0f;
|
||||
cosy = 1.0f;
|
||||
}
|
||||
|
||||
// init the matrix with position p and -z pointing down +x and +y up
|
||||
Row[0].X = 0.0f; Row[0].Y = 0.0f; Row[0].Z = -1.0f;
|
||||
Row[1].X = -1.0f; Row[1].Y = 0.0f; Row[1].Z = 0.0f;
|
||||
Row[2].X = 0.0f; Row[2].Y = 1.0f; Row[2].Z = 0.0f;
|
||||
|
||||
Row[0].W = p.X;
|
||||
Row[1].W = p.Y;
|
||||
Row[2].W = p.Z;
|
||||
|
||||
// Yaw rotation to make the matrix look at the projection of the target
|
||||
// into the x-y plane
|
||||
Rotate_Y(siny,cosy);
|
||||
|
||||
// rotate about local x axis to pitch up to the targets position
|
||||
Rotate_X(sinp,cosp);
|
||||
|
||||
// roll about the local z axis (negate since we look down -z)
|
||||
Rotate_Z(-roll);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* M3DC::Obj_Look_At -- Commando Object "look at" transformation. *
|
||||
* *
|
||||
* Builds a transformation matrix which positions the origin at p, *
|
||||
* points the positive X axis towards a target t, and rolls about the X axis *
|
||||
* by the angle specified by roll. *
|
||||
* *
|
||||
* The object convention used by Commando and G is Forward = +X, Left = +Y, Up = +Z. The *
|
||||
* world is basically the x-y plane with z as altitude and +x is the default "forward". *
|
||||
* *
|
||||
* INPUT: *
|
||||
* p - position of the coordinate system *
|
||||
* t - target of the coordinate system *
|
||||
* roll - roll angle (in radians) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Obj_Look_At(const Vector3 &p,const Vector3 &t,float roll)
|
||||
{
|
||||
float dx,dy,dz; //vector from p to t
|
||||
float len1,len2;
|
||||
float sinp,cosp; //sine and cosine of the pitch ("up-down" tilt about y)
|
||||
float siny,cosy; //sine and cosine of the yaw ("left-right"tilt about z)
|
||||
|
||||
dx = (t[0] - p[0]);
|
||||
dy = (t[1] - p[1]);
|
||||
dz = (t[2] - p[2]);
|
||||
|
||||
len1 = (float)sqrt(dx*dx + dy*dy + dz*dz);
|
||||
len2 = (float)sqrt(dx*dx + dy*dy);
|
||||
|
||||
if (len1 != 0.0f) {
|
||||
sinp = dz/len1;
|
||||
cosp = len2/len1;
|
||||
} else {
|
||||
sinp = 0.0f;
|
||||
cosp = 1.0f;
|
||||
}
|
||||
|
||||
if (len2 != 0.0f) {
|
||||
siny = dy/len2;
|
||||
cosy = dx/len2;
|
||||
} else {
|
||||
siny = 0.0f;
|
||||
cosy = 1.0f;
|
||||
}
|
||||
|
||||
Make_Identity();
|
||||
Translate(p);
|
||||
|
||||
// Yaw rotation to projection of target in x-y plane
|
||||
Rotate_Z(siny,cosy);
|
||||
|
||||
// Pitch rotation
|
||||
Rotate_Y(-sinp,cosp);
|
||||
|
||||
// Roll rotation
|
||||
Rotate_X(roll);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Get_Inverse -- calculate the inverse of this matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 8/7/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Get_Inverse(Matrix3D & inv) const
|
||||
{
|
||||
// TODO: Implement the general purpose inverse function here (once we need it :-)
|
||||
Get_Orthogonal_Inverse(inv);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Get_Orthogonal_Inverse -- Returns the inverse of the matrix *
|
||||
* *
|
||||
* NOTE!!! This only works if the matrix is really ORTHOGONAL!!! *
|
||||
* *
|
||||
***********************************************************************************************
|
||||
* Inverting an orthogonal Matrix3D *
|
||||
* *
|
||||
* M is the original transform, *
|
||||
* R is rotation submatrix, *
|
||||
* T is translation vector in M. *
|
||||
* *
|
||||
* To build MINV *
|
||||
* *
|
||||
* R' = transpose of R (inverse of orthogonal 3x3 matrix is transpose) *
|
||||
* T' = -R'T *
|
||||
* *
|
||||
* Build MINV with R'and T' *
|
||||
* MINV is the inverse of M *
|
||||
* *
|
||||
***********************************************************************************************
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Get_Orthogonal_Inverse(Matrix3D & inv) const
|
||||
{
|
||||
// Transposing the rotation submatrix
|
||||
inv.Row[0][0] = Row[0][0];
|
||||
inv.Row[0][1] = Row[1][0];
|
||||
inv.Row[0][2] = Row[2][0];
|
||||
|
||||
inv.Row[1][0] = Row[0][1];
|
||||
inv.Row[1][1] = Row[1][1];
|
||||
inv.Row[1][2] = Row[2][1];
|
||||
|
||||
inv.Row[2][0] = Row[0][2];
|
||||
inv.Row[2][1] = Row[1][2];
|
||||
inv.Row[2][2] = Row[2][2];
|
||||
|
||||
// Now, calculate translation portion of matrix:
|
||||
// T' = -R'T
|
||||
Vector3 trans = Get_Translation();
|
||||
trans = inv.Rotate_Vector(trans);
|
||||
trans = -trans;
|
||||
|
||||
inv.Row[0][3] = trans[0];
|
||||
inv.Row[1][3] = trans[1];
|
||||
inv.Row[2][3] = trans[2];
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Copy_3x3_Matrix(float *matrix) -- Copies a 3x3 (float[9]) matrix into this matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/16/98 EHC : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Copy_3x3_Matrix(float matrix[3][3])
|
||||
{
|
||||
Row[0][0] = matrix[0][0];
|
||||
Row[0][1] = matrix[0][1];
|
||||
Row[0][2] = matrix[0][2];
|
||||
Row[0][3] = 0;
|
||||
Row[1][0] = matrix[1][0];
|
||||
Row[1][1] = matrix[1][1];
|
||||
Row[1][2] = matrix[1][2];
|
||||
Row[1][3] = 0;
|
||||
Row[2][0] = matrix[2][0];
|
||||
Row[2][1] = matrix[2][1];
|
||||
Row[2][2] = matrix[2][2];
|
||||
Row[2][3] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Multiply -- matrix multiplication without temporaries. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 4/22/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
//void print_matrix(const Matrix3D & m);
|
||||
void Matrix3D::Multiply(const Matrix3D & A,const Matrix3D & B,Matrix3D * set_res)
|
||||
{
|
||||
assert(set_res != NULL);
|
||||
|
||||
Matrix3D tmp;
|
||||
Matrix3D * 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 = (Matrix3D *)&A;
|
||||
}
|
||||
|
||||
tmp1 = B[0][0];
|
||||
tmp2 = B[1][0];
|
||||
tmp3 = B[2][0];
|
||||
|
||||
(*set_res)[0][0] = (*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3;
|
||||
(*set_res)[1][0] = (*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3;
|
||||
(*set_res)[2][0] = (*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] = (*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3;
|
||||
(*set_res)[1][1] = (*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3;
|
||||
(*set_res)[2][1] = (*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] = (*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3;
|
||||
(*set_res)[1][2] = (*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3;
|
||||
(*set_res)[2][2] = (*Aptr)[2][0]*tmp1 + (*Aptr)[2][1]*tmp2 + (*Aptr)[2][2]*tmp3;
|
||||
|
||||
tmp1 = B[0][3];
|
||||
tmp2 = B[1][3];
|
||||
tmp3 = B[2][3];
|
||||
|
||||
(*set_res)[0][3] = (*Aptr)[0][0]*tmp1 + (*Aptr)[0][1]*tmp2 + (*Aptr)[0][2]*tmp3 + (*Aptr)[0][3];
|
||||
(*set_res)[1][3] = (*Aptr)[1][0]*tmp1 + (*Aptr)[1][1]*tmp2 + (*Aptr)[1][2]*tmp3 + (*Aptr)[1][3];
|
||||
(*set_res)[2][3] = (*Aptr)[2][0]*tmp1 + (*Aptr)[2][1]*tmp2 + (*Aptr)[2][2]*tmp3 + (*Aptr)[2][3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Transform_Min_Max_AABox -- compute transformed axis-aligned box *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 7/17/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Transform_Min_Max_AABox
|
||||
(
|
||||
const Vector3 & min,
|
||||
const Vector3 & max,
|
||||
Vector3 * set_min,
|
||||
Vector3 * set_max
|
||||
) const
|
||||
{
|
||||
assert(set_min != &min);
|
||||
assert(set_max != &max);
|
||||
|
||||
float tmp0,tmp1;
|
||||
|
||||
// init the min and max to the translation of the transform
|
||||
set_min->X = set_max->X = Row[0][3];
|
||||
set_min->Y = set_max->Y = Row[1][3];
|
||||
set_min->Z = set_max->Z = Row[2][3];
|
||||
|
||||
// now push them both out by the projections of the original intervals
|
||||
for (int i=0; i<3; i++) {
|
||||
|
||||
for (int j=0; j<3; j++) {
|
||||
|
||||
tmp0 = Row[i][j] * min[j];
|
||||
tmp1 = Row[i][j] * max[j];
|
||||
|
||||
if (tmp0 < tmp1) {
|
||||
|
||||
(*set_min)[i] += tmp0;
|
||||
(*set_max)[i] += tmp1;
|
||||
|
||||
} else {
|
||||
|
||||
(*set_min)[i] += tmp1;
|
||||
(*set_max)[i] += tmp0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Transform_Center_Extent_AABox -- compute transformed axis-aligned box *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 7/17/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::Transform_Center_Extent_AABox
|
||||
(
|
||||
const Vector3 & center,
|
||||
const Vector3 & extent,
|
||||
Vector3 * set_center,
|
||||
Vector3 * set_extent
|
||||
) const
|
||||
{
|
||||
assert(set_center != ¢er);
|
||||
assert(set_extent != &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_center)[i] = Row[i][3];
|
||||
(*set_extent)[i] = 0.0f;
|
||||
|
||||
for (int j=0; j<3; j++) {
|
||||
|
||||
(*set_center)[i] += Row[i][j] * center[j];
|
||||
(*set_extent)[i] += WWMath::Fabs(Row[i][j] * extent[j]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Is_Orthogonal -- checks whether this matrix is orthogonal *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/16/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
int Matrix3D::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;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix3D::Re_Orthogonalize -- makes this matrix orthogonal. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* This function is rather expensive, should only be used if you *know* numerical error is *
|
||||
* killing you. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 9/16/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix3D::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 *= 1.0f/len;
|
||||
}
|
||||
|
||||
len = y.Length();
|
||||
if (len < WWMATH_EPSILON) {
|
||||
Make_Identity();
|
||||
return;
|
||||
} else {
|
||||
y *= 1.0f/len;
|
||||
}
|
||||
|
||||
len = z.Length();
|
||||
if (len < WWMATH_EPSILON) {
|
||||
Make_Identity();
|
||||
return;
|
||||
} else {
|
||||
z *= 1.0f/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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Lerp - linearly interpolate matrices (orientation is slerped) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/05/1998 NH : Created. *
|
||||
*=============================================================================================*/
|
||||
Matrix3D Lerp(const Matrix3D &A, const Matrix3D &B, float factor)
|
||||
{
|
||||
assert(factor >= 0.0f);
|
||||
assert(factor <= 1.0f);
|
||||
|
||||
// Lerp position
|
||||
Vector3 pos = Lerp(A.Get_Translation(), B.Get_Translation(), factor);
|
||||
Quaternion rot = Slerp(Build_Quaternion(A), Build_Quaternion(B), factor);
|
||||
return Matrix3D(rot, pos);
|
||||
}
|
||||
|
||||
1516
Code/Tools/pluglib/matrix3d.h
Normal file
1516
Code/Tools/pluglib/matrix3d.h
Normal file
File diff suppressed because it is too large
Load Diff
174
Code/Tools/pluglib/matrix4.cpp
Normal file
174
Code/Tools/pluglib/matrix4.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/matrix4.cpp $*
|
||||
* *
|
||||
* Author:: Greg_h *
|
||||
* *
|
||||
* $Modtime:: 11/13/99 10:50a $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Matrix4::Multiply -- Multiply two Matrix4's together *
|
||||
* Matrix4::Multiply -- Multiply a Matrix3D * Matrix4 *
|
||||
* Matrix4::Multiply -- Multiply a Matrix4 * Matrix3D *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "matrix4.h"
|
||||
#include <assert.h>
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Multiply -- Multiply two Matrix4's together *
|
||||
* *
|
||||
* INPUT: *
|
||||
* a - first operand *
|
||||
* b - second operand *
|
||||
* res - pointer to matrix to store the result in (must not point to a or b) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix4::Multiply(const Matrix4 &a,const Matrix4 &b,Matrix4 * res)
|
||||
{
|
||||
assert(res != &a);
|
||||
assert(res != &b);
|
||||
|
||||
#define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j]
|
||||
|
||||
(*res)[0][0] = ROWCOL(0,0);
|
||||
(*res)[0][1] = ROWCOL(0,1);
|
||||
(*res)[0][2] = ROWCOL(0,2);
|
||||
(*res)[0][3] = ROWCOL(0,3);
|
||||
|
||||
(*res)[1][0] = ROWCOL(1,0);
|
||||
(*res)[1][1] = ROWCOL(1,1);
|
||||
(*res)[1][2] = ROWCOL(1,2);
|
||||
(*res)[1][3] = ROWCOL(1,3);
|
||||
|
||||
(*res)[2][0] = ROWCOL(2,0);
|
||||
(*res)[2][1] = ROWCOL(2,1);
|
||||
(*res)[2][2] = ROWCOL(2,2);
|
||||
(*res)[2][3] = ROWCOL(2,3);
|
||||
|
||||
(*res)[3][0] = ROWCOL(3,0);
|
||||
(*res)[3][1] = ROWCOL(3,1);
|
||||
(*res)[3][2] = ROWCOL(3,2);
|
||||
(*res)[3][3] = ROWCOL(3,3);
|
||||
|
||||
#undef ROWCOL
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Multiply -- Multiply a Matrix3D * Matrix4 *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/13/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
void Matrix4::Multiply(const Matrix3D &a,const Matrix4 &b,Matrix4 * res)
|
||||
{
|
||||
assert(res != &b);
|
||||
|
||||
#define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j]
|
||||
|
||||
(*res)[0][0] = ROWCOL(0,0);
|
||||
(*res)[0][1] = ROWCOL(0,1);
|
||||
(*res)[0][2] = ROWCOL(0,2);
|
||||
(*res)[0][3] = ROWCOL(0,3);
|
||||
|
||||
(*res)[1][0] = ROWCOL(1,0);
|
||||
(*res)[1][1] = ROWCOL(1,1);
|
||||
(*res)[1][2] = ROWCOL(1,2);
|
||||
(*res)[1][3] = ROWCOL(1,3);
|
||||
|
||||
(*res)[2][0] = ROWCOL(2,0);
|
||||
(*res)[2][1] = ROWCOL(2,1);
|
||||
(*res)[2][2] = ROWCOL(2,2);
|
||||
(*res)[2][3] = ROWCOL(2,3);
|
||||
|
||||
(*res)[3][0] = b[3][0]; // last row of a is 0,0,0,1
|
||||
(*res)[3][1] = b[3][1]; // this leaves the last row of b unchanged
|
||||
(*res)[3][2] = b[3][2];
|
||||
(*res)[3][3] = b[3][3];
|
||||
|
||||
#undef ROWCOL
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Multiply -- Multiply a Matrix4 * Matrix3D *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
void Matrix4::Multiply(const Matrix4 & a,const Matrix3D & b,Matrix4 * res)
|
||||
{
|
||||
assert(res != &a);
|
||||
|
||||
// ROWCOL multiplies a row of 'a' by one of the first three columns of 'b' (4th entry in b is zero)
|
||||
// ROWCOL4 multiplies a row of 'a' by the fourth column of 'b' (4th entry in b is one)
|
||||
|
||||
#define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
|
||||
#define ROWCOL4(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]
|
||||
|
||||
(*res)[0][0] = ROWCOL(0,0);
|
||||
(*res)[0][1] = ROWCOL(0,1);
|
||||
(*res)[0][2] = ROWCOL(0,2);
|
||||
(*res)[0][3] = ROWCOL4(0,3);
|
||||
|
||||
(*res)[1][0] = ROWCOL(1,0);
|
||||
(*res)[1][1] = ROWCOL(1,1);
|
||||
(*res)[1][2] = ROWCOL(1,2);
|
||||
(*res)[1][3] = ROWCOL4(1,3);
|
||||
|
||||
(*res)[2][0] = ROWCOL(2,0);
|
||||
(*res)[2][1] = ROWCOL(2,1);
|
||||
(*res)[2][2] = ROWCOL(2,2);
|
||||
(*res)[2][3] = ROWCOL4(2,3);
|
||||
|
||||
(*res)[3][0] = ROWCOL(3,0);
|
||||
(*res)[3][1] = ROWCOL(3,1);
|
||||
(*res)[3][2] = ROWCOL(3,2);
|
||||
(*res)[3][3] = ROWCOL4(3,3);
|
||||
|
||||
#undef ROWCOL
|
||||
#undef ROWCOL4
|
||||
}
|
||||
716
Code/Tools/pluglib/matrix4.h
Normal file
716
Code/Tools/pluglib/matrix4.h
Normal file
@@ -0,0 +1,716 @@
|
||||
/*
|
||||
** 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/matrix4.h 15 2/03/00 4:55p Jason_a $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : WW3D *
|
||||
* *
|
||||
* File Name : MATRIX4.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 06/02/97 *
|
||||
* *
|
||||
* Last Update : June 2, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Matrix4::Matrix4 -- Constructor, optionally initialize to Identitiy matrix *
|
||||
* Matrix4::Matrix4 -- Copy Constructor *
|
||||
* Matrix4::Matrix4 -- Convert a Matrix3D (fake 4x4) to a Matrix4 *
|
||||
* Matrix4::Matrix4 -- Constructor *
|
||||
* Matrix4::Make_Identity -- Initializes the matrix to Identity *
|
||||
* Matrix4::Init -- Initializes from the contents of the give Matrix3D *
|
||||
* Matrix4::Init -- Initializes the rows from the given Vector4s *
|
||||
* Matrix4::Init_Ortho -- Initialize to an orthographic projection matrix *
|
||||
* Matrix4::Init_Perspective -- Initialize to a perspective projection matrix *
|
||||
* Matrix4::Init_Perspective -- Initialize to a perspective projection matrix *
|
||||
* Matrix4::Transpose -- Returns transpose of the matrix *
|
||||
* Matrix4::Inverse -- returns the inverse of the matrix *
|
||||
* Matrix4::operator = -- assignment operator *
|
||||
* Matrix4::operator += -- "plus equals" operator *
|
||||
* Matrix4::operator-= -- "minus equals" operator *
|
||||
* Matrix4::operator *= -- "times equals" operator *
|
||||
* Matrix4::operator /= -- "divide equals" operator *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX4_H
|
||||
#define MATRIX4_H
|
||||
|
||||
#include "always.h"
|
||||
#include "vector4.h"
|
||||
#include "matrix3d.h"
|
||||
#include "wwmatrix3.h"
|
||||
|
||||
|
||||
class Matrix4
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
** Constructors
|
||||
*/
|
||||
Matrix4(void) {};
|
||||
Matrix4(const Matrix4 & m);
|
||||
|
||||
explicit Matrix4(bool identity);
|
||||
explicit Matrix4(const Matrix3D & m);
|
||||
explicit Matrix4(const Matrix3 & m);
|
||||
explicit Matrix4(const Vector4 & v0, const Vector4 & v1, const Vector4 & v2, const Vector4 & v3);
|
||||
|
||||
void Make_Identity(void);
|
||||
void Init(const Matrix3D & m);
|
||||
void Init(const Matrix3 & m);
|
||||
void Init(const Vector4 & v0, const Vector4 & v1, const Vector4 & v2, const Vector4 & v3);
|
||||
|
||||
void Init_Ortho(float left,float right,float bottom,float top,float znear,float zfar);
|
||||
void Init_Perspective(float hfov,float vfov,float znear,float zfar);
|
||||
void Init_Perspective(float left,float right,float bottom,float top,float znear,float zfar);
|
||||
|
||||
/*
|
||||
** Access operators
|
||||
*/
|
||||
Vector4 & operator [] (int i) { return Row[i]; }
|
||||
const Vector4 & operator [] (int i) const { return Row[i]; }
|
||||
|
||||
/*
|
||||
** Transpose and Inverse
|
||||
*/
|
||||
Matrix4 Transpose(void) const;
|
||||
Matrix4 Inverse(void) const;
|
||||
|
||||
/*
|
||||
** Assignment operators
|
||||
*/
|
||||
Matrix4 & operator = (const Matrix4 & m);
|
||||
Matrix4 & operator += (const Matrix4 & m);
|
||||
Matrix4 & operator -= (const Matrix4 & m);
|
||||
Matrix4 & operator *= (float d);
|
||||
Matrix4 & operator /= (float d);
|
||||
|
||||
/*
|
||||
** Negation
|
||||
*/
|
||||
friend Matrix4 operator - (const Matrix4& a);
|
||||
|
||||
/*
|
||||
** Scalar multiplication and division
|
||||
*/
|
||||
friend Matrix4 operator * (const Matrix4& a,float d);
|
||||
friend Matrix4 operator * (float d,const Matrix4& a);
|
||||
friend Matrix4 operator / (const Matrix4& a,float d);
|
||||
|
||||
/*
|
||||
** matrix addition
|
||||
*/
|
||||
friend Matrix4 operator + (const Matrix4& a, const Matrix4& b);
|
||||
friend Matrix4 Add(const Matrix4& a);
|
||||
|
||||
/*
|
||||
** matrix subtraction
|
||||
*/
|
||||
friend Matrix4 operator - (const Matrix4 & a, const Matrix4 & b);
|
||||
friend Matrix4 Subtract(const Matrix4 & a, const Matrix4 & b);
|
||||
|
||||
/*
|
||||
** matrix multiplication
|
||||
*/
|
||||
friend Matrix4 operator * (const Matrix4 & a, const Matrix4 & b);
|
||||
friend Matrix4 Multiply(const Matrix4 & a, const Matrix4 & b);
|
||||
|
||||
/*
|
||||
** Comparison operators
|
||||
*/
|
||||
friend int operator == (const Matrix4 & a, const Matrix4 & b);
|
||||
friend int operator != (const Matrix4 & a, const Matrix4 & b);
|
||||
|
||||
/*
|
||||
** Swap two matrices in place
|
||||
*/
|
||||
friend void Swap(Matrix4 & a,Matrix4 & b);
|
||||
|
||||
/*
|
||||
** Linear Transforms
|
||||
*/
|
||||
friend Vector4 operator * (const Matrix4 & a, const Vector4 & v);
|
||||
friend Vector4 operator * (const Matrix4 & a, const Vector3 & v);
|
||||
|
||||
/*
|
||||
** Matrix multiplication without temporaries...
|
||||
*/
|
||||
static void Multiply(const Matrix4 &A,const Matrix4 &B,Matrix4 * set_result);
|
||||
static void Multiply(const Matrix3D &A,const Matrix4 &B,Matrix4 * set_result);
|
||||
static void Multiply(const Matrix4 &A,const Matrix3D &B,Matrix4 * set_result);
|
||||
|
||||
static void Transform_Vector(const Matrix4 & tm,const Vector3 & in,Vector3 * out);
|
||||
|
||||
protected:
|
||||
|
||||
Vector4 Row[4];
|
||||
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Matrix4 -- Constructor, optionally initialize to Identitiy matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4::Matrix4(bool identity)
|
||||
{
|
||||
if (identity) {
|
||||
Make_Identity();
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Matrix4 -- Copy Constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4::Matrix4(const Matrix4 & m)
|
||||
{
|
||||
Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2]; Row[3] = m.Row[3];
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Matrix4 -- Convert a Matrix3D (fake 4x4) to a Matrix4 *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4::Matrix4(const Matrix3D & m)
|
||||
{
|
||||
Init(m);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Matrix4 -- Constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4::Matrix4(const Vector4 & r0, const Vector4 & r1, const Vector4 & r2, const Vector4 & r3)
|
||||
{
|
||||
Init(r0,r1,r2,r3);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Make_Identity -- Initializes the matrix to Identity *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Matrix4::Make_Identity(void)
|
||||
{
|
||||
Row[0].Set(1.0,0.0,0.0,0.0);
|
||||
Row[1].Set(0.0,1.0,0.0,0.0);
|
||||
Row[2].Set(0.0,0.0,1.0,0.0);
|
||||
Row[3].Set(0.0,0.0,0.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Init -- Initializes from the contents of the give Matrix3D *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Matrix4::Init(const Matrix3D & m)
|
||||
{
|
||||
Row[0] = m[0]; Row[1] = m[1]; Row[2] = m[2]; Row[3] = Vector4(0.0,0.0,0.0,1.0);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Init -- Initializes the rows from the given Vector4s *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Matrix4::Init(const Vector4 & r0, const Vector4 & r1, const Vector4 & r2, const Vector4 & r3)
|
||||
{
|
||||
Row[0] = r0; Row[1] = r1; Row[2] = r2; Row[3] = r3;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Init_Ortho -- Initialize to an orthographic projection matrix *
|
||||
* *
|
||||
* You can find the formulas for this in the appendix of the OpenGL programming guide. Also *
|
||||
* this happens to be the same convention used by Surrender. *
|
||||
* *
|
||||
* The result of this projection will be that points inside the volume will have all coords *
|
||||
* between -1 and +1. A point at znear will project to z=-1. A point at zfar will project *
|
||||
* to z=+1... *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Note that the znear and zfar parameters are positive distances to the clipping planes *
|
||||
* even though in the camera coordinate system, the clipping planes are at negative z *
|
||||
* coordinates. This holds for all of the projection initializations and is consistent *
|
||||
* with OpenGL's convention. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Matrix4::Init_Ortho
|
||||
(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float znear,
|
||||
float zfar
|
||||
)
|
||||
{
|
||||
assert(znear >= 0.0f);
|
||||
assert(zfar > znear);
|
||||
|
||||
Make_Identity();
|
||||
Row[0][0] = 2.0f / (right - left);
|
||||
Row[0][3] = -(right + left) / (right - left);
|
||||
Row[1][1] = 2.0f / (top - bottom);
|
||||
Row[1][3] = -(top + bottom) / (top - bottom);
|
||||
Row[2][2] = -2.0f / (zfar - znear);
|
||||
Row[2][3] = -(zfar + znear) / (zfar - znear);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Init_Perspective -- Initialize to a perspective projection matrix *
|
||||
* *
|
||||
* You can find the formulas for this matrix in the appendix of the OpenGL programming guide. *
|
||||
* Also, this happens to be the same convention used by Surrender. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* hfov - horizontal field of view (in radians) *
|
||||
* vfov - vertical field of view (in radians) *
|
||||
* znear - distance to near z clipping plane (positive) *
|
||||
* zfar - distance to the far z clipping plane (positive) *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Note that the znear and zfar parameters are positive distances to the clipping planes *
|
||||
* even though in the camera coordinate system, the clipping planes are at negative z *
|
||||
* coordinates. This holds for all of the projection initializations and is consistent *
|
||||
* with OpenGL's convention. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Matrix4::Init_Perspective(float hfov,float vfov,float znear,float zfar)
|
||||
{
|
||||
assert(znear > 0.0f);
|
||||
assert(zfar > znear);
|
||||
|
||||
Make_Identity();
|
||||
Row[0][0] = (1.0 / tan(hfov*0.5));
|
||||
Row[1][1] = (1.0 / tan(vfov*0.5));
|
||||
Row[2][2] = -(zfar + znear) / (zfar - znear);
|
||||
Row[2][3] = -(2.0*zfar*znear) / (zfar - znear);
|
||||
Row[3][2] = -1.0f;
|
||||
Row[3][3] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Init_Perspective -- Initialize to a perspective projection matrix *
|
||||
* *
|
||||
* You can find the formulas for this matrix in the appendix of the OpenGL programming guide. *
|
||||
* Also, this happens to be the same convention used by Surrender. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Note that the znear and zfar parameters are positive distances to the clipping planes *
|
||||
* even though in the camera coordinate system, the clipping planes are at negative z *
|
||||
* coordinates. This holds for all of the projection initializations and is consistent *
|
||||
* with OpenGL's convention. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/5/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Matrix4::Init_Perspective
|
||||
(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float znear,
|
||||
float zfar
|
||||
)
|
||||
{
|
||||
assert(znear > 0.0f);
|
||||
assert(zfar > 0.0f);
|
||||
|
||||
Make_Identity();
|
||||
Row[0][0] = 2.0*znear / (right - left);
|
||||
Row[0][2] = (right + left) / (right - left);
|
||||
Row[1][1] = 2.0*znear / (top - bottom);
|
||||
Row[1][2] = (top + bottom) / (top - bottom);
|
||||
Row[2][2] = -(zfar + znear) / (zfar - znear);
|
||||
Row[2][3] = -(2.0*zfar*znear) / (zfar - znear);
|
||||
Row[3][2] = -1.0f;
|
||||
Row[3][3] = 0.0f;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Transpose -- Returns transpose of the matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4 Matrix4::Transpose() const
|
||||
{
|
||||
return Matrix4(
|
||||
Vector4(Row[0][0], Row[1][0], Row[2][0], Row[3][0]),
|
||||
Vector4(Row[0][1], Row[1][1], Row[2][1], Row[3][1]),
|
||||
Vector4(Row[0][2], Row[1][2], Row[2][2], Row[3][2]),
|
||||
Vector4(Row[0][3], Row[1][3], Row[2][3], Row[3][3])
|
||||
);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::Inverse -- returns the inverse of the matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4 Matrix4::Inverse() const // Gauss-Jordan elimination with partial pivoting
|
||||
{
|
||||
Matrix4 a(*this); // As a evolves from original mat into identity
|
||||
Matrix4 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<4; j++) {
|
||||
|
||||
// Find largest pivot in column j among rows j..3
|
||||
i1 = j;
|
||||
for (i=j+1; i<4; 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.) {
|
||||
//ALGEBRA_ERROR("Matrix4::inverse: singular matrix; can't invert\n");
|
||||
}
|
||||
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<4; i++) {
|
||||
if (i != j) {
|
||||
b.Row[i] -= a[i][j] * b.Row[j];
|
||||
a.Row[i] -= a[i][j] * a.Row[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::operator = -- assignment operator *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4 & Matrix4::operator = (const Matrix4 & m)
|
||||
{
|
||||
Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2]; Row[3] = m.Row[3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::operator += -- "plus equals" operator *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4& Matrix4::operator += (const Matrix4 & m)
|
||||
{
|
||||
Row[0] += m.Row[0]; Row[1] += m.Row[1]; Row[2] += m.Row[2]; Row[3] += m.Row[3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::operator-= -- "minus equals" operator *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4& Matrix4::operator -= (const Matrix4 & m)
|
||||
{
|
||||
Row[0] -= m.Row[0]; Row[1] -= m.Row[1]; Row[2] -= m.Row[2]; Row[3] -= m.Row[3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::operator *= -- "times equals" operator *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4& Matrix4::operator *= (float d)
|
||||
{
|
||||
Row[0] *= d; Row[1] *= d; Row[2] *= d; Row[3] *= d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Matrix4::operator /= -- "divide equals" operator *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Matrix4& Matrix4::operator /= (float d)
|
||||
{
|
||||
float ood = d;
|
||||
Row[0] *= ood; Row[1] *= ood; Row[2] *= ood; Row[3] *= ood;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Matrix4 operator - (const Matrix4 & a)
|
||||
{
|
||||
return Matrix4(-a.Row[0], -a.Row[1], -a.Row[2], -a.Row[3]);
|
||||
}
|
||||
|
||||
inline Matrix4 operator * (const Matrix4 & a, float d)
|
||||
{
|
||||
return Matrix4(a.Row[0] * d, a.Row[1] * d, a.Row[2] * d, a.Row[3] * d);
|
||||
}
|
||||
|
||||
inline Matrix4 operator * (float d, const Matrix4 & a)
|
||||
{
|
||||
return a*d;
|
||||
}
|
||||
|
||||
inline Matrix4 operator / (const Matrix4 & a, float d)
|
||||
{
|
||||
float ood = 1.0f / d;
|
||||
return Matrix4(a.Row[0] * ood, a.Row[1] * ood, a.Row[2] * ood, a.Row[3] * ood);
|
||||
}
|
||||
|
||||
/*
|
||||
** matrix addition
|
||||
*/
|
||||
inline Matrix4 operator + (const Matrix4 & a, const Matrix4 & b)
|
||||
{
|
||||
return Matrix4(
|
||||
a.Row[0] + b.Row[0],
|
||||
a.Row[1] + b.Row[1],
|
||||
a.Row[2] + b.Row[2],
|
||||
a.Row[3] + b.Row[3]
|
||||
);
|
||||
}
|
||||
|
||||
inline Matrix4 Add(const Matrix4 & a, const Matrix4 & b)
|
||||
{ return a+b; }
|
||||
|
||||
/*
|
||||
** matrix subtraction
|
||||
*/
|
||||
inline Matrix4 operator - (const Matrix4 & a, const Matrix4 & b)
|
||||
{
|
||||
return Matrix4(
|
||||
a.Row[0] - b.Row[0],
|
||||
a.Row[1] - b.Row[1],
|
||||
a.Row[2] - b.Row[2],
|
||||
a.Row[3] - b.Row[3]
|
||||
);
|
||||
}
|
||||
|
||||
inline Matrix4 Subtract(const Matrix4 & a, const Matrix4 & b)
|
||||
{ return a-b; }
|
||||
|
||||
/*
|
||||
** matrix multiplication
|
||||
*/
|
||||
inline Matrix4 operator * (const Matrix4 & a, const Matrix4 & b)
|
||||
{
|
||||
#define ROWCOL(i, j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j] + a[i][3]*b[3][j]
|
||||
|
||||
return Matrix4(
|
||||
Vector4(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
|
||||
Vector4(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
|
||||
Vector4(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
|
||||
Vector4(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
|
||||
);
|
||||
|
||||
#undef ROWCOL
|
||||
}
|
||||
|
||||
inline Matrix4 Multiply(const Matrix4 & a, const Matrix4 & b)
|
||||
{ return a*b; }
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Multiply a Matrix4 by a Vector3 (assumes w=1.0!!!). Yeilds a Vector4 result
|
||||
*/
|
||||
inline Vector4 operator * (const Matrix4 & a, const Vector3 & v) {
|
||||
return Vector4(
|
||||
a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2] + a[0][3] * 1.0,
|
||||
a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2] + a[1][3] * 1.0,
|
||||
a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2] + a[2][3] * 1.0,
|
||||
a[3][0] * v[0] + a[3][1] * v[1] + a[3][2] * v[2] + a[3][3] * 1.0
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Multiply a Matrix4 by a Vector4
|
||||
*/
|
||||
inline Vector4 operator * (const Matrix4 & a, const Vector4 & v) {
|
||||
return Vector4(
|
||||
a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2] + a[0][3] * v[3],
|
||||
a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2] + a[1][3] * v[3],
|
||||
a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2] + a[2][3] * v[3],
|
||||
a[3][0] * v[0] + a[3][1] * v[1] + a[3][2] * v[2] + a[3][3] * v[3]
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Multiply a Matrix4 by a Vector4
|
||||
*/
|
||||
inline void Matrix4::Transform_Vector(const Matrix4 & 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 + A[0][3]);
|
||||
out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z + A[1][3]);
|
||||
out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z + A[2][3]);
|
||||
}
|
||||
|
||||
#endif /*MATRIX4_H*/
|
||||
286
Code/Tools/pluglib/nodefilt.cpp
Normal file
286
Code/Tools/pluglib/nodefilt.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
** 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/nodefilt.cpp 9 1/16/98 10:34a Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G *
|
||||
* *
|
||||
* File Name : NODEFILT.CPP *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 06/09/97 *
|
||||
* *
|
||||
* Last Update : June 9, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* VisibleMeshINodeFilter::Accept_Node -- Accepts visible meshes *
|
||||
* AnimatedINodeFilter::Accept_Node -- Accepts animated INodes *
|
||||
* RootINodeFilter::Accept_Node -- Accepts root INodes *
|
||||
* VisibleHelperINodeFilter::Accept_Node -- Accepts visible helper objects *
|
||||
* VisibleMeshOrHelperINodeFilter::Accept_Node -- Accepts visible helper or mesh objects *
|
||||
* HelperINodeFilter::Accept_Node -- Accepts all helper inodes (including hidden) *
|
||||
* MeshINodeFilter::Accept_Node -- Accepts all mesh inodes (including hidden) *
|
||||
* VisibleSelectedINodeFilter::Accept_Node -- Accepts Visible and selected inodes *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "nodefilt.h"
|
||||
#include <istdplug.h>
|
||||
|
||||
|
||||
/*
|
||||
** The default node filter:
|
||||
*/
|
||||
VisibleMeshINodeFilter DefaultINodeFilter;
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* HelperINodeFilter::Accept_Node -- Accepts all helper inodes (including hidden) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/10/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL HelperINodeFilter::Accept_Node(INode * node,TimeValue time)
|
||||
{
|
||||
Object * obj = node->EvalWorldState(time).obj;
|
||||
|
||||
if (obj && obj->SuperClassID() == HELPER_CLASS_ID) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* MeshINodeFilter::Accept_Node -- Accepts all mesh inodes (including hidden) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/10/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL MeshINodeFilter::Accept_Node(INode * node,TimeValue time)
|
||||
{
|
||||
Object * obj = node->EvalWorldState(time).obj;
|
||||
|
||||
if (obj &&
|
||||
obj->CanConvertToType(triObjectClassID) &&
|
||||
obj->SuperClassID() == GEOMOBJECT_CLASS_ID)
|
||||
{
|
||||
|
||||
return TRUE;
|
||||
|
||||
} else {
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VisibleMeshINodeFilter::Accept_Node -- Accepts visible meshes *
|
||||
* *
|
||||
* Accepts nodes which: *
|
||||
* - can be converted to tri-meshes *
|
||||
* - are not hidden *
|
||||
* - whose visibility > 0.0 *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL VisibleMeshINodeFilter::Accept_Node(INode * node, TimeValue time)
|
||||
{
|
||||
Object * obj = node->EvalWorldState(time).obj;
|
||||
|
||||
if
|
||||
(
|
||||
obj
|
||||
&& !node->IsHidden ()
|
||||
&& obj->CanConvertToType(triObjectClassID)
|
||||
&& obj->SuperClassID() == GEOMOBJECT_CLASS_ID
|
||||
// && node->GetVisibility (time) > 0.0f
|
||||
)
|
||||
{
|
||||
|
||||
return TRUE;
|
||||
|
||||
} else {
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* VisibleHelperINodeFilter::Accept_Node -- Accepts visible helper objects *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/03/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL VisibleHelperINodeFilter::Accept_Node(INode * node, TimeValue time)
|
||||
{
|
||||
Object * obj = node->EvalWorldState(time).obj;
|
||||
|
||||
if ((!obj) || (node->IsHidden()) /*|| (node->GetVisibility(time) <= 0.0f)*/) {
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
if (obj->SuperClassID() == HELPER_CLASS_ID) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VisibleMeshOrHelperINodeFilter::Accept_Node -- Accepts visible helper or mesh objects *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/03/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL VisibleMeshOrHelperINodeFilter::Accept_Node(INode * node, TimeValue time)
|
||||
{
|
||||
Object * obj = node->EvalWorldState(time).obj;
|
||||
|
||||
if ((!obj) || (node->IsHidden()) /*|| (node->GetVisibility(time) <= 0.0f)*/) {
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
if (obj->CanConvertToType(triObjectClassID) && obj->SuperClassID() == GEOMOBJECT_CLASS_ID) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
if (obj->SuperClassID() == HELPER_CLASS_ID) {
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* AnimatedINodeFilter::Accept_Node -- Accepts animated INodes *
|
||||
* *
|
||||
* Accepts nodes which: *
|
||||
* - can be converted to tri-meshes *
|
||||
* - are not hidden *
|
||||
* - whose visibility > 0.0 *
|
||||
* - have animation keys! *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL AnimatedINodeFilter::Accept_Node(INode * node, TimeValue time)
|
||||
{
|
||||
Object * obj = node->EvalWorldState(time).obj;
|
||||
Control * poscon = node->GetTMController()->GetPositionController();
|
||||
Control * rotcon = node->GetTMController()->GetRotationController();
|
||||
|
||||
int numkeys = 0;
|
||||
if (poscon != NULL) {
|
||||
IKeyControl * poskeys = GetKeyControlInterface(poscon);
|
||||
if (poskeys != NULL) numkeys += poskeys->GetNumKeys();
|
||||
}
|
||||
|
||||
if (rotcon != NULL) {
|
||||
IKeyControl * rotkeys = GetKeyControlInterface(rotcon);
|
||||
if (rotkeys != NULL) numkeys += rotkeys->GetNumKeys();
|
||||
}
|
||||
|
||||
if (obj && !node->IsHidden() && numkeys > 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* VisibleSelectedINodeFilter::Accept_Node -- Accepts Visible and selected inodes *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/13/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
BOOL VisibleSelectedINodeFilter::Accept_Node(INode * node, TimeValue time)
|
||||
{
|
||||
if (!node->IsHidden() && node->Selected()) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
178
Code/Tools/pluglib/nodefilt.h
Normal file
178
Code/Tools/pluglib/nodefilt.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
** 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/nodefilt.h 6 1/14/98 10:23a Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G *
|
||||
* *
|
||||
* File Name : NODEFILT.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 06/09/97 *
|
||||
* *
|
||||
* Last Update : June 9, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#ifndef NODEFILT_H
|
||||
#define NODEFILT_H
|
||||
|
||||
#include "always.h"
|
||||
#include <Max.h>
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* INodeFilterClass
|
||||
*
|
||||
* This is simply an object used to accept or reject INodes
|
||||
* based on whatever criteria you desire. There are some
|
||||
* default node filters defined in this module or you can
|
||||
* create your own by inheriting the Abstract Base Class
|
||||
* INodeFilterClass and implementing the Accept_Node method.
|
||||
*
|
||||
***************************************************************/
|
||||
class INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time) = 0;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* AnyINodeFilter
|
||||
*
|
||||
* Accepts all INodes...
|
||||
*
|
||||
***************************************************************/
|
||||
class AnyINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time) { return TRUE; }
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* HelperINodeFilter
|
||||
*
|
||||
* Accepts INodes which are Helper objects
|
||||
*
|
||||
***************************************************************/
|
||||
class HelperINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* MeshINodeFilter
|
||||
*
|
||||
* Only accepts INodes which are Triangle meshes
|
||||
*
|
||||
***************************************************************/
|
||||
class MeshINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* VisibleMeshINodeFilter
|
||||
*
|
||||
* Only accepts INodes which are Triangle meshes and are
|
||||
* currently visible
|
||||
*
|
||||
***************************************************************/
|
||||
class VisibleMeshINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* VisibleHelperINodeFilter
|
||||
*
|
||||
* Only accepts INodes which are Helper objects and are
|
||||
* currently visible
|
||||
*
|
||||
***************************************************************/
|
||||
class VisibleHelperINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* VisibleMeshOrHelperINodeFilter
|
||||
*
|
||||
* Only accepts INodes which are Triangle meshes or helper
|
||||
* objects and are currently visible
|
||||
*
|
||||
***************************************************************/
|
||||
class VisibleMeshOrHelperINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* AnimatedINodeFilter
|
||||
*
|
||||
* Only accepts INodes which contain at least on animation
|
||||
* key.
|
||||
*
|
||||
***************************************************************/
|
||||
class AnimatedINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* VisibleSelectedINodeFilter
|
||||
*
|
||||
* Only accepts INodes which are Visible and Selected
|
||||
*
|
||||
***************************************************************/
|
||||
class VisibleSelectedINodeFilter : public INodeFilterClass
|
||||
{
|
||||
public:
|
||||
virtual BOOL Accept_Node(INode * node, TimeValue time);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /*NODEFILT_H*/
|
||||
445
Code/Tools/pluglib/nodelist.cpp
Normal file
445
Code/Tools/pluglib/nodelist.cpp
Normal file
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
** 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/pluglib/nodelist.cpp 9 3/14/02 4:22p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G *
|
||||
* *
|
||||
* File Name : NODELIST.CPP *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 06/09/97 *
|
||||
* *
|
||||
* Last Update : June 9, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* INodeListClass::INodeListClass -- Create an INodeList *
|
||||
* INodeListClass::~INodeListClass -- Delete the INode List *
|
||||
* INode * INodeListClass::operator[] -- Array-like access to the list members *
|
||||
* INodeListClass::callback -- callback function for MAX *
|
||||
* INodeListClass::INodeListClass -- A "copy" contstructor with filtering... *
|
||||
* INodeListClass::INodeListClass -- constructor *
|
||||
* INodeListClass::INodeListClass -- Constructor *
|
||||
* INodeListClass::Insert -- insert a list of nodes into this list *
|
||||
* INodeListClass::Insert -- Inserts an INode into the list *
|
||||
* INodeListClass::Add_Tree -- Add a tree of INodes to the list *
|
||||
* INodeListClass::Remove -- Remove the i'th element of the list *
|
||||
* INodeListClass::Contains -- test whether the given node is in this list *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "nodelist.h"
|
||||
|
||||
|
||||
static AnyINodeFilter _AnyFilter;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* ListEntryClass
|
||||
*
|
||||
* Used to implement a linked list of INodes.
|
||||
*
|
||||
*******************************************************************************/
|
||||
class INodeListEntryClass
|
||||
{
|
||||
public:
|
||||
|
||||
INodeListEntryClass(INode * n,TimeValue /*time*/) { Node = n; }
|
||||
~INodeListEntryClass(void) {}
|
||||
|
||||
INode * Node;
|
||||
INodeListEntryClass * Next;
|
||||
};
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::INodeListClass -- Constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
INodeListClass::INodeListClass(TimeValue time,INodeFilterClass * inodefilter) :
|
||||
NumNodes(0),
|
||||
Time(time),
|
||||
ListHead(NULL),
|
||||
INodeFilter(inodefilter)
|
||||
{
|
||||
if (INodeFilter == NULL) {
|
||||
INodeFilter = &_AnyFilter;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::INodeListClass -- Create an INodeList *
|
||||
* *
|
||||
* INPUT: *
|
||||
* scene - 3dsMAX scene to enumerate *
|
||||
* time - time at which to create the list of INodes *
|
||||
* inodefilter - object which will accept or reject each INode in the scene *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
INodeListClass::INodeListClass(IScene * scene,TimeValue time,INodeFilterClass * inodefilter) :
|
||||
NumNodes(0),
|
||||
Time(time),
|
||||
ListHead(NULL),
|
||||
INodeFilter(inodefilter)
|
||||
{
|
||||
if (INodeFilter == NULL) {
|
||||
INodeFilter = &_AnyFilter;
|
||||
}
|
||||
scene->EnumTree(this);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::INodeListClass -- Constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/13/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
INodeListClass::INodeListClass(INode * root,TimeValue time,INodeFilterClass * nodefilter) :
|
||||
NumNodes(0),
|
||||
Time(time),
|
||||
ListHead(NULL),
|
||||
INodeFilter(nodefilter)
|
||||
{
|
||||
if (INodeFilter == NULL) {
|
||||
INodeFilter = &_AnyFilter;
|
||||
}
|
||||
Add_Tree(root);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::INodeListClass -- A "copy" contstructor with filtering... *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
INodeListClass::INodeListClass(INodeListClass & copyfrom,TimeValue time,INodeFilterClass * inodefilter) :
|
||||
NumNodes(0),
|
||||
Time(time),
|
||||
ListHead(NULL),
|
||||
INodeFilter(inodefilter)
|
||||
{
|
||||
if (INodeFilter == NULL) {
|
||||
INodeFilter = &_AnyFilter;
|
||||
}
|
||||
for (unsigned i=0; i<copyfrom.Num_Nodes(); i++) {
|
||||
Insert(copyfrom[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::~INodeListClass -- Delete the INode List *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
INodeListClass::~INodeListClass(void)
|
||||
{
|
||||
while (ListHead)
|
||||
{
|
||||
INodeListEntryClass * next = ListHead->Next;
|
||||
delete ListHead;
|
||||
ListHead = next;
|
||||
}
|
||||
|
||||
NumNodes = 0;
|
||||
ListHead = NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INode * INodeListClass::operator[] -- Array-like access to the list members *
|
||||
* *
|
||||
* INPUT: *
|
||||
* index - index of the list entry *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* pointer to an INode *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
INode * INodeListClass::operator[] ( int index ) const
|
||||
{
|
||||
INodeListEntryClass * entry = ListHead;
|
||||
while (index > 0 && entry != NULL )
|
||||
{
|
||||
entry = entry->Next;
|
||||
index--;
|
||||
}
|
||||
return entry->Node;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::Insert -- insert a list of nodes into this list *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/14/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void INodeListClass::Insert(INodeListClass & insertlist)
|
||||
{
|
||||
for (unsigned int i=0; i<insertlist.Num_Nodes(); i++) {
|
||||
Insert(insertlist[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::Insert -- Inserts an INode into the list *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 07/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
void INodeListClass::Insert(INode * node)
|
||||
{
|
||||
if (INodeFilter->Accept_Node(node,Time))
|
||||
{
|
||||
INodeListEntryClass * newentry = new INodeListEntryClass(node, Time);
|
||||
newentry->Next = ListHead;
|
||||
ListHead = newentry;
|
||||
NumNodes++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::Remove -- Remove the i'th element of the list *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/27/2000 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
void INodeListClass::Remove(int i)
|
||||
{
|
||||
if ((i < 0) || (i > Num_Nodes())) {
|
||||
return;
|
||||
}
|
||||
|
||||
INodeListEntryClass * prev = ListHead;
|
||||
while (i > 1) {
|
||||
prev = prev->Next;
|
||||
}
|
||||
|
||||
INodeListEntryClass * deleteme = prev->Next;
|
||||
if (deleteme != NULL) {
|
||||
prev->Next = prev->Next->Next;
|
||||
delete deleteme;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::Add_Tree -- Add a tree of INodes to the list *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/13/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void INodeListClass::Add_Tree(INode * root)
|
||||
{
|
||||
if (root == NULL) return;
|
||||
|
||||
Insert(root);
|
||||
for (int i=0; i<root->NumberOfChildren(); i++) {
|
||||
Add_Tree(root->GetChildNode(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::Contains -- test whether the given node is in this list *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 1/30/2002 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
bool INodeListClass::Contains(INode * node)
|
||||
{
|
||||
INodeListIterator it(this);
|
||||
while (!it.Is_Done()) {
|
||||
if (it.Get_INode() == node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* INodeListClass::callback -- callback function for MAX *
|
||||
* *
|
||||
* 3dsMAX calls this function with a pointer to each INode in the scene. We keep a pointer *
|
||||
* to the ones we like. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/09/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
int INodeListClass::callback(INode * node)
|
||||
{
|
||||
Insert(node);
|
||||
|
||||
return TREE_CONTINUE; // Keep on enumerating....
|
||||
}
|
||||
|
||||
|
||||
void INodeListClass::Sort(const INodeCompareClass & node_compare)
|
||||
{
|
||||
for (unsigned int i=0; i<Num_Nodes(); i++) {
|
||||
for (unsigned int j=0; j<Num_Nodes(); j++) {
|
||||
|
||||
INodeListEntryClass * ni = get_nth_item(i);
|
||||
INodeListEntryClass * nj = get_nth_item(j);
|
||||
|
||||
if (node_compare(ni->Node,nj->Node) > 0) {
|
||||
INode * tmp = ni->Node;
|
||||
ni->Node = nj->Node;
|
||||
nj->Node = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INodeListEntryClass * INodeListClass::get_nth_item(int index)
|
||||
{
|
||||
INodeListEntryClass * entry = ListHead;
|
||||
while (index > 0 && entry != NULL )
|
||||
{
|
||||
entry = entry->Next;
|
||||
index--;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* INodeListIterator
|
||||
*
|
||||
* Iterator for INodeLists
|
||||
*
|
||||
*******************************************************************************/
|
||||
INodeListIterator::INodeListIterator(INodeListClass * list) :
|
||||
List(list)
|
||||
{
|
||||
assert(list != NULL);
|
||||
First();
|
||||
}
|
||||
|
||||
INodeListIterator::~INodeListIterator(void)
|
||||
{
|
||||
}
|
||||
|
||||
void INodeListIterator::First(INodeListClass * list)
|
||||
{
|
||||
if (list != NULL) {
|
||||
List = list;
|
||||
}
|
||||
assert(List != NULL);
|
||||
Node = List->ListHead;
|
||||
}
|
||||
|
||||
void INodeListIterator::Next(void)
|
||||
{
|
||||
if (Node != NULL) {
|
||||
Node = Node->Next;
|
||||
}
|
||||
}
|
||||
|
||||
bool INodeListIterator::Is_Done(void)
|
||||
{
|
||||
return (Node == NULL);
|
||||
}
|
||||
|
||||
|
||||
INode * INodeListIterator::Get_INode(void)
|
||||
{
|
||||
if (Node != NULL) {
|
||||
return Node->Node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
123
Code/Tools/pluglib/nodelist.h
Normal file
123
Code/Tools/pluglib/nodelist.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
** 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/pluglib/nodelist.h 8 3/14/02 4:22p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G *
|
||||
* *
|
||||
* File Name : NODELIST.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 06/09/97 *
|
||||
* *
|
||||
* Last Update : June 9, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#ifndef NODELIST_H
|
||||
#define NODELIST_H
|
||||
|
||||
#include "always.h"
|
||||
#include <Max.h>
|
||||
|
||||
#ifndef NODEFILT_H
|
||||
#include "nodefilt.h"
|
||||
#endif
|
||||
|
||||
|
||||
class INodeListEntryClass;
|
||||
class INodeCompareClass;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* INodeListClass
|
||||
*
|
||||
* This is a class that can enumerate a 3dsMax scene and build a list of
|
||||
* all of the INodes that meet your desired criteria.
|
||||
*
|
||||
*******************************************************************************/
|
||||
class INodeListClass : public ITreeEnumProc
|
||||
{
|
||||
public:
|
||||
|
||||
INodeListClass(TimeValue time,INodeFilterClass * nodefilter = NULL);
|
||||
INodeListClass(IScene * scene,TimeValue time,INodeFilterClass * nodefilter = NULL);
|
||||
INodeListClass(INode * root,TimeValue time,INodeFilterClass * nodefilter = NULL);
|
||||
INodeListClass(INodeListClass & copyfrom,TimeValue time,INodeFilterClass * inodefilter = NULL);
|
||||
~INodeListClass();
|
||||
|
||||
void Set_Filter(INodeFilterClass * inodefilter) { INodeFilter = inodefilter; }
|
||||
void Insert(INodeListClass & insertlist);
|
||||
void Insert(INode * node);
|
||||
void Remove(int i);
|
||||
unsigned Num_Nodes(void) const { return NumNodes; }
|
||||
INode * operator[] (int index) const;
|
||||
void Sort(const INodeCompareClass & node_compare);
|
||||
void Add_Tree(INode * root);
|
||||
bool Contains(INode * node);
|
||||
|
||||
private:
|
||||
|
||||
unsigned NumNodes;
|
||||
TimeValue Time;
|
||||
INodeListEntryClass * ListHead;
|
||||
INodeFilterClass * INodeFilter;
|
||||
|
||||
INodeListEntryClass * get_nth_item(int index);
|
||||
int callback(INode * node);
|
||||
|
||||
friend class INodeListIterator;
|
||||
};
|
||||
|
||||
|
||||
class INodeCompareClass
|
||||
{
|
||||
public:
|
||||
// returns <0 if nodea < node b.
|
||||
// returns =0 if nodea = node b.
|
||||
// returns >0 if nodea > node b.
|
||||
virtual int operator() (INode * nodea,INode * nodeb) const = 0;
|
||||
};
|
||||
|
||||
|
||||
class INodeListIterator
|
||||
{
|
||||
public:
|
||||
INodeListIterator(INodeListClass * list);
|
||||
~INodeListIterator(void);
|
||||
|
||||
void First(INodeListClass * list = NULL);
|
||||
void Next(void);
|
||||
bool Is_Done(void);
|
||||
|
||||
INode * Get_INode(void);
|
||||
|
||||
private:
|
||||
INodeListClass * List;
|
||||
INodeListEntryClass * Node;
|
||||
|
||||
};
|
||||
|
||||
#endif /*NODELIST_H*/
|
||||
57
Code/Tools/pluglib/noinit.h
Normal file
57
Code/Tools/pluglib/noinit.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/noinit.h $*
|
||||
* *
|
||||
* $Author:: Eric_c $*
|
||||
* *
|
||||
* $Modtime:: 3/23/99 5:20p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef NOINIT_H
|
||||
#define NOINIT_H
|
||||
|
||||
/**********************************************************************
|
||||
** This class is solely used as a parameter to a constructor that does
|
||||
** absolutely no initialization to the object being constructed. By using
|
||||
** this method, it is possible to load and save data directly from a
|
||||
** class that has virtual functions. The construction process automatically
|
||||
** takes care of initializing the virtual function table pointer and the
|
||||
** rest of the constructor doesn't initialize any data members. After loading
|
||||
** into a class object, simply perform an in-place new operation.
|
||||
*/
|
||||
#ifndef NoInitClass
|
||||
class NoInitClass {
|
||||
public:
|
||||
void operator () (void) const {};
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
268
Code/Tools/pluglib/palette.cpp
Normal file
268
Code/Tools/pluglib/palette.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Library/PALETTE.CPP $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 7/22/97 11:37a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* PaletteClass::Adjust -- Adjusts the palette toward another palette. *
|
||||
* PaletteClass::Adjust -- Adjusts this palette toward black. *
|
||||
* PaletteClass::Closest_Color -- Finds closest match to color specified. *
|
||||
* PaletteClass::PaletteClass -- Constructor that fills palette with color specified. *
|
||||
* PaletteClass::operator = -- Assignment operator for palette objects. *
|
||||
* PaletteClass::operator == -- Equality operator for palette objects. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "always.h"
|
||||
#include "palette.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::PaletteClass -- Constructor that fills palette with color specified. *
|
||||
* *
|
||||
* This constructor will fill the palette with the color specified. *
|
||||
* *
|
||||
* INPUT: rgb -- Reference to the color to fill the entire palette with. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
PaletteClass::PaletteClass(RGBClass const & rgb)
|
||||
{
|
||||
for (int index = 0; index < COLOR_COUNT; index++) {
|
||||
Palette[index] = rgb;
|
||||
}
|
||||
}
|
||||
|
||||
PaletteClass::PaletteClass(unsigned char *binary_palette)
|
||||
{
|
||||
memcpy(&Palette[0], binary_palette, sizeof(Palette));
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::operator == -- Equality operator for palette objects. *
|
||||
* *
|
||||
* This is the comparison for equality operator. It will compare palette objects to *
|
||||
* determine if they are identical. *
|
||||
* *
|
||||
* INPUT: palette -- Reference to the palette to compare to this palette. *
|
||||
* *
|
||||
* OUTPUT: Are the two palettes identical? *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int PaletteClass::operator == (PaletteClass const & palette) const
|
||||
{
|
||||
if (this == &palette) return(true);
|
||||
return(memcmp(&Palette[0], &palette.Palette[0], sizeof(Palette)) == 0);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::operator = -- Assignment operator for palette objects. *
|
||||
* *
|
||||
* This is the assignment operator for palette objects. Although the default C++ generated *
|
||||
* assignment operator would function correctly, it would not check for self-assignment *
|
||||
* and thus this routine can be faster. *
|
||||
* *
|
||||
* INPUT: palette -- Reference to that palette that will be copied into this palette. *
|
||||
* *
|
||||
* OUTPUT: Returns with a reference to the newly copied to palette. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
PaletteClass & PaletteClass::operator = (PaletteClass const & palette)
|
||||
{
|
||||
if (this == &palette) return(*this);
|
||||
|
||||
memcpy(&Palette[0], &palette.Palette[0], sizeof(Palette));
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::Adjust -- Adjusts this palette toward black. *
|
||||
* *
|
||||
* This routine is used to adjust this palette toward black. Typical use of this routine *
|
||||
* is when fading the palette to black. *
|
||||
* *
|
||||
* INPUT: ratio -- The ratio to fade this palette to black. 0 means no fading at all. 255 *
|
||||
* means 100% faded to black. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: This routine doesn't actually set the palette to the video card. Use the Set() *
|
||||
* function to achieve that purpose. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void PaletteClass::Adjust(int ratio)
|
||||
{
|
||||
for (int index = 0; index < COLOR_COUNT; index++) {
|
||||
Palette[index].Adjust(ratio, BlackColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::Adjust -- Adjusts the palette toward another palette. *
|
||||
* *
|
||||
* This routine is used to adjust a palette toward a destination palette by the ratio *
|
||||
* specified. This is primarily used by the palette fading routines. *
|
||||
* *
|
||||
* INPUT: palette -- Reference to the destination palette. *
|
||||
* *
|
||||
* ratio -- The ratio to adjust this palette toward the destination palette. A *
|
||||
* value of 0 means no adjustment at all. A value of 255 means 100% *
|
||||
* adjustment. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void PaletteClass::Adjust(int ratio, PaletteClass const & palette)
|
||||
{
|
||||
for (int index = 0; index < COLOR_COUNT; index++) {
|
||||
Palette[index].Adjust(ratio, palette[index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::Partial_Adjust -- Adjusts the specified parts of this palette toward black. *
|
||||
* *
|
||||
* This routine is used to adjust this palette toward black. Typical use of this routine *
|
||||
* is when fading the palette to black. The input lookup table is used to determine *
|
||||
* which entries should fade and which should stay the same *
|
||||
* *
|
||||
* INPUT: ratio -- The ratio to fade this palette to black. 0 means no fading at all. 255 *
|
||||
* means 100% faded to black. *
|
||||
* *
|
||||
* lookup -- ptr to lookup table *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: This routine doesn't actually set the palette to the video card. Use the Set() *
|
||||
* function to achieve that purpose. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void PaletteClass::Partial_Adjust(int ratio, char *lut)
|
||||
{
|
||||
for (int index = 0; index < COLOR_COUNT; index++) {
|
||||
if (lut[index]) {
|
||||
Palette[index].Adjust(ratio, BlackColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::Partial_Adjust -- Adjusts the palette toward another palette. *
|
||||
* *
|
||||
* This routine is used to adjust a palette toward a destination palette by the ratio *
|
||||
* specified. This is primarily used by the palette fading routines. The input lookup *
|
||||
* table is used to determine which entries should fade and which should stay the same *
|
||||
* *
|
||||
* *
|
||||
* INPUT: palette -- Reference to the destination palette. *
|
||||
* *
|
||||
* ratio -- The ratio to adjust this palette toward the destination palette. A *
|
||||
* value of 0 means no adjustment at all. A value of 255 means 100% *
|
||||
* adjustment. *
|
||||
* *
|
||||
* lookup -- ptr to lookup table *
|
||||
* *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void PaletteClass::Partial_Adjust(int ratio, PaletteClass const & palette, char *lut)
|
||||
{
|
||||
for (int index = 0; index < COLOR_COUNT; index++) {
|
||||
if (lut[index]) {
|
||||
Palette[index].Adjust(ratio, palette[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* PaletteClass::Closest_Color -- Finds closest match to color specified. *
|
||||
* *
|
||||
* This routine will examine the palette and return with the color index number for the *
|
||||
* color that most closely matches the color specified. Remap operations rely heavily on *
|
||||
* this routine to allow working with a constant palette. *
|
||||
* *
|
||||
* INPUT: rgb -- Reference to a color to search for in the current palette. *
|
||||
* *
|
||||
* OUTPUT: Returns with a color index value to most closely matches the specified color. *
|
||||
* *
|
||||
* WARNINGS: This routine will quite likely not find an exact match. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int PaletteClass::Closest_Color(RGBClass const & rgb) const
|
||||
{
|
||||
int closest = 0;
|
||||
int value = -1;
|
||||
|
||||
RGBClass const * ptr = &Palette[0];
|
||||
for (int index = 0; index < COLOR_COUNT; index++) {
|
||||
int difference = rgb.Difference(*ptr++);
|
||||
if (value == -1 || difference < value) {
|
||||
value = difference;
|
||||
closest = index;
|
||||
}
|
||||
}
|
||||
return(closest);
|
||||
}
|
||||
81
Code/Tools/pluglib/palette.h
Normal file
81
Code/Tools/pluglib/palette.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/PALETTE.H $*
|
||||
* *
|
||||
* $Author:: Eric_c $*
|
||||
* *
|
||||
* $Modtime:: 4/02/99 12:00p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef PALETTE_H
|
||||
#define PALETTE_H
|
||||
|
||||
#include "rgb.h"
|
||||
|
||||
/*
|
||||
** The palette class is used to manipulate a palette as a whole. All 256 colors are
|
||||
** represented by the palette class object.
|
||||
*/
|
||||
class PaletteClass
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
COLOR_COUNT=256 // Number of color indices on the palette.
|
||||
};
|
||||
|
||||
PaletteClass(void) {};
|
||||
PaletteClass(RGBClass const & rgb);
|
||||
PaletteClass(unsigned char *binary_palette);
|
||||
|
||||
RGBClass & operator[] (int index) {return(Palette[index % COLOR_COUNT]);};
|
||||
RGBClass const & operator[] (int index) const {return(Palette[index % COLOR_COUNT]);};
|
||||
RGBClass & Get_Color(int index) {return(Palette[index % COLOR_COUNT]);};
|
||||
RGBClass const & Get_Color(int index) const {return(Palette[index % COLOR_COUNT]);};
|
||||
int operator == (PaletteClass const & palette) const;
|
||||
int operator != (PaletteClass const & palette) const {return(!(operator ==(palette)));};
|
||||
PaletteClass & operator = (PaletteClass const & palette);
|
||||
operator const unsigned char * (void) const {return((const unsigned char *)&Palette[0]);};
|
||||
operator unsigned char * (void) {return((unsigned char *)&Palette[0]);};
|
||||
|
||||
void Adjust(int ratio);
|
||||
void Adjust(int ratio, PaletteClass const & palette);
|
||||
void Partial_Adjust(int ratio, char *lut);
|
||||
void Partial_Adjust(int ratio, PaletteClass const & palette, char *lut);
|
||||
int Closest_Color(RGBClass const & rgb) const;
|
||||
|
||||
protected:
|
||||
RGBClass Palette[COLOR_COUNT];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
99
Code/Tools/pluglib/plane.h
Normal file
99
Code/Tools/pluglib/plane.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
** 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/pluglib/plane.h 8 4/22/98 6:36p Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Voxel Technology *
|
||||
* *
|
||||
* File Name : PLANE.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 03/17/97 *
|
||||
* *
|
||||
* Last Update : March 17, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#ifndef PLANE_H
|
||||
#define PLANE_H
|
||||
|
||||
#ifndef VECTOR3_H
|
||||
#include "vector3.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** PlaneClass
|
||||
**
|
||||
** 3D-planes. This class needs to be fleshed out but it does what I need for now.
|
||||
*/
|
||||
|
||||
class PlaneClass
|
||||
{
|
||||
public:
|
||||
|
||||
Vector3 N;
|
||||
float D;
|
||||
|
||||
PlaneClass(void) : N(0.0f,0.0f,1.0f), D(0.0f) { }
|
||||
PlaneClass(float a,float b,float c,float d) : N(a,b,c),D(d) { }
|
||||
PlaneClass(const Vector3 & normal,float dist) : N(normal), D(dist) { }
|
||||
|
||||
// Create a plane given the normal and a point on the plane
|
||||
PlaneClass(const Vector3 & normal,const Vector3 & point);
|
||||
|
||||
// Create a plane out of three points, ordered according to a right-hand convention.
|
||||
PlaneClass(const Vector3 & point1, const Vector3 & point2, const Vector3 & point3);
|
||||
|
||||
void Set(float a,float b,float c,float d) { N[0] = a; N[1] = b; N[2] = c; D = d; }
|
||||
};
|
||||
|
||||
inline PlaneClass::PlaneClass(const Vector3 & normal,const Vector3 & point)
|
||||
{
|
||||
N = normal;
|
||||
D = Vector3::Dot_Product(normal , point);
|
||||
}
|
||||
|
||||
inline PlaneClass::PlaneClass(const Vector3 & point1, const Vector3 & point2, const Vector3 & point3)
|
||||
{
|
||||
N = Vector3::Cross_Product((point2 - point1), (point3 - point1));
|
||||
if (N != Vector3(0.0f, 0.0f, 0.0f)) {
|
||||
// Points are not colinear. Normalize N and calculate D.
|
||||
N.Normalize();
|
||||
D = N * point1;
|
||||
} else {
|
||||
// They are colinear - return default plane (constructors can't fail).
|
||||
N = Vector3(0.0f, 0.0f, 1.0f);
|
||||
D = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool In_Front(const Vector3 & point,const PlaneClass & plane)
|
||||
{
|
||||
double dist = point * plane.N;
|
||||
return (dist > plane.D);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /*PLANE_H*/
|
||||
1218
Code/Tools/pluglib/pluglib.dsp
Normal file
1218
Code/Tools/pluglib/pluglib.dsp
Normal file
File diff suppressed because it is too large
Load Diff
1262
Code/Tools/pluglib/rawfile.cpp
Normal file
1262
Code/Tools/pluglib/rawfile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
203
Code/Tools/pluglib/rawfile.h
Normal file
203
Code/Tools/pluglib/rawfile.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/rawfile.h $*
|
||||
* *
|
||||
* $Author:: Ian_l $*
|
||||
* *
|
||||
* $Modtime:: 10/31/01 2:00p $*
|
||||
* *
|
||||
* $Revision:: 9 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* RawFileClass::File_Name -- Returns with the filename associate with the file object. *
|
||||
* RawFileClass::RawFileClass -- Default constructor for a file object. *
|
||||
* RawFileClass::~RawFileClass -- Default deconstructor for a file object. *
|
||||
* RawFileClass::Is_Open -- Checks to see if the file is open or not. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef RAWFILE_Hx
|
||||
#define RAWFILE_Hx
|
||||
|
||||
//#include <errno.h>
|
||||
|
||||
// #include "win.h"
|
||||
|
||||
#ifdef _UNIX
|
||||
#include <stdio.h>
|
||||
#include "osdep.h"
|
||||
#define NULL_HANDLE NULL
|
||||
#define HANDLE_TYPE FILE*
|
||||
#else
|
||||
#define NULL_HANDLE INVALID_HANDLE_VALUE
|
||||
#define HANDLE_TYPE HANDLE
|
||||
#endif
|
||||
|
||||
#include "wwfile.h"
|
||||
|
||||
|
||||
#ifndef WWERROR
|
||||
#define WWERROR -1
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This is the definition of the raw file class. It is derived from the abstract base FileClass
|
||||
** and handles the interface to the low level DOS routines. This is the first class in the
|
||||
** chain of derived file classes that actually performs a useful function. With this class,
|
||||
** I/O is possible. More sophisticated features, such as packed files, CD-ROM support,
|
||||
** file caching, and XMS/EMS memory support, are handled by derived classes.
|
||||
**
|
||||
** Of particular importance is the need to override the error routine if more sophisticated
|
||||
** error handling is required. This is more than likely if greater functionality is derived
|
||||
** from this base class.
|
||||
*/
|
||||
class RawFileClass : public FileClass
|
||||
{
|
||||
typedef FileClass BASECLASS;
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
** This is a record of the access rights used to open the file. These rights are
|
||||
** used if the file object is duplicated.
|
||||
*/
|
||||
int Rights;
|
||||
|
||||
RawFileClass(char const *filename);
|
||||
RawFileClass(void);
|
||||
RawFileClass (RawFileClass const & f);
|
||||
RawFileClass & operator = (RawFileClass const & f);
|
||||
virtual ~RawFileClass(void);
|
||||
|
||||
virtual char const * File_Name(void) const;
|
||||
virtual char const * Set_Name(char const *filename);
|
||||
virtual int Create(void);
|
||||
virtual int Delete(void);
|
||||
virtual bool Is_Available(int forced=false);
|
||||
virtual bool Is_Open(void) const;
|
||||
virtual int Open(char const *filename, int rights=READ);
|
||||
virtual int Open(int rights=READ);
|
||||
virtual int Read(void *buffer, int size);
|
||||
virtual int Seek(int pos, int dir=SEEK_CUR);
|
||||
virtual int Size(void);
|
||||
virtual int Write(void const *buffer, int size);
|
||||
virtual void Close(void);
|
||||
virtual unsigned long Get_Date_Time(void);
|
||||
virtual bool Set_Date_Time(unsigned long datetime);
|
||||
virtual void Error(int error, int canretry = false, char const * filename=NULL);
|
||||
virtual void Bias(int start, int length=-1);
|
||||
virtual void * Get_File_Handle(void) { return Handle; }
|
||||
|
||||
virtual void Attach (void *handle, int rights=READ);
|
||||
virtual void Detach (void);
|
||||
|
||||
/*
|
||||
** These bias values enable a sub-portion of a file to appear as if it
|
||||
** were the whole file. This comes in very handy for multi-part files such as
|
||||
** mixfiles.
|
||||
*/
|
||||
int BiasStart;
|
||||
int BiasLength;
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
** This function returns the largest size a low level DOS read or write may
|
||||
** perform. Larger file transfers are performed in chunks of this size or less.
|
||||
*/
|
||||
int Transfer_Block_Size(void);
|
||||
|
||||
int Raw_Seek(int pos, int dir=SEEK_CUR);
|
||||
void Reset(void);
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
** This is the low level DOS handle. A -1 indicates an empty condition.
|
||||
*/
|
||||
#ifdef _UNIX
|
||||
FILE* Handle;
|
||||
#else
|
||||
void * Handle;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This points to the filename as a NULL terminated string. It may point to either a
|
||||
** constant or an allocated string as indicated by the "Allocated" flag.
|
||||
*/
|
||||
char const * Filename;
|
||||
|
||||
//
|
||||
// file date and time are in the following formats:
|
||||
//
|
||||
// date bits 0-4 day (0-31)
|
||||
// bits 5-8 month (1-12)
|
||||
// bits 9-15 year (0-119 representing 1980-2099)
|
||||
//
|
||||
// time bits 0-4 second/2 (0-29)
|
||||
// bits 5-10 minutes (0-59)
|
||||
// bits 11-15 hours (0-23)
|
||||
//
|
||||
unsigned short Date;
|
||||
unsigned short Time;
|
||||
|
||||
/*
|
||||
** Filenames that were assigned as part of the construction process
|
||||
** are not allocated. It is assumed that the filename string is a
|
||||
** constant in that case and thus making duplication unnecessary.
|
||||
** This value will be non-zero if the filename has be allocated
|
||||
** (using strdup()).
|
||||
*/
|
||||
bool Allocated;
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* RawFileClass::File_Name -- Returns with the filename associate with the file object. *
|
||||
* *
|
||||
* Use this routine to determine what filename is associated with this file object. If no *
|
||||
* filename has yet been assigned, then this routing will return NULL. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: Returns with a pointer to the file name associated with this file object or NULL *
|
||||
* if one doesn't exist. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/1994 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
inline char const * RawFileClass::File_Name(void) const
|
||||
{
|
||||
return(Filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
176
Code/Tools/pluglib/realcrc.cpp
Normal file
176
Code/Tools/pluglib/realcrc.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Westwood Library *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/realcrc.cpp $*
|
||||
* *
|
||||
* Author:: Byon Garrabrant *
|
||||
* *
|
||||
* $Modtime:: 7/09/99 1:44p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* CRC_Memory -- calculates a CRC for a block of memory *
|
||||
* CRC_String -- Calculates a CRC for a NULL-terminated string *
|
||||
* CRC_Stringi -- Calculates a CRC for a string, case-insensitive *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "realcrc.h"
|
||||
#include <ctype.h>
|
||||
|
||||
// CRC for poly 0x04C11DB7
|
||||
unsigned long CRC32_Table[ 256 ] =
|
||||
{
|
||||
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
|
||||
0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
|
||||
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
|
||||
0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
|
||||
0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
|
||||
0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
|
||||
0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
|
||||
0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
|
||||
0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
|
||||
0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
|
||||
0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
|
||||
0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
|
||||
0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
|
||||
0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
|
||||
0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
|
||||
0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
|
||||
0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
|
||||
0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
|
||||
0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
|
||||
0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
|
||||
0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
|
||||
0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
|
||||
0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
|
||||
0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
|
||||
0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
|
||||
0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
|
||||
0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
|
||||
0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
|
||||
0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
|
||||
0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
|
||||
0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
|
||||
0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
|
||||
0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
|
||||
0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
|
||||
0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
|
||||
0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
|
||||
0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
|
||||
0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
|
||||
0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
|
||||
0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
|
||||
0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
|
||||
0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
|
||||
0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
|
||||
0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
|
||||
0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
|
||||
0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
|
||||
0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
|
||||
0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
|
||||
0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
|
||||
0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
|
||||
0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
|
||||
0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
|
||||
0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
|
||||
0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
|
||||
0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
|
||||
0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
|
||||
0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
|
||||
0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
|
||||
0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
|
||||
0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
|
||||
0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
|
||||
0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
|
||||
0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
|
||||
0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
|
||||
};
|
||||
|
||||
#define CRC32(c,crc) (CRC32_Table[((unsigned long)(crc) ^ (c)) & 0xFFL] ^ (((crc) >> 8) & 0x00FFFFFFL))
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CRC_Memory -- calculates a CRC for a block of memory *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
unsigned long CRC_Memory( const unsigned char *data, unsigned long length, unsigned long crc )
|
||||
{
|
||||
crc ^= 0xFFFFFFFF; // invert previous CRC
|
||||
while ( length-- ) {
|
||||
crc = CRC32( *data++, crc ); // calc crc for each byte
|
||||
}
|
||||
return (crc ^ 0xFFFFFFFF); // invert new CRC and return it
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CRC_String -- Calculates a CRC for a NULL-terminated string *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
unsigned long CRC_String( const char *string, unsigned long crc )
|
||||
{
|
||||
crc ^= 0xFFFFFFFF; // invert previous CRC
|
||||
while ( *string ) {
|
||||
crc = CRC32( *string++, crc ); // calc crc for each byte
|
||||
}
|
||||
return (crc ^ 0xFFFFFFFF); // invert new CRC and return it
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* CRC_Stringi -- Calculates a CRC for a string, case-insensitive *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*=============================================================================================*/
|
||||
unsigned long CRC_Stringi( const char *string, unsigned long crc )
|
||||
{
|
||||
crc ^= 0xFFFFFFFF; // invert previous CRC
|
||||
while ( *string ) {
|
||||
char c = (char)toupper(*string++);
|
||||
crc = CRC32( c, crc ); // calc crc for each byte
|
||||
}
|
||||
return (crc ^ 0xFFFFFFFF); // invert new CRC and return it
|
||||
}
|
||||
49
Code/Tools/pluglib/realcrc.h
Normal file
49
Code/Tools/pluglib/realcrc.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Westwood Library *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/realcrc.h $*
|
||||
* *
|
||||
* Author:: Byon Garrabrant *
|
||||
* *
|
||||
* $Modtime:: 4/02/99 12:00p $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef REALCRC_H
|
||||
#define REALCRC_H
|
||||
|
||||
|
||||
unsigned long CRC_Memory( const unsigned char *data, unsigned long length, unsigned long crc = 0 );
|
||||
unsigned long CRC_String( const char *string, unsigned long crc = 0 );
|
||||
unsigned long CRC_Stringi( const char *string, unsigned long crc = 0 );
|
||||
|
||||
|
||||
#endif
|
||||
231
Code/Tools/pluglib/rgb.cpp
Normal file
231
Code/Tools/pluglib/rgb.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Library/RGB.CPP $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 7/22/97 11:37a $*
|
||||
* *
|
||||
* $Revision:: 1 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* RGBClass::Adjust -- Adjust one RGB value toward another. *
|
||||
* RGBClass::Difference -- Determines the "distance" between two colors. *
|
||||
* RGBClass::operator HSVClass -- Conversion operator for RGB to HSV object. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "always.h"
|
||||
#include "hsv.h"
|
||||
#include "palette.h"
|
||||
#include "rgb.h"
|
||||
|
||||
RGBClass const BlackColor(0, 0, 0);
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* RGBClass::Adjust -- Adjust one RGB value toward another. *
|
||||
* *
|
||||
* This routine is used to modify an RGB value to proportionately match another RGB value *
|
||||
* according to the ratio parameter specified. Typical use of this routine is in palette *
|
||||
* fading from one palette to another or to black. *
|
||||
* *
|
||||
* INPUT: ratio -- The ration of transformation. This value is in the form of 0 to 255, *
|
||||
* with 0 being no change, and 255 being 100% transformed into the *
|
||||
* destination color. *
|
||||
* *
|
||||
* rgb -- Reference to the destination RGB color to transform this color into. *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
void RGBClass::Adjust(int ratio, RGBClass const & rgb)
|
||||
{
|
||||
/*
|
||||
** Ratio conversion is limited to 0 through 100%. This is
|
||||
** the range of 0 to 255.
|
||||
*/
|
||||
ratio &= 0x00FF;
|
||||
|
||||
|
||||
/*
|
||||
** Adjust the color guns by the ratio specified toward the
|
||||
** destination color.
|
||||
*/
|
||||
int value = (int)rgb.Red - (int)Red;
|
||||
Red = (unsigned char)((int)Red + (value * ratio) / 256);
|
||||
|
||||
value = (int)rgb.Green - (int)Green;
|
||||
Green = (unsigned char)((int)Green + (value * ratio) / 256);
|
||||
|
||||
value = (int)rgb.Blue - (int)Blue;
|
||||
Blue = (unsigned char)((int)Blue + (value * ratio) / 256);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* RGBClass::Difference -- Determines the "distance" between two colors. *
|
||||
* *
|
||||
* This routine is used to calculate a relative distance between two colors. The value is *
|
||||
* relative only to itself and thus is useful only for determining the magnitude of *
|
||||
* color difference rather than the nature of the color difference. Palette remapping *
|
||||
* code uses this routine to find closest matches for colors. *
|
||||
* *
|
||||
* INPUT: rgb -- Reference to the color to be compared to this color. *
|
||||
* *
|
||||
* OUTPUT: Returns the difference between the two colors. The value returned is zero if the *
|
||||
* colors exactly match. The greater the positive value the greater the difference *
|
||||
* between the colors. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/02/1995 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
int RGBClass::Difference(RGBClass const & rgb) const
|
||||
{
|
||||
int r = (int)Red - (int)rgb.Red;
|
||||
if (r < 0) r = -r;
|
||||
|
||||
int g = (int)Green - (int)rgb.Green;
|
||||
if (g < 0) g = -g;
|
||||
|
||||
int b = (int)Blue - (int)rgb.Blue;
|
||||
if (b < 0) b = -b;
|
||||
|
||||
/*
|
||||
** At first crack, the difference algorithm might be coded as the sum of the color differences
|
||||
** (or sum of the square of the color distances). However, this would not take advantage of the
|
||||
** fact that the human eye is most sensative to green, followed by the color blue. With this
|
||||
** thought in mind, the following difference algorithm is used.
|
||||
*/
|
||||
return(4*g + 3*b + 2*r);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* RGBClass::operator HSVClass -- Conversion operator for RGB to HSV object. *
|
||||
* *
|
||||
* This conversion operator will convert an RGBClass object into an HSVClass object. *
|
||||
* *
|
||||
* INPUT: none *
|
||||
* *
|
||||
* OUTPUT: Returns with a reference (implicit) to the HSVClass object that most closely *
|
||||
* represents the RGBClass object. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/20/1996 JLB : Created. *
|
||||
*=============================================================================================*/
|
||||
RGBClass::operator HSVClass (void) const
|
||||
{
|
||||
int hue;
|
||||
int saturation;
|
||||
int value;
|
||||
|
||||
/*
|
||||
** Fetch working component values for the color guns.
|
||||
*/
|
||||
int red = Get_Red();
|
||||
int green = Get_Green();
|
||||
int blue = Get_Blue();
|
||||
|
||||
/*
|
||||
** The hue defaults to none. Only if there is a saturation value will the
|
||||
** hue be calculated.
|
||||
*/
|
||||
hue = 0;
|
||||
|
||||
/*
|
||||
** Set the value (brightness) to match the brightest color gun.
|
||||
*/
|
||||
value = (red > green) ? red : green;
|
||||
if (blue > value) value = blue;
|
||||
|
||||
/*
|
||||
** Determine the amount of true white present in the color. This is the
|
||||
** minimum color gun value. The white component is used to determine
|
||||
** color saturation.
|
||||
*/
|
||||
int white = (red < green) ? red : green;
|
||||
if (blue < white) white = blue;
|
||||
|
||||
/*
|
||||
** Determine the saturation (intensity) of the color by comparing the
|
||||
** ratio of true white as a component of the overall color. The more
|
||||
** white component, the less saturation.
|
||||
*/
|
||||
saturation = 0;
|
||||
if (value) {
|
||||
saturation = ((value - white) * 255) / value;
|
||||
}
|
||||
|
||||
/*
|
||||
** If there is any saturation at all, then the hue must be calculated. The
|
||||
** hue is based on a six sided color wheel.
|
||||
*/
|
||||
if (saturation != 0) {
|
||||
unsigned int tmp = value - white;
|
||||
unsigned int r1 = ((value - red) * 255) / tmp;
|
||||
unsigned int g1 = ((value - green) * 255) / tmp;
|
||||
unsigned int b1 = ((value - blue) * 255) / tmp;
|
||||
|
||||
// Find effect of second most predominant color.
|
||||
// In which section of the hexagon of colors does the color lie?
|
||||
if (value == red) {
|
||||
if (white == green) {
|
||||
tmp = 5 * 256 + b1;
|
||||
} else {
|
||||
tmp = 1 * 256 - g1;
|
||||
}
|
||||
} else {
|
||||
if (value == green) {
|
||||
if (white == blue) {
|
||||
tmp = 1 * 256 + r1;
|
||||
} else {
|
||||
tmp = 3 * 256 - b1;
|
||||
}
|
||||
} else {
|
||||
if (white == red) {
|
||||
tmp = 3 * 256 + g1;
|
||||
} else {
|
||||
tmp = 5 * 256 - r1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divide by six and round.
|
||||
hue = tmp / 6;
|
||||
}
|
||||
|
||||
HSVClass hsv((unsigned char)hue, (unsigned char)saturation, (unsigned char)value);
|
||||
return(hsv);
|
||||
}
|
||||
|
||||
95
Code/Tools/pluglib/rgb.h
Normal file
95
Code/Tools/pluglib/rgb.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/RGB.H $*
|
||||
* *
|
||||
* $Author:: Eric_c $*
|
||||
* *
|
||||
* $Modtime:: 4/02/99 12:00p $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef RGB_H
|
||||
#define RGB_H
|
||||
|
||||
class PaletteClass;
|
||||
class HSVClass;
|
||||
|
||||
|
||||
/*
|
||||
** Each color entry is represented by this class. It holds the values for the color
|
||||
** guns. The gun values are recorded in device dependant format, but the interface
|
||||
** uses gun values from 0 to 255.
|
||||
*/
|
||||
class RGBClass
|
||||
{
|
||||
public:
|
||||
RGBClass(void) : Red(0), Green(0), Blue(0) {}
|
||||
RGBClass(unsigned char red, unsigned char green, unsigned char blue) : Red(red), Green(green), Blue(blue) {}
|
||||
operator HSVClass (void) const;
|
||||
RGBClass & operator = (RGBClass const & rgb) {
|
||||
if (this == &rgb) return(*this);
|
||||
|
||||
Red = rgb.Red;
|
||||
Green = rgb.Green;
|
||||
Blue = rgb.Blue;
|
||||
return(*this);
|
||||
}
|
||||
|
||||
enum {
|
||||
MAX_VALUE=255
|
||||
};
|
||||
|
||||
void Adjust(int ratio, RGBClass const & rgb);
|
||||
int Difference(RGBClass const & rgb) const;
|
||||
int Get_Red(void) const {return (Red);}
|
||||
int Get_Green(void) const {return(Green);}
|
||||
int Get_Blue(void) const {return(Blue);}
|
||||
void Set_Red(unsigned char value) {Red = value;}
|
||||
void Set_Green(unsigned char value) {Green = value;}
|
||||
void Set_Blue(unsigned char value) {Blue = value;}
|
||||
|
||||
private:
|
||||
|
||||
friend class PaletteClass;
|
||||
|
||||
/*
|
||||
** These hold the actual color gun values in machine independant scale. This
|
||||
** means the values range from 0 to 255.
|
||||
*/
|
||||
unsigned char Red;
|
||||
unsigned char Green;
|
||||
unsigned char Blue;
|
||||
};
|
||||
|
||||
extern RGBClass const BlackColor;
|
||||
|
||||
#endif
|
||||
291
Code/Tools/pluglib/tri.cpp
Normal file
291
Code/Tools/pluglib/tri.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/tri.cpp $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 3/12/02 10:21a $*
|
||||
* *
|
||||
* $Revision:: 10 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* TriClass::Find_Dominant_Plane -- returns indices of the axes of the dominant plane *
|
||||
* TriClass::Contains_Point -- performs 2D point-in-triangle test. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "tri.h"
|
||||
#include "vector2.h"
|
||||
|
||||
|
||||
|
||||
static inline void find_dominant_plane(const TriClass & tri, int * axis1,int * axis2,int * axis3)
|
||||
{
|
||||
/*
|
||||
** Find the largest component of the normal
|
||||
*/
|
||||
int ni = 0;
|
||||
float x = WWMath::Fabs(tri.N->X);
|
||||
float y = WWMath::Fabs(tri.N->Y);
|
||||
float z = WWMath::Fabs(tri.N->Z);
|
||||
float val = x;
|
||||
|
||||
if (y > val) {
|
||||
ni = 1;
|
||||
val = y;
|
||||
}
|
||||
|
||||
if (z > val) {
|
||||
ni = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
** return the indices of the two axes perpendicular
|
||||
*/
|
||||
switch (ni)
|
||||
{
|
||||
case 0:
|
||||
// Dominant is the X axis
|
||||
*axis1 = 1;
|
||||
*axis2 = 2;
|
||||
*axis3 = 0;
|
||||
break;
|
||||
case 1:
|
||||
// Dominant is the Y axis
|
||||
*axis1 = 0;
|
||||
*axis2 = 2;
|
||||
*axis3 = 1;
|
||||
break;
|
||||
case 2:
|
||||
// Dominant is the Z axis
|
||||
*axis1 = 0;
|
||||
*axis2 = 1;
|
||||
*axis3 = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* TriClass::Find_Dominant_Plane -- returns indices of the axes of the dominant plane *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 3/24/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void TriClass::Find_Dominant_Plane(int * axis1,int * axis2) const
|
||||
{
|
||||
/*
|
||||
** Find the largest component of the normal
|
||||
*/
|
||||
int ni = 0;
|
||||
float x = WWMath::Fabs(N->X);
|
||||
float y = WWMath::Fabs(N->Y);
|
||||
float z = WWMath::Fabs(N->Z);
|
||||
float val = x;
|
||||
|
||||
if (y > val) {
|
||||
ni = 1;
|
||||
val = y;
|
||||
}
|
||||
|
||||
if (z > val) {
|
||||
ni = 2;
|
||||
}
|
||||
|
||||
/*
|
||||
** return the indices of the two axes perpendicular
|
||||
*/
|
||||
switch (ni)
|
||||
{
|
||||
case 0:
|
||||
// Dominant is the X axis
|
||||
*axis1 = 1;
|
||||
*axis2 = 2;
|
||||
break;
|
||||
case 1:
|
||||
// Dominant is the Y axis
|
||||
*axis1 = 0;
|
||||
*axis2 = 2;
|
||||
break;
|
||||
case 2:
|
||||
// Dominant is the Z axis
|
||||
*axis1 = 0;
|
||||
*axis2 = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* TriClass::Contains_Point -- performs 2D point-in-triangle test. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Assumes that the point is in the plane of the triangle... use this after you've intersected *
|
||||
* a ray with the plane of the triangle. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 3/24/99 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
bool TriClass::Contains_Point(const Vector3 & ipoint) const
|
||||
{
|
||||
#if 0
|
||||
/*
|
||||
** Perform the test in 2d on the plane which the normal
|
||||
** is most perpendicular to. (copied from E.Cosky's intersection code)
|
||||
*/
|
||||
int axis1 = 0;
|
||||
int axis2 = 0;
|
||||
Find_Dominant_Plane(&axis1,&axis2);
|
||||
|
||||
#if 1
|
||||
unsigned char flags; // dummy variable passed into function and not used here
|
||||
return Point_In_Triangle_2D(*V[0], *V[1], *V[2], ipoint, axis1, axis2, flags);
|
||||
#else
|
||||
float u0 = ipoint[axis1] - (*V[0])[axis1];
|
||||
float v0 = ipoint[axis2] - (*V[0])[axis2];
|
||||
|
||||
/*
|
||||
** determine the 2d vectors on the dominant plane from the first vertex to the other two
|
||||
*/
|
||||
float u1 = (*V[1])[axis1] - (*V[0])[axis1];
|
||||
float v1 = (*V[1])[axis2] - (*V[0])[axis2];
|
||||
float u2 = (*V[2])[axis1] - (*V[0])[axis1];
|
||||
float v2 = (*V[2])[axis2] - (*V[0])[axis2];
|
||||
|
||||
float alpha, beta;
|
||||
bool intersect = false;
|
||||
|
||||
// calculate alpha and beta as normalized (0..1) percentages across the 2d projected triangle
|
||||
// and do bounds checking (sum <= 1) to determine whether or not the triangle intersection occurs.
|
||||
if (u1 == 0) {
|
||||
beta = u0 / u2;
|
||||
if ((beta >= 0) && (beta <= 1)) {
|
||||
alpha = (v0 - beta * v2) / v1;
|
||||
intersect = ((alpha >= 0) && ((alpha + beta) <= 1 + WWMATH_EPSILON));
|
||||
}
|
||||
} else {
|
||||
beta = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
|
||||
if ((beta >= 0) && (beta <= 1)) {
|
||||
alpha = (u0 - beta * u2) / u1;
|
||||
intersect = ((alpha >= 0) && ((alpha + beta) <= 1 + WWMATH_EPSILON));
|
||||
}
|
||||
}
|
||||
|
||||
return intersect;
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
** New cross-product based point-containment
|
||||
*/
|
||||
#if 0
|
||||
int vi;
|
||||
int axis3 = 0;
|
||||
|
||||
for (vi=0; vi<3; vi++) {
|
||||
if ((axis1 != vi) && (axis2 != vi)) axis3 = vi;
|
||||
}
|
||||
|
||||
Vector3 test_point = ipoint;
|
||||
test_point[axis3] = 0.0f;
|
||||
|
||||
Vector3 points[3];
|
||||
for (vi=0; vi<3; vi++) {
|
||||
points[vi] = *(V[vi]);
|
||||
points[vi][axis3] = 0.0f;
|
||||
}
|
||||
|
||||
bool side[3];
|
||||
Vector3 edge;
|
||||
Vector3 cross;
|
||||
Vector3 dp;
|
||||
|
||||
for (vi=0; vi<3; vi++) {
|
||||
edge = points[(vi+1)%3] - points[vi];
|
||||
dp = test_point - points[vi];
|
||||
|
||||
Vector3::Cross_Product(dp,edge,&cross);
|
||||
side[vi] = (cross[axis3] > 0.0f);
|
||||
}
|
||||
|
||||
bool my_intersect = ((side[0] == side[1]) && (side[1] == side[2]));
|
||||
return my_intersect;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** "Optimized" version
|
||||
*/
|
||||
#if 1
|
||||
int vi;
|
||||
int axis1 = 0;
|
||||
int axis2 = 0;
|
||||
int axis3 = 0;
|
||||
|
||||
find_dominant_plane(*this,&axis1,&axis2,&axis3);
|
||||
|
||||
int side_mask = 0;
|
||||
const int POS = 0x01;
|
||||
const int NEG = 0x02;
|
||||
|
||||
/*
|
||||
** Compute the 2D cross product of edge0 with a vector to the point
|
||||
*/
|
||||
Vector2 edge;
|
||||
Vector2 dp;
|
||||
|
||||
for (vi=0; vi<3; vi++) {
|
||||
|
||||
int va=vi;
|
||||
int vb=(vi+1)%3;
|
||||
|
||||
edge.Set((*V[vb])[axis1] - (*V[va])[axis1] , (*V[vb])[axis2] - (*V[va])[axis2]);
|
||||
dp.Set(ipoint[axis1] - (*V[va])[axis1] , ipoint[axis2] - (*V[va])[axis2]);
|
||||
float cross = edge.X * dp.Y - edge.Y * dp.X;
|
||||
|
||||
if (cross > WWMATH_EPSILON) {
|
||||
side_mask |= POS;
|
||||
}
|
||||
if (cross < -WWMATH_EPSILON) {
|
||||
side_mask |= NEG;
|
||||
}
|
||||
}
|
||||
|
||||
bool my_intersect = (side_mask != (POS | NEG));
|
||||
return my_intersect;
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
306
Code/Tools/pluglib/tri.h
Normal file
306
Code/Tools/pluglib/tri.h
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/tri.h $*
|
||||
* *
|
||||
* Author:: Greg_h *
|
||||
* *
|
||||
* $Modtime:: 5/04/01 8:35p $*
|
||||
* *
|
||||
* $Revision:: 14 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef TRI_H
|
||||
#define TRI_H
|
||||
|
||||
#include "always.h"
|
||||
#include "vector4.h"
|
||||
#include "vector3.h"
|
||||
#include "vector2.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/**
|
||||
** TriClass
|
||||
** When the math library needs to deal with triangles, this will be the form used.
|
||||
** The initial reason for this class is for Commando's collision detection code. Initially
|
||||
** I wrote custom code inside the render object for the terrain to perform collision
|
||||
** detection. Moving the low-level geometrical collision code into the math library makes it
|
||||
** more re-useable and independent from changes in the rendering code.
|
||||
*/
|
||||
class TriClass
|
||||
{
|
||||
public:
|
||||
|
||||
const Vector3 * N;
|
||||
const Vector3 * V[3];
|
||||
|
||||
void Compute_Normal()
|
||||
{
|
||||
assert(N);
|
||||
assert(V[0]);
|
||||
assert(V[1]);
|
||||
assert(V[2]);
|
||||
|
||||
Vector3::Cross_Product(*(V[1])-*(V[0]),*(V[2])-*(V[0]),(Vector3 *)N);
|
||||
((Vector3 *)N)->Normalize();
|
||||
}
|
||||
|
||||
|
||||
bool Contains_Point(const Vector3 & ipoint) const;
|
||||
void Find_Dominant_Plane(int * axis1,int * axis2) const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** Utility functions:
|
||||
** Functions which have to do with triangles but not neccessarily with TriClass - usually used
|
||||
** by TriClass but also available for use elsewhere.
|
||||
*/
|
||||
|
||||
// Enums for raycast flags (currently used only for semi-infinite axis-aligned rays)
|
||||
enum
|
||||
{
|
||||
TRI_RAYCAST_FLAG_NONE = 0x00,
|
||||
TRI_RAYCAST_FLAG_HIT_EDGE = 0x01,
|
||||
TRI_RAYCAST_FLAG_START_IN_TRI = 0x02
|
||||
};
|
||||
|
||||
// This function does a pure 2D point-in-triangle test. We pass in 3D points both for the
|
||||
// triangle and test points, but we also pass in the two axes to use (the third axis is ignored,
|
||||
// so we are actually testing the projection of the four points onto one of the axis planes). The
|
||||
// triangle points are not assumed to be in any particular winding order (that is checked for
|
||||
// internally). It is used internally by TriClass::Contains_Point(), and may be used elsewhere.
|
||||
// If the ray intersects the camera at an edge we also count it as an intersection. We set a bit
|
||||
// in 'flags' to true in this case (some users of this function need this extra information and
|
||||
// it is very cheap to compute). We do not modify 'flags' if no edges are hit, so it must be
|
||||
// initialized outside this function if its value is to be used.
|
||||
inline bool Point_In_Triangle_2D(const Vector3 &tri_point0, const Vector3 &tri_point1,
|
||||
const Vector3 &tri_point2, const Vector3 &test_point, int axis_1, int axis_2,
|
||||
unsigned char &flags)
|
||||
{
|
||||
// The function is based on checking signs of determinants, or in a more visually intuitive
|
||||
// sense, checking on which side of a line a point lies. For example, if the points run in
|
||||
// counter-clockwise order, the interior of the triangle is the intersection of the three
|
||||
// half-planes to the left of the directed infinite lines along P0 to P1, P1 to P2, P2 to P0.
|
||||
// Therefore the test point is in the triangle iff it is to the left of all three lines (if
|
||||
// the points are in clockwise order, we check if it is to the right of the lines).
|
||||
Vector2 p0p1(tri_point1[axis_1] - tri_point0[axis_1], tri_point1[axis_2] - tri_point0[axis_2]);
|
||||
Vector2 p1p2(tri_point2[axis_1] - tri_point1[axis_1], tri_point2[axis_2] - tri_point1[axis_2]);
|
||||
Vector2 p2p0(tri_point0[axis_1] - tri_point2[axis_1], tri_point0[axis_2] - tri_point2[axis_2]);
|
||||
|
||||
// Check which side P2 is relative to P0P1. The sign of this test must equal the sign of all
|
||||
// three tests between the lines and the test point for the test point to be inside the
|
||||
// triangle. (this test will also tell us if the three points are colinear - if the triangle
|
||||
// is degenerate).
|
||||
Vector2 p0p2(tri_point2[axis_1] - tri_point0[axis_1], tri_point2[axis_2] - tri_point0[axis_2]);
|
||||
float p0p1p2 = Vector2::Perp_Dot_Product(p0p1, p0p2);
|
||||
if (p0p1p2 != 0.0f) {
|
||||
|
||||
// The triangle is not degenerate - test three sides
|
||||
float side_factor = p0p1p2 > 0.0f ? 1.0f : -1.0f;
|
||||
float factors[3];
|
||||
|
||||
// Now perform tests
|
||||
Vector2 p0pT(test_point[axis_1] - tri_point0[axis_1], test_point[axis_2] - tri_point0[axis_2]);
|
||||
factors[0] = Vector2::Perp_Dot_Product(p0p1, p0pT);
|
||||
if (factors[0] * side_factor < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
Vector2 p1pT(test_point[axis_1] - tri_point1[axis_1], test_point[axis_2] - tri_point1[axis_2]);
|
||||
factors[1] = Vector2::Perp_Dot_Product(p1p2, p1pT);
|
||||
if (factors[1] * side_factor < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
Vector2 p2pT(test_point[axis_1] - tri_point2[axis_1], test_point[axis_2] - tri_point2[axis_2]);
|
||||
factors[2] = Vector2::Perp_Dot_Product(p2p0, p2pT);
|
||||
if (factors[2] * side_factor < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
if ((factors[0] == 0.0f) || (factors[1] == 0.0f) || (factors[2] == 0.0f)) flags |= TRI_RAYCAST_FLAG_HIT_EDGE;
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
// The triangle is degenerate. This should be a rare case, so it does not matter much if it
|
||||
// is a little slower than the non-colinear case.
|
||||
|
||||
// Find the two outer points along the triangle's line ('start' and 'end' points)
|
||||
float p0p1dist2 = p0p1.Length2();
|
||||
float p1p2dist2 = p1p2.Length2();
|
||||
float p2p0dist2 = p1p2.Length2();
|
||||
float max_dist2;
|
||||
Vector2 pSpE, pSpT; // 'end' point, test point - both in 'start' points' frame
|
||||
if (p0p1dist2 > p1p2dist2) {
|
||||
if (p0p1dist2 > p2p0dist2) {
|
||||
// points 0 and 1 are the 'outer' points. 0 is 'start' and 1 is 'end'.
|
||||
pSpE = p0p1;
|
||||
pSpT.Set(test_point[axis_1] - tri_point0[axis_1], test_point[axis_2] - tri_point0[axis_2]);
|
||||
max_dist2 = p0p1dist2;
|
||||
} else {
|
||||
// points 0 and 2 are the 'outer' points. 2 is 'start' and 0 is 'end'.
|
||||
pSpE = p2p0;
|
||||
pSpT.Set(test_point[axis_1] - tri_point2[axis_1], test_point[axis_2] - tri_point2[axis_2]);
|
||||
max_dist2 = p2p0dist2;
|
||||
}
|
||||
} else {
|
||||
if (p1p2dist2 > p2p0dist2) {
|
||||
// points 1 and 2 are the 'outer' points. 1 is 'start' and 2 is 'end'.
|
||||
pSpE = p1p2;
|
||||
pSpT.Set(test_point[axis_1] - tri_point1[axis_1], test_point[axis_2] - tri_point1[axis_2]);
|
||||
max_dist2 = p1p2dist2;
|
||||
} else {
|
||||
// points 0 and 2 are the 'outer' points. 2 is 'start' and 0 is 'end'.
|
||||
pSpE = p2p0;
|
||||
pSpT.Set(test_point[axis_1] - tri_point2[axis_1], test_point[axis_2] - tri_point2[axis_2]);
|
||||
max_dist2 = p2p0dist2;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_dist2 != 0.0f) {
|
||||
// Triangle is line segment, check if test point is colinear with it
|
||||
if (Vector2::Perp_Dot_Product(pSpE, pSpT)) {
|
||||
// Not colinear
|
||||
return false;
|
||||
} else {
|
||||
// Colinear - is test point's distance from start and end <= segment length?
|
||||
Vector2 pEpT = pSpT - pSpE;
|
||||
if (pSpT.Length2() <= max_dist2 && pEpT.Length2() <= max_dist2) {
|
||||
flags |= TRI_RAYCAST_FLAG_HIT_EDGE;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// All triangle points coincide, check if test point coincides with them
|
||||
if (pSpT.Length2() == 0.0f) {
|
||||
flags |= TRI_RAYCAST_FLAG_HIT_EDGE;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This function tests a semi-infinite axis-aligned ray vs. a triangle.
|
||||
// The inputs are blah blah blah
|
||||
inline bool Cast_Semi_Infinite_Axis_Aligned_Ray_To_Triangle(const Vector3 &tri_point0,
|
||||
const Vector3 &tri_point1, const Vector3 &tri_point2, const Vector4 &tri_plane,
|
||||
const Vector3 &ray_start, int axis_r, int axis_1, int axis_2, int direction,
|
||||
unsigned char & flags)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
// First check infinite ray vs. triangle (2D check)
|
||||
unsigned char flags_2d = TRI_RAYCAST_FLAG_NONE;
|
||||
if (Point_In_Triangle_2D(tri_point0, tri_point1, tri_point2, ray_start, axis_1, axis_2, flags_2d)) {
|
||||
|
||||
// NOTE: SR plane equations, unlike WWMath's PlaneClass, use the Ax+By+Cz+D = 0
|
||||
// representation. It can also be viewed as C0x+C1y+C2z+C3 = dist where dist is the
|
||||
// signed distance from the plane (and therefore the plane is defined as those points
|
||||
// where dist = 0). Now that we know that the projection along the ray is inside the
|
||||
// triangle, determining whether the ray hits the triangle is a matter of determining
|
||||
// whether the start point is on the triangle plane's "anti-rayward side" (the side
|
||||
// which the ray points away from).
|
||||
// To determine this, we will use C[axis_r] (the plane coefficient of the ray axis).
|
||||
// This coefficient is positive if the positive direction of the ray axis points into
|
||||
// the planes' positive halfspace and negative if it points into the planes' negative
|
||||
// halfspace (it is zero if the ray axis is parallel to the triangle plane). If we
|
||||
// multiply this by 'sign' which is defined to be -1.0 if 'direction' equals 0 and
|
||||
// 1.0 if 'direction' equals 1, we will get a number which is positive or negative
|
||||
// depending on which halfspace the ray itself (as opposed to the rays axis) points
|
||||
// towards. If we further multiply this by dist(start point) - the result of plugging
|
||||
// the start point into the plane equation - we will get a number which is positive
|
||||
// if the start point is on the 'rayward side' (ray does not intersect the triangle)
|
||||
// and is negative if the start point is on the 'anti-rayward side' (ray does
|
||||
// intersect triangle). In either of these two cases we are done.
|
||||
// (see below for what happens when the result is zero - more checks need to be made).
|
||||
static const float sign[2] = {-1.0f, 1.0f };
|
||||
float result = tri_plane[axis_r] * sign[direction] * (tri_plane.X * ray_start.X +
|
||||
tri_plane.Y * ray_start.Y + tri_plane.Z * ray_start.Z + tri_plane.W);
|
||||
if (result < 0.0f) {
|
||||
// Intersection!
|
||||
flags |= (flags_2d & TRI_RAYCAST_FLAG_HIT_EDGE);
|
||||
retval = true;
|
||||
} else {
|
||||
if (result == 0.0f) {
|
||||
// If the result is 0, this means either the ray is parallel to the triangle
|
||||
// plane or the start point is embedded in the triangle plane. Note that since
|
||||
// the start point passed the 2D check, then if the ray is parallel the start
|
||||
// point must also be embedded in the triangle plane. This leaves us with two
|
||||
// cases:
|
||||
// A) The ray is not parallel to the plane - in this case the start point is
|
||||
// embedded in the triangle. We report an intersection, bitwise OR the edge
|
||||
// result from the 2D check into the 'edge hit' flag and set the 'start in tri'
|
||||
// flag.
|
||||
// B) The ray is parallel to the plane. In this case the result of the 2D test
|
||||
// tells us that the infinite line intersects the triangle (actually is
|
||||
// embedded in the triangle along part of its length), but we do not know
|
||||
// whether the semi-infinite ray also does so. We simplify things by not
|
||||
// counting such an 'intersection'. There are four reasons behind this:
|
||||
// 1. It differs from a 'normal' intersection (which has one intersecting
|
||||
// point) - there are infinitely many intersecting points.
|
||||
// 2. Moving the plane by an infinitesimally small amount to either side will
|
||||
// cause the ray to no longer touch the plane.
|
||||
// 3. This will not affect results for the known uses of this function.
|
||||
// 4. By doing so we avoid having to code up a bunch of complex tests.
|
||||
// Therefore in case B) we just report no intersection. We still need to find
|
||||
// out whether the point is embedded in the triangle (for setting the flag) so
|
||||
// we do another simple 2D test on the dominant plane.
|
||||
if (tri_plane[axis_r]) {
|
||||
// Case A)
|
||||
flags |= (flags_2d & TRI_RAYCAST_FLAG_HIT_EDGE);
|
||||
flags |= TRI_RAYCAST_FLAG_START_IN_TRI;
|
||||
retval = true;
|
||||
} else {
|
||||
// Case B) - test if point in tri (we know it is in plane, so we can use
|
||||
// TriClass function)
|
||||
TriClass tri;
|
||||
tri.V[0] = &tri_point0;
|
||||
tri.V[1] = &tri_point1;
|
||||
tri.V[2] = &tri_point2;
|
||||
tri.N = (Vector3*)&tri_plane;
|
||||
if (tri.Contains_Point(ray_start)) {
|
||||
flags |= TRI_RAYCAST_FLAG_START_IN_TRI;
|
||||
}
|
||||
}
|
||||
} // if (result == 0.0f)
|
||||
} // else (result < 0.0f)
|
||||
} // if Point_In_Triangle_2D()
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
||||
228
Code/Tools/pluglib/uarray.h
Normal file
228
Code/Tools/pluglib/uarray.h
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Library *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/uarray.h $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 9/24/99 1:56p $*
|
||||
* *
|
||||
* $Revision:: 7 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* UniqueArrayClass<T>::UniqueArrayClass -- constructor *
|
||||
* UniqueArrayClass<T>::~UniqueArrayClass -- destructor *
|
||||
* UniqueArrayClass<T>::Add -- Add an item to the array *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef UARRAY_H
|
||||
#define UARRAY_H
|
||||
|
||||
#ifndef HASHCALC_H
|
||||
#include "hashcalc.h"
|
||||
#endif
|
||||
|
||||
#ifndef VECTOR_H
|
||||
#include "vector.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** UniqueArrayClass
|
||||
** This template class can be used to generate an array of unique objects
|
||||
** amongst a huge list of objects which may or may not be unique. However,
|
||||
** in order to use the UniqueArrayClass, you will need to implement a
|
||||
** HashCalculatorClass for the type you are using.
|
||||
**
|
||||
** Note that the UniqueArrayClass does *copies* of the objects you are
|
||||
** giving it. It is meant to be used with relatively lightweight objects.
|
||||
*/
|
||||
template <class T> class UniqueArrayClass
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
UniqueArrayClass(int initialsize,int growthrate,HashCalculatorClass<T> * hasher);
|
||||
~UniqueArrayClass(void);
|
||||
|
||||
int Add(const T & new_item);
|
||||
|
||||
int Count(void) const { return Get_Unique_Count(); }
|
||||
int Get_Unique_Count(void) const { return UniqueItems.Count(); }
|
||||
const T & Get(int index) const { return UniqueItems[index].Item; }
|
||||
const T & operator [] (int index) const { return Get(index); }
|
||||
|
||||
private:
|
||||
|
||||
enum { NO_ITEM = 0xFFFFFFFF };
|
||||
|
||||
class HashItem
|
||||
{
|
||||
public:
|
||||
T Item;
|
||||
int NextHashIndex;
|
||||
|
||||
bool operator == (const HashItem & that) { return ((Item == that.Item) && (NextHashIndex == that.NextHashIndex)); }
|
||||
bool operator != (const HashItem & that) { return !(*this == that); }
|
||||
};
|
||||
|
||||
// Dynamic Vector of the unique items:
|
||||
DynamicVectorClass<HashItem> UniqueItems;
|
||||
|
||||
// Hash table:
|
||||
int HashTableSize;
|
||||
int * HashTable;
|
||||
|
||||
// object which does the hashing for the type
|
||||
HashCalculatorClass<T> * HashCalculator;
|
||||
|
||||
friend class VectorClass<T>;
|
||||
friend class DynamicVectorClass<T>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* UniqueArrayClass<T>::UniqueArrayClass -- constructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 5/29/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
template <class T>
|
||||
UniqueArrayClass<T>::UniqueArrayClass(int initial_size,int growth_rate,HashCalculatorClass<T> * hasher) :
|
||||
UniqueItems(initial_size),
|
||||
HashCalculator(hasher)
|
||||
{
|
||||
// set the growth rate.
|
||||
UniqueItems.Set_Growth_Step(growth_rate);
|
||||
|
||||
// sizing and allocating the actual hash table
|
||||
int bits = HashCalculator->Num_Hash_Bits();
|
||||
assert(bits > 0);
|
||||
assert(bits < 24);
|
||||
HashTableSize = 1<<bits;
|
||||
HashTable = new int[HashTableSize];
|
||||
|
||||
for (int hidx=0; hidx < HashTableSize; hidx++) {
|
||||
HashTable[hidx] = NO_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* UniqueArrayClass<T>::~UniqueArrayClass -- destructor *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 5/29/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
template <class T>
|
||||
UniqueArrayClass<T>::~UniqueArrayClass(void)
|
||||
{
|
||||
if (HashTable != NULL) {
|
||||
delete[] HashTable;
|
||||
HashTable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* UniqueArrayClass<T>::Add -- Add an item to the array *
|
||||
* *
|
||||
* Only adds the item to the end of the array if another duplicate item is not found. Returns *
|
||||
* the array index of where the item is stored. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 5/29/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
template <class T>
|
||||
inline int UniqueArrayClass<T>::Add(const T & new_item)
|
||||
{
|
||||
/*
|
||||
** Use the hash table to quickly (hopefully :-) detect
|
||||
** whether this item is already in the array
|
||||
*/
|
||||
int num_hash_vals;
|
||||
HashCalculator->Compute_Hash(new_item);
|
||||
num_hash_vals = HashCalculator->Num_Hash_Values();
|
||||
|
||||
unsigned int lasthash = 0xFFFFFFFF;
|
||||
unsigned int hash;
|
||||
|
||||
for (int hidx = 0; hidx < num_hash_vals; hidx++) {
|
||||
hash = HashCalculator->Get_Hash_Value(hidx);
|
||||
if (hash != lasthash) {
|
||||
|
||||
int test_item_index = HashTable[hash];
|
||||
|
||||
while (test_item_index != 0xFFFFFFFF) {
|
||||
if (HashCalculator->Items_Match(UniqueItems[test_item_index].Item,new_item)) {
|
||||
return test_item_index;
|
||||
}
|
||||
test_item_index = UniqueItems[test_item_index].NextHashIndex;
|
||||
}
|
||||
}
|
||||
lasthash = hash;
|
||||
}
|
||||
|
||||
/*
|
||||
** Ok, this is a new item so add it (copy it!) into the array
|
||||
*/
|
||||
int index = UniqueItems.Count();
|
||||
int hash_index = HashCalculator->Get_Hash_Value(0);
|
||||
|
||||
HashItem entry;
|
||||
entry.Item = new_item;
|
||||
entry.NextHashIndex = HashTable[hash_index];
|
||||
HashTable[hash_index] = index;
|
||||
|
||||
UniqueItems.Add(entry);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
#endif // UARRAY_H
|
||||
|
||||
640
Code/Tools/pluglib/vector2.h
Normal file
640
Code/Tools/pluglib/vector2.h
Normal file
@@ -0,0 +1,640 @@
|
||||
/*
|
||||
** 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/wwmath/vector2.h 19 9/01/00 5:30p Ian_l $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 3D *
|
||||
* *
|
||||
* File Name : VECTOR2.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 02/24/97 *
|
||||
* *
|
||||
* Last Update : February 24, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Scalar Division Operator -- Divide a vector by a scalar *
|
||||
* Scalar Multiply Operator -- Multiply a vector by a scalar *
|
||||
* Vector Addition Operator -- Add two vectors *
|
||||
* Vector Subtraction Operator -- Subract two vectors *
|
||||
* Vector Inner Product Operator -- Compute the inner or dot product *
|
||||
* Vector Equality Operator -- Detemine if two vectors are identical *
|
||||
* Equal_Within_Epsilon -- Determine if two vectors are identical within *
|
||||
* Vector Inequality Operator -- Detemine if two vectors are identical *
|
||||
* Swap -- swap two Vector2's *
|
||||
* Vector2::Is_Valid -- Verifies that all components are valid floats *
|
||||
* Vector2::Update_Min -- sets each component of the vector to the min of this and a. *
|
||||
* Vector2::Update_Max -- sets each component of the vector to the max of this and a. *
|
||||
* Vector2::Scale -- multiply components of a vector by independant scaling factors. *
|
||||
* Vector2::Lerp -- linearly interpolates two Vector2's *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef VECTOR2_H
|
||||
#define VECTOR2_H
|
||||
|
||||
#include "always.h"
|
||||
#include "wwmath.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/*
|
||||
** 2-Dimensional Vectors
|
||||
*/
|
||||
|
||||
class Vector2
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
union {
|
||||
float X;
|
||||
float U;
|
||||
};
|
||||
|
||||
union {
|
||||
float Y;
|
||||
float V;
|
||||
};
|
||||
|
||||
// Constructors
|
||||
Vector2(void) {};
|
||||
Vector2(const Vector2 & v) { X = v.X; Y = v.Y; }
|
||||
Vector2(float x, float y) { X = x; Y = y; }
|
||||
Vector2(const float vector[2]) { X = vector[0]; Y = vector[1]; }
|
||||
|
||||
|
||||
// Assignment
|
||||
Vector2 & operator = (const Vector2 & v) { X = v[0]; Y = v[1]; return *this; }
|
||||
void Set(float x, float y) { X = x; Y = y; }
|
||||
void Set(const Vector2 & v) { X = v.X; Y = v.Y; }
|
||||
|
||||
// Array access
|
||||
float & operator [](int i) { return (&X)[i]; }
|
||||
const float & operator [](int i) const { return (&X)[i]; }
|
||||
|
||||
// normalize, compute length
|
||||
void Normalize(void);
|
||||
float Length(void) const;
|
||||
float Length2(void) const;
|
||||
|
||||
// unary operators
|
||||
Vector2 operator-() const { return Vector2(-X,-Y); }
|
||||
Vector2 operator+() const { return *this; }
|
||||
|
||||
Vector2 & operator += (const Vector2 & v) { X += v.X; Y += v.Y; return *this; }
|
||||
Vector2 & operator -= (const Vector2 & v) { X -= v.X; Y -= v.Y; return *this; }
|
||||
Vector2 & operator *= (float k) { X = (float)(X*k); Y=(float)(Y*k); return *this; }
|
||||
Vector2 & operator /= (float k) { k=1.0f/k; X*=k; Y*=k; return *this; }
|
||||
|
||||
// scalar multiplication, division
|
||||
friend Vector2 operator * (const Vector2 &a,float k);
|
||||
friend Vector2 operator * (float k,const Vector2 &a);
|
||||
friend Vector2 operator / (const Vector2 &a,float k);
|
||||
|
||||
// vector addition,subtraction
|
||||
friend Vector2 operator + (const Vector2 &a,const Vector2 &b);
|
||||
friend Vector2 operator - (const Vector2 &a,const Vector2 &b);
|
||||
|
||||
// dot product / inner product
|
||||
friend float operator * (const Vector2 &a,const Vector2 &b);
|
||||
static float Dot_Product(const Vector2 &a,const Vector2 &b);
|
||||
|
||||
// dot product between a and perpendicular vector to b
|
||||
static float Perp_Dot_Product(const Vector2 &a,const Vector2 &b);
|
||||
|
||||
// Equality operators
|
||||
friend bool operator == (const Vector2 &a,const Vector2 &b);
|
||||
friend bool operator != (const Vector2 &a,const Vector2 &b);
|
||||
friend bool Equal_Within_Epsilon(const Vector2 &a,const Vector2 &b,float epsilon);
|
||||
|
||||
// Rotation
|
||||
void Rotate(float theta);
|
||||
void Rotate(float s, float c);
|
||||
bool Rotate_Towards_Vector(Vector2 &target, float max_theta, bool & positive_turn);
|
||||
bool Rotate_Towards_Vector(Vector2 &target, float max_s, float max_c, bool & positive_turn);
|
||||
|
||||
// verify that none of the members of this vector are invalid floats
|
||||
bool Is_Valid(void) const;
|
||||
|
||||
// make this vector the min or max of itself and the passed vector
|
||||
void Update_Min (const Vector2 & a);
|
||||
void Update_Max (const Vector2 & a);
|
||||
void Scale (float a, float b);
|
||||
|
||||
static float Distance(const Vector2 &p1, const Vector2 &p2);
|
||||
static float Quick_Distance(const Vector2 &p1, const Vector2 &p2);
|
||||
|
||||
// interpolate between two Vector2's
|
||||
static void Lerp(const Vector2 & a,const Vector2 & b,float t,Vector2 * set_result);
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Scalar Multiply Operator -- Multiply a vector by a scalar *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
inline Vector2 operator * (const Vector2 &a,float k)
|
||||
{
|
||||
return Vector2((a[0] * k),(a[1] * k));
|
||||
}
|
||||
|
||||
inline Vector2 operator * (float k, const Vector2 &a)
|
||||
{
|
||||
return Vector2((a[0] * k),(a[1] * k));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Scalar Division Operator -- Divide a vector by a scalar *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline Vector2 operator / (const Vector2 &a,float k)
|
||||
{
|
||||
float ook=1.0f/k;
|
||||
return Vector2((a[0] * ook),(a[1] * ook));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Addition Operator -- Add two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
inline Vector2 operator + (const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return Vector2(
|
||||
a.X + b.X,
|
||||
a.Y + b.Y
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Subtraction Operator -- Subract two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
inline Vector2 operator - (const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return Vector2(
|
||||
a.X - b.X,
|
||||
a.Y - b.Y
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Inner Product -- Compute the inner or dot product of two vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline float operator * (const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return a.X*b.X + a.Y*b.Y;
|
||||
}
|
||||
|
||||
inline float Vector2::Dot_Product(const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return a*b;
|
||||
}
|
||||
|
||||
inline float Vector2::Perp_Dot_Product(const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return a.X * -b.Y + a.Y * b.X;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Equality Operator -- Detemine if two vectors are identical *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool operator == (const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return ( (a[0] == b[0]) && (a[1] == b[1]));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Inequality Operator -- Detemine if two vectors are identical *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool operator != (const Vector2 &a,const Vector2 &b)
|
||||
{
|
||||
return ( (a[0] != b[0]) || (a[1] != b[1]));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Equal_Within_Epsilon -- Determine if two vectors are identical within e*
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool Equal_Within_Epsilon(const Vector2 &a,const Vector2 &b,float epsilon)
|
||||
{
|
||||
return( (WWMath::Fabs(a.X - b.X) < epsilon) && (WWMath::Fabs(a.Y - b.Y) < epsilon) );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Normalize -- Normalizes the vector. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline void Vector2::Normalize()
|
||||
{
|
||||
float len2 = Length2();
|
||||
if (len2 != 0.0f) {
|
||||
float oolen = WWMath::Inv_Sqrt(len2);
|
||||
X *= oolen;
|
||||
Y *= oolen;
|
||||
}
|
||||
}
|
||||
|
||||
inline Vector2 Normalize(const Vector2 & vec)
|
||||
{
|
||||
float len2 = vec.Length2();
|
||||
if (len2 != 0.0f) {
|
||||
float oolen = WWMath::Inv_Sqrt(len2);
|
||||
return vec / oolen;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Length -- Returns the length of the vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline float Vector2::Length() const
|
||||
{
|
||||
return (float)WWMath::Sqrt(Length2());
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Length -- Returns the square of the length of the vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline float Vector2::Length2() const
|
||||
{
|
||||
return (X*X + Y*Y);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Rotate -- Rotate vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* float theta - angle to rotate *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline void Vector2::Rotate(float theta)
|
||||
{
|
||||
Rotate(sin(theta), cos(theta));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Rotate -- Rotate vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* s - sine of the angle *
|
||||
* c - cosine of the angle *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline void Vector2::Rotate(float s, float c)
|
||||
{
|
||||
float new_x = X * c + Y * -s;
|
||||
float new_y = X * s + Y * c;
|
||||
X = new_x;
|
||||
Y = new_y;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Rotate -- Rotate towards given vector (stop on reaching it) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* float theta - angle to rotate *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* bool - true if we have reached the desired vector *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* This function assumes both vectors are normalized! *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool Vector2::Rotate_Towards_Vector(Vector2 &target, float max_theta, bool & positive_turn)
|
||||
{
|
||||
return Rotate_Towards_Vector(target, sin(max_theta), cos(max_theta), positive_turn);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector2::Rotate -- Rotate towards given vector (stop on reaching it) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* s - sine of the angle *
|
||||
* c - cosine of the angle *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* bool - true if we have reached the desired vector *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* This function assumes both vectors are normalized! *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool Vector2::Rotate_Towards_Vector(Vector2 &target, float max_s, float max_c, bool & positive_turn)
|
||||
{
|
||||
bool return_value = false;
|
||||
|
||||
positive_turn = Vector2::Perp_Dot_Product(target, *this) > 0.0f;
|
||||
|
||||
if (Vector2::Dot_Product(*this, target) >= max_c) {
|
||||
Set(target);
|
||||
return_value = true;
|
||||
} else {
|
||||
// Determine turn direction and rotate accordingly.
|
||||
if (positive_turn) {
|
||||
Rotate(max_s, max_c);
|
||||
} else {
|
||||
Rotate(-max_s, max_c);
|
||||
}
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Swap -- swap two Vector2's *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/11/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Swap(Vector2 & a,Vector2 & b)
|
||||
{
|
||||
Vector2 tmp(a);
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector2::Is_Valid -- Verifies that all components are valid floats *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline bool Vector2::Is_Valid(void) const
|
||||
{
|
||||
return (WWMath::Is_Valid_Float(X) && WWMath::Is_Valid_Float(Y));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector2::Update_Min -- Set each component of the vector to the min of this and a. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/12/00 IML : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Vector2::Update_Min (const Vector2 & a)
|
||||
{
|
||||
if (a.X < X) X = a.X;
|
||||
if (a.Y < Y) Y = a.Y;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector2::Update_Max -- Set each component of the vector to the max of this and a. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/12/00 IML : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Vector2::Update_Max (const Vector2 & a)
|
||||
{
|
||||
if (a.X > X) X = a.X;
|
||||
if (a.Y > Y) Y = a.Y;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector2::Scale -- multiply components of a vector by independant scaling factors. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/19/2000 IML : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Vector2::Scale (float a, float b)
|
||||
{
|
||||
X *= a;
|
||||
Y *= b;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Quick_Distance -- Fast but inaccurate 2D distance calculation. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/1999MLL: Created. *
|
||||
*=============================================================================================*/
|
||||
inline float Quick_Distance(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
// From Graphic Gems I.
|
||||
float x_diff = x1 - x2;
|
||||
float y_diff = y1 - y2;
|
||||
|
||||
WWMath::Fabs(x_diff);
|
||||
WWMath::Fabs(y_diff);
|
||||
|
||||
if (x_diff > y_diff)
|
||||
{
|
||||
return ((y_diff / 2) + x_diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((x_diff / 2) + y_diff);
|
||||
}
|
||||
}
|
||||
|
||||
inline float Vector2::Quick_Distance(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
return ::Quick_Distance(a.X, a.Y, b.X, b.Y);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Distance -- Accurate distance 2D calculation. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/1999MLL: Created. *
|
||||
*=============================================================================================*/
|
||||
inline float Vector2::Distance(const Vector2 &a, const Vector2 &b)
|
||||
{
|
||||
Vector2 temp;
|
||||
temp = a - b;
|
||||
|
||||
return (temp.Length());
|
||||
}
|
||||
|
||||
inline float Distance(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
float x_diff = x1 - x2;
|
||||
float y_diff = y1 - y2;
|
||||
|
||||
return (WWMath::Sqrt((x_diff * x_diff) + (y_diff * y_diff)));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector2::Lerp -- linearly interpolates two Vector2's *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 4/14/2000 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Vector2::Lerp(const Vector2 & a,const Vector2 & b,float t,Vector2 * set_result)
|
||||
{
|
||||
assert(set_result != NULL);
|
||||
set_result->X = (a.X + (b.X - a.X)*t);
|
||||
set_result->Y = (a.Y + (b.Y - a.Y)*t);
|
||||
}
|
||||
|
||||
|
||||
#endif /* VECTOR2_H */
|
||||
|
||||
926
Code/Tools/pluglib/vector3.h
Normal file
926
Code/Tools/pluglib/vector3.h
Normal file
@@ -0,0 +1,926 @@
|
||||
/*
|
||||
** 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/wwmath/vector3.h 40 5/11/01 7:11p Jani_p $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 3D *
|
||||
* *
|
||||
* File Name : VECTOR3.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 02/24/97 *
|
||||
* *
|
||||
* Last Update : February 24, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Scalar Division Operator -- Divide a vector by a scalar *
|
||||
* Scalar Multiply Operator -- Multiply a vector by a scalar *
|
||||
* Vector Addition Operator -- Add two vectors *
|
||||
* Vector Subtraction Operator -- Subract two vectors *
|
||||
* Vector Inner Product Operator -- Compute the inner or dot product *
|
||||
* Vector Equality Operator -- Determine if two vectors are identical *
|
||||
* Vector Inequality Operator -- Determine if two vectors are identical *
|
||||
* Equal_Within_Epsilon -- Determine if two vectors are identical within *
|
||||
* Cross_Product -- compute the cross product of two vectors *
|
||||
* Vector3::Normalize -- Normalizes the vector. *
|
||||
* Vector3::Length -- Returns the length of the vector *
|
||||
* Vector3::Length2 -- Returns the square of the length of the vector *
|
||||
* Vector3::Quick_Length -- returns a quick approximation of the length *
|
||||
* Swap -- swap two Vector3's *
|
||||
* Lerp -- linearly interpolate two Vector3's by an interpolation factor. *
|
||||
* Lerp -- linearly interpolate two Vector3's without return-by-value *
|
||||
* Vector3::Add -- Add two vector3's without return-by-value *
|
||||
* Vector3::Subtract -- Subtract two vector3's without return-by-value *
|
||||
* Vector3::Update_Min -- sets each component of the vector to the min of this and a *
|
||||
* Vector3::Update_Max -- Sets each component of the vector to the max of this and a *
|
||||
* Vector3::Scale -- scale this vector by 3 independent scale factors *
|
||||
* Vector3::Rotate_X -- rotates this vector around the X axis *
|
||||
* Vector3::Rotate_X -- Rotates this vector around the x axis *
|
||||
* Vector3::Rotate_Y -- Rotates this vector around the y axis *
|
||||
* Vector3::Rotate_Y -- Rotates this vector around the Y axis *
|
||||
* Vector3::Rotate_Z -- Rotates this vector around the Z axis *
|
||||
* Vector3::Rotate_Z -- Rotates this vector around the Z axis *
|
||||
* Vector3::Is_Valid -- Verifies that each component of this vector is a valid float *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef VECTOR3_H
|
||||
#define VECTOR3_H
|
||||
|
||||
#include "always.h"
|
||||
#include "wwmath.h"
|
||||
#include <assert.h>
|
||||
#ifdef _UNIX
|
||||
#include "osdep.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Vector3 - 3-Dimensional Vectors
|
||||
*/
|
||||
class Vector3
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
|
||||
|
||||
// Constructors
|
||||
WWINLINE Vector3(void) {};
|
||||
WWINLINE Vector3(const Vector3 & v) { X = v.X; Y = v.Y; Z = v.Z; }
|
||||
WWINLINE Vector3(float x, float y, float z) { X = x; Y = y; Z = z; }
|
||||
WWINLINE Vector3(const float vector[3]) { X = vector[0]; Y = vector[1]; Z = vector[2]; }
|
||||
|
||||
// Assignment
|
||||
WWINLINE Vector3 & operator = (const Vector3 & v) { X = v.X; Y = v.Y; Z = v.Z; return *this; }
|
||||
WWINLINE void Set(float x, float y, float z) { X = x; Y = y; Z = z; }
|
||||
WWINLINE void Set(const Vector3 & that) { X = that.X; Y = that.Y; Z = that.Z; }
|
||||
|
||||
// Array access
|
||||
WWINLINE float & operator [](int i) { return (&X)[i]; }
|
||||
WWINLINE const float & operator [](int i) const { return (&X)[i]; }
|
||||
|
||||
// normalize, compute length
|
||||
void Normalize(void);
|
||||
WWINLINE float Length(void) const;
|
||||
WWINLINE float Length2(void) const;
|
||||
float Quick_Length(void) const;
|
||||
void Scale(const Vector3 & scale);
|
||||
|
||||
// rotation, (warning, modifies this vector!)
|
||||
WWINLINE void Rotate_X(float angle);
|
||||
WWINLINE void Rotate_X(float s_angle,float c_angle);
|
||||
WWINLINE void Rotate_Y(float angle);
|
||||
WWINLINE void Rotate_Y(float s_angle,float c_angle);
|
||||
WWINLINE void Rotate_Z(float angle);
|
||||
WWINLINE void Rotate_Z(float s_angle,float c_angle);
|
||||
|
||||
// unary operators
|
||||
WWINLINE Vector3 operator-() const { return(Vector3(-X,-Y,-Z)); }
|
||||
WWINLINE Vector3 operator+() const { return *this; }
|
||||
|
||||
WWINLINE Vector3 & operator += (const Vector3 & v) { X += v.X; Y += v.Y; Z += v.Z; return *this; }
|
||||
WWINLINE Vector3 & operator -= (const Vector3 & v) { X -= v.X; Y -= v.Y; Z -= v.Z; return *this; }
|
||||
WWINLINE Vector3 & operator *= (float k) { X = X*k; Y=Y*k; Z=Z*k; return *this; }
|
||||
WWINLINE Vector3 & operator /= (float k) { float ook=1.0f/k; X=X*ook; Y=Y*ook; Z=Z*ook; return *this; }
|
||||
|
||||
// scalar multiplication, division
|
||||
WWINLINE friend Vector3 operator * (const Vector3 &a,float k);
|
||||
WWINLINE friend Vector3 operator * (float k,const Vector3 &a);
|
||||
WWINLINE friend Vector3 operator / (const Vector3 &a,float k);
|
||||
|
||||
// vector addition,subtraction
|
||||
WWINLINE friend Vector3 operator + (const Vector3 &a,const Vector3 &b);
|
||||
WWINLINE friend Vector3 operator - (const Vector3 &a,const Vector3 &b);
|
||||
|
||||
// Equality operators
|
||||
friend bool operator == (const Vector3 &a,const Vector3 &b);
|
||||
friend bool operator != (const Vector3 &a,const Vector3 &b);
|
||||
WWINLINE friend bool Equal_Within_Epsilon(const Vector3 &a,const Vector3 &b,float epsilon);
|
||||
|
||||
// dot product / inner product
|
||||
WWINLINE friend float operator * (const Vector3 &a,const Vector3 &b);
|
||||
static WWINLINE float Dot_Product(const Vector3 &a,const Vector3 &b);
|
||||
|
||||
// cross product / outer product
|
||||
static WWINLINE Vector3 Cross_Product(const Vector3 &a,const Vector3 &b);
|
||||
static WWINLINE void Cross_Product(const Vector3 &a,const Vector3 &b,Vector3 * result);
|
||||
static WWINLINE float Cross_Product_X(const Vector3 &a,const Vector3 &b);
|
||||
static WWINLINE float Cross_Product_Y(const Vector3 &a,const Vector3 &b);
|
||||
static WWINLINE float Cross_Product_Z(const Vector3 &a,const Vector3 &b);
|
||||
|
||||
// add and subtract without return by value
|
||||
static WWINLINE void Add(const Vector3 & a,const Vector3 & b,Vector3 * c);
|
||||
static WWINLINE void Subtract(const Vector3 & a,const Vector3 & b,Vector3 * c);
|
||||
|
||||
// Line intersection functions.
|
||||
static WWINLINE float Find_X_At_Y(float y, const Vector3 &p1, const Vector3 &p2);
|
||||
static WWINLINE float Find_X_At_Z(float z, const Vector3 &p1, const Vector3 &p2);
|
||||
static WWINLINE float Find_Y_At_X(float x, const Vector3 &p1, const Vector3 &p2);
|
||||
static WWINLINE float Find_Y_At_Z(float z, const Vector3 &p1, const Vector3 &p2);
|
||||
static WWINLINE float Find_Z_At_X(float x, const Vector3 &p1, const Vector3 &p2);
|
||||
static WWINLINE float Find_Z_At_Y(float z, const Vector3 &p1, const Vector3 &p2);
|
||||
|
||||
// make this vector the min or max of itself and the passed vector
|
||||
WWINLINE void Update_Min(const Vector3 & a);
|
||||
WWINLINE void Update_Max(const Vector3 & a);
|
||||
WWINLINE void Cap_Absolute_To(const Vector3 & a);
|
||||
|
||||
// verify that none of the members of this vector are invalid floats
|
||||
WWINLINE bool Is_Valid(void) const;
|
||||
|
||||
static WWINLINE float Quick_Distance(const Vector3 &p1, const Vector3 &p2);
|
||||
static WWINLINE float Distance(const Vector3 &p1, const Vector3 &p2);
|
||||
|
||||
// Linearly interpolate two Vector3's
|
||||
static void Lerp(const Vector3 & a, const Vector3 & b, float alpha,Vector3 * set_result);
|
||||
|
||||
// Color Conversion
|
||||
WWINLINE unsigned long Convert_To_ABGR( void ) const;
|
||||
WWINLINE unsigned long Convert_To_ARGB( void ) const;
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Scalar Multiply Operator -- Multiply a vector by a scalar *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
WWINLINE Vector3 operator * (const Vector3 &a,float k)
|
||||
{
|
||||
return Vector3((a.X * k),(a.Y * k),(a.Z * k));
|
||||
}
|
||||
|
||||
WWINLINE Vector3 operator * (float k, const Vector3 &a)
|
||||
{
|
||||
return Vector3((a.X * k),(a.Y * k),(a.Z * k));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Scalar Division Operator -- Divide a vector by a scalar *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE Vector3 operator / (const Vector3 &a,float k)
|
||||
{
|
||||
float ook = 1.0f/k;
|
||||
return Vector3((a.X * ook),(a.Y * ook),(a.Z * ook));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Addition Operator -- Add two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
WWINLINE Vector3 operator + (const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return Vector3(
|
||||
a.X+b.X,
|
||||
a.Y+b.Y,
|
||||
a.Z+b.Z
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Subtraction Operator -- Subract two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
WWINLINE Vector3 operator - (const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return Vector3(
|
||||
a.X-b.X,
|
||||
a.Y-b.Y,
|
||||
a.Z-b.Z
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Inner Product -- Compute the inner or dot product of two vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE float operator * (const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return a.X*b.X +
|
||||
a.Y*b.Y +
|
||||
a.Z*b.Z;
|
||||
}
|
||||
|
||||
WWINLINE float Vector3::Dot_Product(const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return a*b;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Equality Operator -- Determine if two vectors are identical *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE bool operator == (const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return ( (a.X == b.X) && (a.Y == b.Y) && (a.Z == b.Z));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Inequality Operator -- Determine if two vectors are identical *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE bool operator != (const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return ( (a.X != b.X) || (a.Y != b.Y) || (a.Z != b.Z));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Equal_Within_Epsilon -- Determine if two vectors are identical within e*
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE bool Equal_Within_Epsilon(const Vector3 &a,const Vector3 &b,float epsilon)
|
||||
{
|
||||
return( (WWMath::Fabs(a.X - b.X) < epsilon) &&
|
||||
(WWMath::Fabs(a.Y - b.Y) < epsilon) &&
|
||||
(WWMath::Fabs(a.Z - b.Z) < epsilon) );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Cross_Product -- compute the cross product of two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE Vector3 Vector3::Cross_Product(const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return Vector3(
|
||||
(a.Y * b.Z - a.Z * b.Y),
|
||||
(a.Z * b.X - a.X * b.Z),
|
||||
(a.X * b.Y - a.Y * b.X)
|
||||
);
|
||||
}
|
||||
|
||||
WWINLINE void Vector3::Cross_Product(const Vector3 &a,const Vector3 &b,Vector3 * set_result)
|
||||
{
|
||||
assert(set_result != &a);
|
||||
set_result->X = (a.Y * b.Z - a.Z * b.Y);
|
||||
set_result->Y = (a.Z * b.X - a.X * b.Z);
|
||||
set_result->Z = (a.X * b.Y - a.Y * b.X);
|
||||
}
|
||||
|
||||
WWINLINE float Vector3::Cross_Product_X(const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return a.Y * b.Z - a.Z * b.Y;
|
||||
}
|
||||
|
||||
WWINLINE float Vector3::Cross_Product_Y(const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return a.Z * b.X - a.X * b.Z;
|
||||
}
|
||||
|
||||
WWINLINE float Vector3::Cross_Product_Z(const Vector3 &a,const Vector3 &b)
|
||||
{
|
||||
return a.X * b.Y - a.Y * b.X;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector3::Normalize -- Normalizes the vector. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE void Vector3::Normalize()
|
||||
{
|
||||
float len2 = Length2();
|
||||
if (len2 != 0.0f) {
|
||||
float oolen = WWMath::Inv_Sqrt(Length2());
|
||||
X *= oolen;
|
||||
Y *= oolen;
|
||||
Z *= oolen;
|
||||
}
|
||||
}
|
||||
|
||||
WWINLINE Vector3 Normalize(const Vector3 & vec)
|
||||
{
|
||||
float len2 = vec.Length2();
|
||||
if (len2 != 0.0f) {
|
||||
float oolen = WWMath::Inv_Sqrt(len2);
|
||||
return vec * oolen;
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector3::Length -- Returns the length of the vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE float Vector3::Length() const
|
||||
{
|
||||
return WWMath::Sqrt(Length2());
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector3::Length2 -- Returns the square of the length of the vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
WWINLINE float Vector3::Length2() const
|
||||
{
|
||||
return X*X + Y*Y + Z*Z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Quick_Length -- returns a quick approximation of the length *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 7/15/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE float Vector3::Quick_Length(void) const
|
||||
{
|
||||
// this method of approximating the length comes from Graphics Gems 1 and
|
||||
// supposedly gives an error of +/- 8%
|
||||
float max = WWMath::Fabs(X);
|
||||
float mid = WWMath::Fabs(Y);
|
||||
float min = WWMath::Fabs(Z);
|
||||
float tmp;
|
||||
|
||||
if (max < mid) { tmp = max; max = mid; mid = tmp; }
|
||||
if (max < min) { tmp = max; max = min; min = tmp; }
|
||||
if (mid < min) { tmp = mid; mid = min; min = mid; }
|
||||
|
||||
return max + (11.0f / 32.0f)*mid + (1.0f / 4.0f)*min;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Swap -- swap two Vector3's *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/11/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Swap(Vector3 & a,Vector3 & b)
|
||||
{
|
||||
Vector3 tmp(a);
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Lerp -- linearly interpolate two Vector3's by an interpolation factor. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: No checking is done to ensure that alpha is between 0 and 1. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 08/11/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE Vector3 Lerp(const Vector3 & a, const Vector3 & b, float alpha)
|
||||
{
|
||||
return Vector3(
|
||||
(a.X + (b.X - a.X)*alpha),
|
||||
(a.Y + (b.Y - a.Y)*alpha),
|
||||
(a.Z + (b.Z - a.Z)*alpha)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Lerp -- linearly interpolate two Vector3's without return-by-value *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Lerp(const Vector3 & a, const Vector3 & b, float alpha,Vector3 * set_result)
|
||||
{
|
||||
assert(set_result != NULL);
|
||||
set_result->X = (a.X + (b.X - a.X)*alpha);
|
||||
set_result->Y = (a.Y + (b.Y - a.Y)*alpha);
|
||||
set_result->Z = (a.Z + (b.Z - a.Z)*alpha);
|
||||
}
|
||||
|
||||
WWINLINE void Vector3::Lerp(const Vector3 & a, const Vector3 & b, float alpha,Vector3 * set_result)
|
||||
{
|
||||
assert(set_result != NULL);
|
||||
set_result->X = (a.X + (b.X - a.X)*alpha);
|
||||
set_result->Y = (a.Y + (b.Y - a.Y)*alpha);
|
||||
set_result->Z = (a.Z + (b.Z - a.Z)*alpha);
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Add -- Add two vector3's without return-by-value *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Add(const Vector3 &a,const Vector3 &b,Vector3 * set_result)
|
||||
{
|
||||
assert(set_result != NULL);
|
||||
set_result->X = a.X + b.X;
|
||||
set_result->Y = a.Y + b.Y;
|
||||
set_result->Z = a.Z + b.Z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Subtract -- Subtract two vector3's without return-by-value *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Subtract(const Vector3 &a,const Vector3 &b,Vector3 * set_result)
|
||||
{
|
||||
assert(set_result != NULL);
|
||||
set_result->X = a.X - b.X;
|
||||
set_result->Y = a.Y - b.Y;
|
||||
set_result->Z = a.Z - b.Z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Update_Min -- sets each component of the vector to the min of this and a *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Update_Min(const Vector3 & a)
|
||||
{
|
||||
if (a.X < X) X = a.X;
|
||||
if (a.Y < Y) Y = a.Y;
|
||||
if (a.Z < Z) Z = a.Z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Update_Max -- Sets each component of the vector to the max of this and a *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Update_Max(const Vector3 & a)
|
||||
{
|
||||
if (a.X > X) X = a.X;
|
||||
if (a.Y > Y) Y = a.Y;
|
||||
if (a.Z > Z) Z = a.Z;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Cap_To_Absolute_Of -- Sets each component of the vector to no larger than the -ve or +ve of*
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/99 wst : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Cap_Absolute_To(const Vector3 & a)
|
||||
{
|
||||
if (X > 0)
|
||||
{
|
||||
if (a.X < X) X = a.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (-a.X > X) X = -a.X;
|
||||
}
|
||||
|
||||
if (Y > 0)
|
||||
{
|
||||
if (a.Y < Y) Y = a.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (-a.Y > Y) Y = -a.Y;
|
||||
}
|
||||
|
||||
if (Z > 0)
|
||||
{
|
||||
if (a.Z < Z) Z = a.Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (-a.Z > Z) Z = -a.Z;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Scale -- scale this vector by 3 independent scale factors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Scale(const Vector3 & scale)
|
||||
{
|
||||
X *= scale.X;
|
||||
Y *= scale.Y;
|
||||
Z *= scale.Z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Rotate_X -- rotates this vector around the X axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Rotate_X(float angle)
|
||||
{
|
||||
Rotate_X(sinf(angle),cosf(angle));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Rotate_X -- Rotates this vector around the x axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Rotate_X(float s_angle,float c_angle)
|
||||
{
|
||||
float tmp_y = Y;
|
||||
float tmp_z = Z;
|
||||
|
||||
Y = c_angle * tmp_y - s_angle * tmp_z;
|
||||
Z = s_angle * tmp_y + c_angle * tmp_z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Rotate_Y -- Rotates this vector around the y axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Rotate_Y(float angle)
|
||||
{
|
||||
Rotate_Y(sinf(angle),cosf(angle));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Rotate_Y -- Rotates this vector around the Y axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Rotate_Y(float s_angle,float c_angle)
|
||||
{
|
||||
float tmp_x = X;
|
||||
float tmp_z = Z;
|
||||
|
||||
X = c_angle * tmp_x + s_angle * tmp_z;
|
||||
Z = -s_angle * tmp_x + c_angle * tmp_z;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Rotate_Z -- Rotates this vector around the Z axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Rotate_Z(float angle)
|
||||
{
|
||||
Rotate_Z(sinf(angle),cosf(angle));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Rotate_Z -- Rotates this vector around the Z axis *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE void Vector3::Rotate_Z(float s_angle,float c_angle)
|
||||
{
|
||||
float tmp_x = X;
|
||||
float tmp_y = Y;
|
||||
|
||||
X = c_angle * tmp_x - s_angle * tmp_y;
|
||||
Y = s_angle * tmp_x + c_angle * tmp_y;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Is_Valid -- Verifies that each component of this vector is a valid float *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE bool Vector3::Is_Valid(void) const
|
||||
{
|
||||
return (WWMath::Is_Valid_Float(X) && WWMath::Is_Valid_Float(Y) && WWMath::Is_Valid_Float(Z));
|
||||
}
|
||||
|
||||
WWINLINE float Vector3::Find_X_At_Y(float y, const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
return(p1.X + ((y - p1.Y) * ((p2.X - p1.X) / (p2.Y - p1.Y))));
|
||||
}
|
||||
WWINLINE float Vector3::Find_X_At_Z(float z, const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
return(p1.X + ((z - p1.Z) * ((p2.X - p1.X) / (p2.Z - p1.Z))));
|
||||
}
|
||||
WWINLINE float Vector3::Find_Y_At_X(float x, const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
return(p1.Y + ((x - p1.X) * ((p2.Y - p1.Y) / (p2.X - p1.X))));
|
||||
}
|
||||
WWINLINE float Vector3::Find_Y_At_Z(float z, const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
return(p1.Y + ((z - p1.Z) * ((p2.Y - p1.Y) / (p2.Z - p1.Z))));
|
||||
}
|
||||
WWINLINE float Vector3::Find_Z_At_X(float x, const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
return(p1.Z + ((x - p1.X) * ((p2.Z - p1.Z) / (p2.X - p1.X))));
|
||||
}
|
||||
WWINLINE float Vector3::Find_Z_At_Y(float y, const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
return(p1.Z + ((y - p1.Y) * ((p2.Z - p1.Z) / (p2.Y - p1.Y))));
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Distance -- Accurate distance calculation. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/1999MLL: Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE float Vector3::Distance(const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
Vector3 temp;
|
||||
temp = p1 - p2;
|
||||
return (temp.Length());
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Quick_Distance -- Fast but inaccurate distance calculation. *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/1999MLL: Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE float Vector3::Quick_Distance(const Vector3 &p1, const Vector3 &p2)
|
||||
{
|
||||
Vector3 temp;
|
||||
temp = p1 - p2;
|
||||
return (temp.Quick_Length());
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Convert_To_ABGR -- Converts to SR packed color . *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/1999MLL: Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE unsigned long Vector3::Convert_To_ABGR( void ) const
|
||||
{
|
||||
return (unsigned(255)<<24) |
|
||||
(unsigned(Z*255.0f)<<16) |
|
||||
(unsigned(Y*255.0f)<<8) |
|
||||
(unsigned(X*255.0f));
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector3::Convert_To_ARGB -- Converts to packed color . *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 11/29/1999MLL: Created. *
|
||||
*=============================================================================================*/
|
||||
WWINLINE unsigned long Vector3::Convert_To_ARGB( void ) const
|
||||
{
|
||||
return (unsigned(255)<<24) |
|
||||
(unsigned(X*255.0f)<<16) |
|
||||
(unsigned(Y*255.0f)<<8) |
|
||||
(unsigned(Z*255.0f));
|
||||
}
|
||||
|
||||
#endif /* Vector3_H */
|
||||
|
||||
143
Code/Tools/pluglib/vector3i.h
Normal file
143
Code/Tools/pluglib/vector3i.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/vector3i.h $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 11/24/01 5:24p $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef VECTOR3I_H
|
||||
#define VECTOR3I_H
|
||||
|
||||
#include "always.h"
|
||||
|
||||
class Vector3i
|
||||
{
|
||||
public:
|
||||
|
||||
int I;
|
||||
int J;
|
||||
int K;
|
||||
|
||||
WWINLINE Vector3i(void);
|
||||
WWINLINE Vector3i(int i,int j,int k);
|
||||
|
||||
WWINLINE bool operator== (const Vector3i & v) const;
|
||||
WWINLINE bool operator!= (const Vector3i& v) const;
|
||||
WWINLINE const int& operator[] (int n) const;
|
||||
WWINLINE int& operator[] (int n);
|
||||
};
|
||||
|
||||
|
||||
WWINLINE Vector3i::Vector3i(void)
|
||||
{
|
||||
}
|
||||
|
||||
WWINLINE Vector3i::Vector3i(int i,int j,int k)
|
||||
{
|
||||
I = i; J = j; K = k;
|
||||
}
|
||||
|
||||
WWINLINE bool Vector3i::operator == (const Vector3i & v) const
|
||||
{
|
||||
return (I == v.I && J == v.J && K == v.K);
|
||||
}
|
||||
|
||||
WWINLINE bool Vector3i::operator != (const Vector3i& v) const
|
||||
{
|
||||
return !(I == v.I && J == v.J && K == v.K);
|
||||
}
|
||||
|
||||
WWINLINE const int& Vector3i::operator[] (int n) const
|
||||
{
|
||||
return ((int*)this)[n];
|
||||
}
|
||||
|
||||
WWINLINE int& Vector3i::operator[] (int n)
|
||||
{
|
||||
return ((int*)this)[n];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class Vector3i16
|
||||
{
|
||||
public:
|
||||
|
||||
unsigned short I;
|
||||
unsigned short J;
|
||||
unsigned short K;
|
||||
|
||||
WWINLINE Vector3i16(void);
|
||||
WWINLINE Vector3i16(unsigned short i,unsigned short j,unsigned short k);
|
||||
|
||||
WWINLINE bool operator== (const Vector3i & v) const;
|
||||
WWINLINE bool operator!= (const Vector3i& v) const;
|
||||
WWINLINE const unsigned short & operator[] (int n) const;
|
||||
WWINLINE unsigned short & operator[] (int n);
|
||||
};
|
||||
|
||||
|
||||
WWINLINE Vector3i16::Vector3i16(void)
|
||||
{
|
||||
}
|
||||
|
||||
WWINLINE Vector3i16::Vector3i16(unsigned short i,unsigned short j,unsigned short k)
|
||||
{
|
||||
I = i; J = j; K = k;
|
||||
}
|
||||
|
||||
WWINLINE bool Vector3i16::operator == (const Vector3i & v) const
|
||||
{
|
||||
return (I == v.I && J == v.J && K == v.K);
|
||||
}
|
||||
|
||||
WWINLINE bool Vector3i16::operator != (const Vector3i& v) const
|
||||
{
|
||||
return !(I == v.I && J == v.J && K == v.K);
|
||||
}
|
||||
|
||||
WWINLINE const unsigned short & Vector3i16::operator[] (int n) const
|
||||
{
|
||||
return ((unsigned short *)this)[n];
|
||||
}
|
||||
|
||||
WWINLINE unsigned short & Vector3i16::operator[] (int n)
|
||||
{
|
||||
return ((unsigned short *)this)[n];
|
||||
}
|
||||
|
||||
#endif
|
||||
390
Code/Tools/pluglib/vector4.h
Normal file
390
Code/Tools/pluglib/vector4.h
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
** 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/wwmath/vector4.h 12 12/14/99 11:08a Greg_h $ */
|
||||
/***************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood 3D *
|
||||
* *
|
||||
* File Name : VECTOR4.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 02/24/97 *
|
||||
* *
|
||||
* Last Update : June 2, 1997 [GH] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Scalar Division Operator -- Divide a vector by a scalar *
|
||||
* Scalar Multiply Operator -- Multiply a vector by a scalar *
|
||||
* Vector Addition Operator -- Add two vectors *
|
||||
* Vector Subtraction Operator -- Subract two vectors *
|
||||
* Vector Inner Product Operator -- Compute the inner or dot product *
|
||||
* Vector Equality Operator -- Detemine if two vectors are identical *
|
||||
* Vector Inequality Operator -- Detemine if two vectors are identical *
|
||||
* Swap -- swap two Vector4's *
|
||||
* Vector4::Is_Valid -- Vector4::Is_Valid *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef VECTOR4_H
|
||||
#define VECTOR4_H
|
||||
|
||||
#include "always.h"
|
||||
#include "wwmath.h"
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
** Vector4 - 4 dimensional vectors
|
||||
*/
|
||||
class Vector4
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
float W;
|
||||
|
||||
|
||||
// Constructors
|
||||
Vector4(void) {};
|
||||
Vector4(const Vector4 & v) { X = v.X; Y = v.Y; Z = v.Z; W = v.W; }
|
||||
Vector4(float x, float y, float z, float w) { X = x; Y = y; Z = z; W = w; }
|
||||
Vector4(const float vector[4]) { X = vector[0]; Y = vector[1]; Z = vector[2]; W = vector[3]; }
|
||||
|
||||
// Assignment
|
||||
Vector4 & operator = (const Vector4 & v) { X = v.X; Y = v.Y; Z = v.Z; W = v.W; return *this; }
|
||||
void Set(float x, float y, float z, float w) { X = x; Y = y; Z = z; W = w; }
|
||||
|
||||
// Array access
|
||||
float & operator [](int i) { return (&X)[i]; }
|
||||
const float & operator [](int i) const { return (&X)[i]; }
|
||||
|
||||
// normalize, compute length
|
||||
void Normalize(void);
|
||||
float Length(void) const;
|
||||
float Length2(void) const;
|
||||
|
||||
// unary operators
|
||||
Vector4 operator-() const { return(Vector4(-X,-Y,-Z,-W)); }
|
||||
Vector4 operator+() const { return *this; }
|
||||
|
||||
Vector4 & operator += (const Vector4 & v) { X += v.X; Y += v.Y; Z += v.Z; W += v.W; return *this; }
|
||||
Vector4 & operator -= (const Vector4 & v) { X -= v.X; Y -= v.Y; Z -= v.Z; W += v.W; return *this; }
|
||||
Vector4 & operator *= (float k) { X = X*k; Y=Y*k; Z=Z*k; W=W*k; return *this; }
|
||||
Vector4 & operator /= (float k) { k=1.0f/k; X = X*k; Y=Y*k; Z=Z*k; W=W*k; return *this; }
|
||||
|
||||
// scalar multiplication, division
|
||||
friend Vector4 operator * (const Vector4 &a,float k);
|
||||
friend Vector4 operator * (float k,const Vector4 &a);
|
||||
friend Vector4 operator / (const Vector4 &a,float k);
|
||||
|
||||
// vector addition,subtraction
|
||||
friend Vector4 operator + (const Vector4 &a,const Vector4 &b);
|
||||
friend Vector4 operator - (const Vector4 &a,const Vector4 &b);
|
||||
|
||||
// dot product / inner product
|
||||
friend float operator * (const Vector4 &a,const Vector4 &b);
|
||||
static float Dot_Product(const Vector4 &a,const Vector4 &b);
|
||||
|
||||
// Equality operators
|
||||
friend bool operator == (const Vector4 &a,const Vector4 &b);
|
||||
friend bool operator != (const Vector4 &a,const Vector4 &b);
|
||||
|
||||
// verify that none of the members of this vector are invalid floats
|
||||
bool Is_Valid(void) const;
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* Scalar Multiply Operator -- Multiply a vector by a scalar *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
inline Vector4 operator * (const Vector4 &a,float k)
|
||||
{
|
||||
return Vector4((a.X * k),(a.Y * k),(a.Z * k),(a.W * k));
|
||||
}
|
||||
|
||||
inline Vector4 operator * (float k, const Vector4 &a)
|
||||
{
|
||||
return a*k;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Scalar Division Operator -- Divide a vector by a scalar *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline Vector4 operator / (const Vector4 &a,float k)
|
||||
{
|
||||
float ook=1.0f/k;
|
||||
return Vector4((a[0] * ook),(a[1] * ook),(a[2] * ook),(a[3] * ook));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Addition Operator -- Add two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
inline Vector4 operator + (const Vector4 &a,const Vector4 &b)
|
||||
{
|
||||
return Vector4(
|
||||
a[0]+b[0],
|
||||
a[1]+b[1],
|
||||
a[2]+b[2],
|
||||
a[3]+b[3]
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Subtraction Operator -- Subract two vectors *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*========================================================================*/
|
||||
inline Vector4 operator - (const Vector4 &a,const Vector4 &b)
|
||||
{
|
||||
return Vector4(
|
||||
a[0]-b[0],
|
||||
a[1]-b[1],
|
||||
a[2]-b[2],
|
||||
a[3]-b[3]
|
||||
);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Inner Product -- Compute the inner or dot product of two vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline float operator * (const Vector4 &a,const Vector4 &b)
|
||||
{
|
||||
return a[0]*b[0] +
|
||||
a[1]*b[1] +
|
||||
a[2]*b[2] +
|
||||
a[3]*b[3];
|
||||
}
|
||||
|
||||
inline float Vector4::Dot_Product(const Vector4 &a,const Vector4 &b)
|
||||
{
|
||||
return a*b;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Equality Operator -- Detemine if two vectors are identical *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool operator == (const Vector4 &a,const Vector4 &b)
|
||||
{
|
||||
return ( (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector Inequality Operator -- Detemine if two vectors are identical *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline bool operator != (const Vector4 &a,const Vector4 &b)
|
||||
{
|
||||
return ( (a[0] != b[0]) || (a[1] != b[1]) || (a[2] != b[2]) || (a[3] != b[3]));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector4::Normalize -- Normalizes the vector. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline void Vector4::Normalize()
|
||||
{
|
||||
float len2 = Length2();
|
||||
if (len2 != 0.0f) {
|
||||
float oolen = WWMath::Inv_Sqrt(len2);
|
||||
X *= oolen;
|
||||
Y *= oolen;
|
||||
Z *= oolen;
|
||||
W *= oolen;
|
||||
}
|
||||
}
|
||||
|
||||
inline Vector4 Normalize(const Vector4 & vec)
|
||||
{
|
||||
float len2 = vec.Length2();
|
||||
if (len2 != 0.0f) {
|
||||
float oolen = WWMath::Inv_Sqrt(len2);
|
||||
return vec * oolen;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector4::Length -- Returns the length of the vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline float Vector4::Length() const
|
||||
{
|
||||
return WWMath::Sqrt(Length2());
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Vector4::Length -- Returns the square of the length of the vector *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
*========================================================================*/
|
||||
inline float Vector4::Length2() const
|
||||
{
|
||||
return X*X + Y*Y + Z*Z + W*W;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Swap -- swap two Vector4's *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/02/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline void Swap(Vector4 & a,Vector4 & b)
|
||||
{
|
||||
Vector4 tmp(a);
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Lerp -- linearly interpolate two Vector4's by an interpolation factor. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: No checking is done to ensure that alpha is between 0 and 1. *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 01/14/1999 NH : Created. *
|
||||
*=============================================================================================*/
|
||||
inline Vector4 Lerp(const Vector4 & a, const Vector4 & b, float alpha)
|
||||
{
|
||||
return Vector4(
|
||||
(a.X + (b.X - a.X)*alpha),
|
||||
(a.Y + (b.Y - a.Y)*alpha),
|
||||
(a.Z + (b.Z - a.Z)*alpha),
|
||||
(a.W + (b.W - a.W)*alpha)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Vector4::Is_Valid -- Vector4::Is_Valid *
|
||||
* *
|
||||
* verifies that all members of this vector are valid floats *
|
||||
* *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 10/18/99 gth : Created. *
|
||||
*=============================================================================================*/
|
||||
inline bool Vector4::Is_Valid(void) const
|
||||
{
|
||||
return (WWMath::Is_Valid_Float(X) && WWMath::Is_Valid_Float(Y) && WWMath::Is_Valid_Float(Z) && WWMath::Is_Valid_Float(W));
|
||||
}
|
||||
|
||||
|
||||
#endif /* VECTOR4_H */
|
||||
|
||||
125
Code/Tools/pluglib/visualc.h
Normal file
125
Code/Tools/pluglib/visualc.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/visualc.h $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 5/16/01 4:11p $*
|
||||
* *
|
||||
* $Revision:: 9 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
/**********************************************************************
|
||||
** The "bool" integral type was defined by the C++ comittee in
|
||||
** November of '94. Until the compiler supports this, use the following
|
||||
** definition.
|
||||
*/
|
||||
#include "bool.h"
|
||||
|
||||
|
||||
/*
|
||||
** Make the inline depth 255
|
||||
*/
|
||||
#pragma inline_depth(255)
|
||||
|
||||
|
||||
/*
|
||||
** Turn off some unneeded warnings.
|
||||
*/
|
||||
|
||||
// "unreferenced inline function has been removed" Yea, so what?
|
||||
#pragma warning(disable : 4514)
|
||||
|
||||
// "conversion from 'double' to 'float', possible loss of data" Yea, so what?
|
||||
#pragma warning(disable : 4244)
|
||||
|
||||
// "overflow in floating-point constant arithmetic" This warning occurs even if the
|
||||
// loss of precision is insignificant.
|
||||
#pragma warning(disable : 4056)
|
||||
|
||||
// "function not inlined" This warning is typically useless. The inline keyword
|
||||
// only serves as a suggestion to the compiler and it may or may not inline a
|
||||
// function on a case by case basis. No need to be told of this.
|
||||
#pragma warning(disable : 4710)
|
||||
|
||||
// "'this' used in base member initializer list" Using "this" in a base member
|
||||
// initializer is valid -- no need for this warning.
|
||||
#pragma warning(disable : 4355)
|
||||
|
||||
// "typedef-name used as a synonym for class-name". This is by design and should
|
||||
// not be a warning.
|
||||
#pragma warning(disable : 4097)
|
||||
|
||||
// Unreferenced local function removed.
|
||||
#pragma warning(disable : 4505)
|
||||
|
||||
// 'function selected for automatic inlining'
|
||||
#pragma warning(disable : 4711)
|
||||
|
||||
// 'copy constructor could not be generated'
|
||||
#pragma warning(disable : 4511)
|
||||
|
||||
// 'assignment operator could not be generated'
|
||||
#pragma warning(disable : 4512)
|
||||
|
||||
// 'unreferenced formal parameter'
|
||||
#pragma warning(disable : 4100)
|
||||
|
||||
// HIDE WARNING 4786 "identifier was truncated to '255' characters in the browser information"
|
||||
// Tempates create LLLOOONNNGGG identifiers!
|
||||
#pragma warning(disable : 4786)
|
||||
|
||||
// 'function selected for automatic inline expansion'. Cool, but since we're treating
|
||||
// warnings as errors, don't warn me about this!
|
||||
#pragma warning(disable : 4711)
|
||||
|
||||
|
||||
|
||||
#define M_E 2.71828182845904523536
|
||||
#define M_LOG2E 1.44269504088896340736
|
||||
#define M_LOG10E 0.434294481903251827651
|
||||
#define M_LN2 0.693147180559945309417
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#define M_1_PI 0.318309886183790671538
|
||||
#define M_2_PI 0.636619772367581343076
|
||||
#define M_1_SQRTPI 0.564189583547756286948
|
||||
#define M_2_SQRTPI 1.12837916709551257390
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#define M_SQRT_2 0.707106781186547524401
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
889
Code/Tools/pluglib/w3d_file.h
Normal file
889
Code/Tools/pluglib/w3d_file.h
Normal file
@@ -0,0 +1,889 @@
|
||||
/*
|
||||
** 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/ww3d/w3d_file.h 56 8/12/98 11:16a Greg_h $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Commando / G 3D Library *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/ww3d/w3d_file.h $*
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 8/11/98 4:15p $*
|
||||
* *
|
||||
* $Revision:: 56 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#ifndef W3D_FILE_H
|
||||
#define W3D_FILE_H
|
||||
|
||||
#include "always.h"
|
||||
|
||||
#ifndef BITTYPE_H
|
||||
#include "bittype.h"
|
||||
#endif
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
VERSION NUMBERS:
|
||||
|
||||
Each Major chunk type will contain a "header" as its first
|
||||
sub-chunk. The first member of this header will be a Version
|
||||
number formatted so that its major revision number is the
|
||||
high two bytes and its minor revision number is the lower two
|
||||
bytes.
|
||||
|
||||
Version 1.0:
|
||||
|
||||
MESHES - contained the following chunks:
|
||||
W3D_CHUNK_MESH_HEADER, // header for a mesh
|
||||
W3D_CHUNK_VERTICES, // array of vertices
|
||||
W3D_CHUNK_VERTEX_NORMALS, // array of normals
|
||||
W3D_CHUNK_SURRENDER_NORMALS, // array of surrender normals (one per vertex as req. by surrender)
|
||||
W3D_CHUNK_TEXCOORDS, // array of texture coordinates
|
||||
W3D_CHUNK_MATERIALS, // array of materials
|
||||
W3D_CHUNK_TRIANGLES, // array of triangles
|
||||
W3D_CHUNK_SURRENDER_TRIANGLES,// array of surrender format tris
|
||||
W3D_CHUNK_MESH_USER_TEXT, // Name of owning hierarchy, text from the MAX comment field
|
||||
|
||||
HIERARCHY TREES - contained the following chunks:
|
||||
W3D_CHUNK_HIERARCHY_HEADER,
|
||||
W3D_CHUNK_PIVOTS,
|
||||
W3D_CHUNK_PIVOT_FIXUPS,
|
||||
|
||||
HIERARCHY ANIMATIONS - contained the following chunks:
|
||||
W3D_CHUNK_ANIMATION_HEADER,
|
||||
W3D_CHUNK_ANIMATION_CHANNEL,
|
||||
|
||||
MESH CONNECTIONS - (blueprint for a hierarchical model) contained these chunks:
|
||||
|
||||
|
||||
Version 2.0:
|
||||
|
||||
MESHES:
|
||||
|
||||
- Mesh header now contains the hierarchy model name. The mesh name will be built
|
||||
as <HModelName>.<MeshName> instead of the old convention: <HTreeName>.<Meshname>
|
||||
|
||||
- The material chunk is replaced with a new material structure which contains
|
||||
some information for animating materials.
|
||||
|
||||
- Vertex Influences link vertices of a mesh to bones in a hierarchy, this is
|
||||
the information needed for skinning.
|
||||
|
||||
- Damage chunks added. A damage chunk contains a new set of materials, a set
|
||||
of vertex offsets, and a set of vertex colors.
|
||||
|
||||
Added the following chunks:
|
||||
|
||||
W3D_CHUNK_VERTEX_COLORS,
|
||||
W3D_CHUNK_VERTEX_INFLUENCES,
|
||||
W3D_CHUNK_DAMAGE,
|
||||
W3D_CHUNK_DAMAGE_HEADER,
|
||||
W3D_CHUNK_DAMAGE_MATERIALS,
|
||||
W3D_CHUNK_DAMAGE_VERTICES,
|
||||
W3D_CHUNK_DAMAGE_COLORS,
|
||||
W3D_CHUNK_MATERIALS2,
|
||||
|
||||
MESH CONNECTIONS: Hierarchy models can now contain skins and collision meshes
|
||||
in addition to the normal meshes.
|
||||
|
||||
W3D_CHUNK_COLLISION_CONNECTION, // collision meshes connected to the hierarchy
|
||||
W3D_CHUNK_SKIN_CONNECTION, // skins connected to the hierarchy
|
||||
W3D_CHUNK_CONNECTION_AUX_DATA // extension of the connection header
|
||||
|
||||
|
||||
Dec 12, 1997
|
||||
|
||||
Changed MESH_CONNECTIONS chunks into HMODEL chunks because the name
|
||||
mesh connections was becoming more and more inappropriate... This was only
|
||||
a data structure naming change so no-one other than the coders are affected
|
||||
|
||||
Added W3D_CHUNK_LODMODEL. An LOD Model contains a set of names for
|
||||
render objects, each with a specified distance range.
|
||||
|
||||
|
||||
Feb 6, 1998
|
||||
|
||||
Added W3D_CHUNK_SECTMESH and its sub-chunks. This will be the file
|
||||
format for the terrain geometry exported from POV's Atlas tool.
|
||||
|
||||
March 29, 1998 : Version 3.0
|
||||
|
||||
- New material chunk which supports the new features of the 3D engine
|
||||
- Modified HTrees to always have a root transform to remove all of the
|
||||
special case -1 bone indexes.
|
||||
- Added new mesh types, A mesh can now be categorized as: normal,
|
||||
aligned, skin, collision, or shadow.
|
||||
|
||||
June 22, 1998
|
||||
|
||||
Removed the "SECTMESH" chunks which were never implemented or used.
|
||||
|
||||
Adding a new type of object: The 'Tilemap'. This simple-sounding object
|
||||
is a binary partition tree of tiles where tiles are rectangular regions of
|
||||
space. In each leaf to the tree, a mesh is referenced. The tile map is
|
||||
made of several chunks:
|
||||
|
||||
- W3D_CHUNK_TILEMAP
|
||||
- W3D_CHUNK_TILEMAP_HEADER
|
||||
- W3D_CHUNK_TILES
|
||||
- W3D_CHUNK_MESH
|
||||
- W3D_CHUNK_MESH
|
||||
...
|
||||
|
||||
- W3D_CHUNK_PARTITION_TREE
|
||||
- W3D_CHUNK_PARTITION_TREE_HEADER
|
||||
- W3D_CHUNK_PARTITION_TREE_NODES
|
||||
|
||||
- W3D_CHUNK_TILE_INSTANCES
|
||||
- W3D_CHUNK_TILE_INSTANCE
|
||||
|
||||
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
#define W3D_MAKE_VERSION(major,minor) (((major) << 16) | (minor))
|
||||
#define W3D_GET_MAJOR_VERSION(ver) ((ver)>>16)
|
||||
#define W3D_GET_MINOR_VERSION(ver) ((ver) & 0xFFFF)
|
||||
|
||||
#define W3D_CURRENT_VERSION W3D_MAKE_VERSION(3,0)
|
||||
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
CHUNK TYPES FOR ALL 3D DATA
|
||||
|
||||
All 3d data is stored in chunks similar to an IFF file. Each
|
||||
chunk will be headed by an ID and size field.
|
||||
|
||||
All structures defined in this header file are prefixed with
|
||||
W3d to prevent naming conflicts with in-game structures which
|
||||
may be slightly different than the on-disk structures.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
enum {
|
||||
|
||||
W3D_CHUNK_MESH = 0, // Mesh definition (.WTM file)
|
||||
W3D_CHUNK_MESH_HEADER, // header for a mesh
|
||||
W3D_CHUNK_VERTICES, // array of vertices
|
||||
W3D_CHUNK_VERTEX_NORMALS, // array of normals
|
||||
W3D_CHUNK_SURRENDER_NORMALS, // array of surrender normals (one per vertex as req. by surrender)
|
||||
W3D_CHUNK_TEXCOORDS, // array of texture coordinates
|
||||
W3D_CHUNK_MATERIALS, // array of materials
|
||||
O_W3D_CHUNK_TRIANGLES, // array of triangles (obsolete)
|
||||
O_W3D_CHUNK_QUADRANGLES, // array of quads (obsolete)
|
||||
W3D_CHUNK_SURRENDER_TRIANGLES,// array of surrender format tris
|
||||
O_W3D_CHUNK_POV_TRIANGLES, // POV format triangles (obsolete)
|
||||
O_W3D_CHUNK_POV_QUADRANGLES, // POV format quads (obsolete)
|
||||
W3D_CHUNK_MESH_USER_TEXT, // Name of owning hierarchy, text from the MAX comment field
|
||||
W3D_CHUNK_VERTEX_COLORS, // Pre-set vertex coloring
|
||||
W3D_CHUNK_VERTEX_INFLUENCES, // Mesh Deformation vertex connections
|
||||
W3D_CHUNK_DAMAGE, // Mesh damage, new set of materials, vertex positions, vertex colors
|
||||
W3D_CHUNK_DAMAGE_HEADER, // Header for the damage data, tells what is coming
|
||||
W3D_CHUNK_DAMAGE_VERTICES, // Array of modified vertices (W3dMeshDamageVertexStruct's)
|
||||
W3D_CHUNK_DAMAGE_COLORS, // Array of modified vert colors (W3dMeshDamageColorStruct's)
|
||||
O_W3D_CHUNK_DAMAGE_MATERIALS, // (OBSOLETE) Damage materials simply wrapped with MATERIALS3 or higher
|
||||
|
||||
W3D_CHUNK_MATERIALS2, // array of version 2 materials (with animation frame counts)
|
||||
|
||||
W3D_CHUNK_MATERIALS3, // array of version 3 materials (all new surrender features supported)
|
||||
W3D_CHUNK_MATERIAL3, // Each version 3 material wrapped with this chunk ID
|
||||
W3D_CHUNK_MATERIAL3_NAME, // Name of the material (array of chars, null terminated)
|
||||
W3D_CHUNK_MATERIAL3_INFO, // contains a W3dMaterial3Struct, general material info
|
||||
W3D_CHUNK_MATERIAL3_DC_MAP, // wraps the following two chunks, diffuse color texture
|
||||
W3D_CHUNK_MAP3_FILENAME, // filename of the texture
|
||||
W3D_CHUNK_MAP3_INFO, // a W3dMap3Struct
|
||||
W3D_CHUNK_MATERIAL3_DI_MAP, // diffuse illimination map, same format as other maps
|
||||
W3D_CHUNK_MATERIAL3_SC_MAP, // specular color map, same format as other maps
|
||||
W3D_CHUNK_MATERIAL3_SI_MAP, // specular illumination map, same format as other maps
|
||||
|
||||
W3D_CHUNK_MESH_HEADER3, // New improved mesh header
|
||||
W3D_CHUNK_TRIANGLES, // New improved triangles chunk
|
||||
W3D_CHUNK_PER_TRI_MATERIALS, // Multi-Mtl meshes - An array of uint16 material id's
|
||||
|
||||
W3D_CHUNK_HIERARCHY = 0x100, // hierarchy tree definition (.WHT file)
|
||||
W3D_CHUNK_HIERARCHY_HEADER,
|
||||
W3D_CHUNK_PIVOTS,
|
||||
W3D_CHUNK_PIVOT_FIXUPS, // only needed by the exporter...
|
||||
|
||||
W3D_CHUNK_ANIMATION = 0x200, // hierarchy animation data (.WHA file)
|
||||
W3D_CHUNK_ANIMATION_HEADER,
|
||||
W3D_CHUNK_ANIMATION_CHANNEL,
|
||||
W3D_CHUNK_BIT_CHANNEL, // channel of boolean values (e.g. visibility)
|
||||
|
||||
W3D_CHUNK_HMODEL = 0x300, // blueprint for a hierarchy model
|
||||
W3D_CHUNK_HMODEL_HEADER, // usually found at end of a .WTM file
|
||||
W3D_CHUNK_NODE, // render objects connected to the hierarchy
|
||||
W3D_CHUNK_COLLISION_NODE, // collision meshes connected to the hierarchy
|
||||
W3D_CHUNK_SKIN_NODE, // skins connected to the hierarchy
|
||||
W3D_CHUNK_HMODEL_AUX_DATA, // extension of the connection header
|
||||
W3D_CHUNK_SHADOW_NODE, // shadow object connected to the hierarchy
|
||||
|
||||
W3D_CHUNK_LODMODEL = 0x400, // blueprint for an LOD model. This is simply a
|
||||
W3D_CHUNK_LODMODEL_HEADER, // collection of 'n' render objects, ordered in terms
|
||||
W3D_CHUNK_LOD, // of their expected rendering costs.
|
||||
|
||||
W3D_CHUNK_TILEMAP = 0x600, // Tile Map definition.
|
||||
W3D_CHUNK_TILEMAP_NAME,
|
||||
W3D_CHUNK_TILEMAP_HEADER,
|
||||
W3D_CHUNK_TILEMAP_TILE_INSTANCES,
|
||||
W3D_CHUNK_TILEMAP_PARTITION_TREE,
|
||||
W3D_CHUNK_TILEMAP_PARTITION_NODE,
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct W3dChunkHeader
|
||||
{
|
||||
uint32 ChunkType; // Type of chunk (see above enumeration)
|
||||
uint32 ChunkSize; // Size of the chunk, (not including the chunk header)
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
WTM ( Westwood Triangle Mesh )
|
||||
|
||||
Each mesh will be contained within a WTM_CHUNK_MESH within
|
||||
this chunk will be the following chunks:
|
||||
|
||||
The header will be the first chunk and it tells general
|
||||
information about the mesh such as how many triangles there
|
||||
are, how many vertices, the bounding box, center
|
||||
of mass, inertia matrix, etc.
|
||||
|
||||
The vertex array is an array of Vectors giving the object
|
||||
space location of each vertex
|
||||
|
||||
The normal array is an array of all of the unique vertex
|
||||
normal vectors needed by the mesh. This allows for vertices
|
||||
with multiple normals so that we can duplicate the effect
|
||||
of the smoothing groups in 3dsMax.
|
||||
|
||||
The surrender normal array is an array of vertex normals which
|
||||
correspond 1to1 with the vertices. This is because the current
|
||||
version of surrender can only handle one vertex normal per vertex.
|
||||
In this case, the application should skip the normal array chunk
|
||||
and read the surrender normal chunk into its SR_VERTs
|
||||
|
||||
The texture coord array is all of the unique texture coordinates
|
||||
for the mesh. This allows triangles to share vertices but not
|
||||
necessarily share texture coordinates.
|
||||
|
||||
The material array is a list of the names and rgb colors of
|
||||
all of the unique materials used by the mesh. All triangles will
|
||||
have a material index into this list.
|
||||
|
||||
The triangle array is all of the triangles which make up the
|
||||
mesh. Each triangle has 3 indices to its vertices, vertex normals,
|
||||
and texture coordinates. Each also has a material id and the
|
||||
coefficients for its plane equation.
|
||||
|
||||
The Surrender Triangle array is all of the triangles in a slightly
|
||||
different format. Surrender triangles contain their u-v coordinates
|
||||
so there is no indirection and no possibility for sharing. To
|
||||
make the importer faster, the triangles will also be stored in this
|
||||
format. The application can read whichever chunk it wants to.
|
||||
|
||||
The mesh user text chunk is a NULL-terminated text buffer.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
#define W3D_NAME_LEN 16
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// vector
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dVectorStruct
|
||||
{
|
||||
float32 X; // X,Y,Z coordinates
|
||||
float32 Y;
|
||||
float32 Z;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// quaternion
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dQuaternionStruct
|
||||
{
|
||||
float32 Q[4];
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// texture coordinate
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dTexCoordStruct
|
||||
{
|
||||
float32 U; // U,V coordinates
|
||||
float32 V;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// rgb color, one byte per channel, padded to an even 4 bytes
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dRGBStruct
|
||||
{
|
||||
uint8 R;
|
||||
uint8 G;
|
||||
uint8 B;
|
||||
uint8 pad;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Version 1.0 Material, array of these are found inside the W3D_CHUNK_MATERIALS chunk.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dMaterialStruct
|
||||
{
|
||||
char MaterialName[W3D_NAME_LEN]; // name of the material (NULL terminated)
|
||||
char PrimaryName[W3D_NAME_LEN]; // primary texture name (NULL terminated)
|
||||
char SecondaryName[W3D_NAME_LEN]; // secondary texture name (NULL terminated)
|
||||
uint32 RenderFlags; // Rendering flags
|
||||
uint8 Red; // Rgb colors
|
||||
uint8 Green;
|
||||
uint8 Blue;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Version 2.0 Material, array of these are found inside the W3D_CHUNK_MATERIALS2 chunk.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dMaterial2Struct
|
||||
{
|
||||
char MaterialName[W3D_NAME_LEN]; // name of the material (NULL terminated)
|
||||
char PrimaryName[W3D_NAME_LEN]; // primary texture name (NULL terminated)
|
||||
char SecondaryName[W3D_NAME_LEN]; // secondary texture name (NULL terminated)
|
||||
uint32 RenderFlags; // Rendering flags
|
||||
uint8 Red; // Rgb colors
|
||||
uint8 Green;
|
||||
uint8 Blue;
|
||||
uint8 Alpha;
|
||||
|
||||
uint16 PrimaryNumFrames; // number of animated frames (if 1, not animated)
|
||||
uint16 SecondaryNumFrames; // number of animated frames (if 1, not animated)
|
||||
|
||||
char Pad[12]; // expansion room
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MATERIAL ATTRIBUTES (version 3.0 onward)
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Use alpha enables alpha channels, etc, Use sorting causes display lists using
|
||||
// this material to be sorted (even with z-buf, translucent materials need to be sorted)
|
||||
#define W3DMATERIAL_USE_ALPHA 0x00000001
|
||||
#define W3DMATERIAL_USE_SORTING 0x00000002
|
||||
|
||||
// Hints for render devices that cannot support all features
|
||||
#define W3DMATERIAL_HINT_DIT_OVER_DCT 0x00000010
|
||||
#define W3DMATERIAL_HINT_SIT_OVER_SCT 0x00000020
|
||||
#define W3DMATERIAL_HINT_DIT_OVER_DIG 0x00000040
|
||||
#define W3DMATERIAL_HINT_SIT_OVER_SIG 0x00000080
|
||||
#define W3DMATERIAL_HINT_FAST_SPECULAR_AFTER_ALPHA 0x00000100
|
||||
|
||||
// Last byte is for PSX: Translucency type and a lighting disable flag.
|
||||
#define W3DMATERIAL_PSX_MASK 0xFF000000
|
||||
#define W3DMATERIAL_PSX_TRANS_MASK 0x07000000
|
||||
#define W3DMATERIAL_PSX_TRANS_NONE 0x00000000
|
||||
#define W3DMATERIAL_PSX_TRANS_100 0x01000000
|
||||
#define W3DMATERIAL_PSX_TRANS_50 0x02000000
|
||||
#define W3DMATERIAL_PSX_TRANS_25 0x03000000
|
||||
#define W3DMATERIAL_PSX_TRANS_MINUS_100 0x04000000
|
||||
#define W3DMATERIAL_PSX_NO_RT_LIGHTING 0x08000000
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MAPPING TYPES (version 3.0 onward)
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define W3DMAPPING_UV 0
|
||||
#define W3DMAPPING_ENVIRONMENT 1
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Version 3.0 Material, A W3D_CHUNK_MATERIALS3 chunk will wrap a bunch of
|
||||
// W3D_CHUNK_MATERIAL3 chunks. Inside each chunk will be a name chunk, an 'info' chunk which
|
||||
// contains the following struct, and one or more map chunks. a mesh with 2 materials might
|
||||
// look like:
|
||||
//
|
||||
// W3D_CHUNK_MATERIALS3 <-- simply a wrapper around the array of mtls
|
||||
// W3D_CHUNK_MATERIAL3 <-- a wrapper around each material
|
||||
// W3D_CHUNK_STRING <-- name of the material
|
||||
// W3D_CHUNK_MATERIAL3_INFO <-- standard material properties, a W3dMaterial3Struct
|
||||
// W3D_CHUNK_MATERIAL3_DC_MAP <-- a map, W3dMap3Struct
|
||||
// W3D_CHUNK_STRING <-- filename of the map
|
||||
// W3D_CHUNK_MAP_INFO <-- map parameters
|
||||
// W3D_CHUNK_MATERIAL3_SC_MAP
|
||||
// W3D_CHUNK_STRING <-- filename of the map
|
||||
// W3D_CHUNK_MAP_INFO
|
||||
// W3D_CHUNK_MATERIAL3
|
||||
// W3D_CHUNK_MATERIAL3_NAME
|
||||
// W3D_CHUNK_MATERIAL3_INFO
|
||||
// W3D_CHUNK_MATERIAL3_SI_MAP
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dMaterial3Struct
|
||||
{
|
||||
uint32 Attributes; // flags,hints,etc.
|
||||
|
||||
W3dRGBStruct DiffuseColor; // diffuse color
|
||||
W3dRGBStruct SpecularColor; // specular color
|
||||
|
||||
W3dRGBStruct EmissiveCoefficients; // emmissive coefficients, default to 0,0,0
|
||||
W3dRGBStruct AmbientCoefficients; // ambient coefficients, default to 1,1,1
|
||||
W3dRGBStruct DiffuseCoefficients; // diffuse coeficients, default to 1,1,1
|
||||
W3dRGBStruct SpecularCoefficients; // specular coefficients, default to 0,0,0
|
||||
|
||||
float32 Shininess; // how tight the specular highlight will be, 1 - 1000 (default = 1)
|
||||
float32 Opacity; // how opaque the material is, 0.0 = invisible, 1.0 = fully opaque (default = 1)
|
||||
float32 Translucency; // how much light passes through the material. (default = 0)
|
||||
float32 FogCoeff; // effect of fog (0.0=not fogged, 1.0=fogged) (default = 1)
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// A map, only occurs as part of a material, will be preceeded by its name.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dMap3Struct
|
||||
{
|
||||
uint16 MappingType; // Mapping type, will be one of the above #defines (e.g. W3DMAPPING_UV)
|
||||
uint16 FrameCount; // Number of frames (1 if not animated)
|
||||
float32 FrameRate; // Frame rate, frames per second in floating point
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// A triangle, occurs inside the W3D_CHUNK_SURRENDER_TRIANGLES chunk
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dSurrenderTriStruct
|
||||
{
|
||||
uint32 Vindex[3]; // vertex, vert normal, and texture coord indexes (all use same index)
|
||||
W3dTexCoordStruct TexCoord[3]; // texture coordinates (OBSOLETE!!!)
|
||||
uint32 MaterialIdx; // material index
|
||||
W3dVectorStruct Normal; // Face normal
|
||||
uint32 Attributes; // collision flags, sort method, etc
|
||||
W3dRGBStruct Gouraud[3]; // Pre-set shading values (OBSOLETE!!!)
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// A triangle, occurs inside the W3D_CHUNK_TRIANGLES chunk
|
||||
// This is NEW for Version 3.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dTriStruct
|
||||
{
|
||||
uint32 Vindex[3]; // vertex,vnormal,texcoord,color indices
|
||||
uint32 Attributes; // attributes bits
|
||||
W3dVectorStruct Normal; // plane normal
|
||||
float32 Dist; // plane distance
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Flags for the Mesh Attributes member
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define W3D_MESH_FLAG_NONE 0x00000000 // plain ole normal mesh
|
||||
#define W3D_MESH_FLAG_COLLISION_BOX 0x00000001 // mesh is a collision box (should be 8 verts, should be hidden, etc)
|
||||
#define W3D_MESH_FLAG_SKIN 0x00000002 // skin mesh
|
||||
#define W3D_MESH_FLAG_SHADOW 0x00000004 // intended to be projected as a shadow
|
||||
#define W3D_MESH_FLAG_ALIGNED 0x00000008 // always aligns with camera
|
||||
|
||||
#define W3D_MESH_FLAG_COLLISION_TYPE_MASK 0x00000FF0 // mask for the collision type bits
|
||||
#define W3D_MESH_FLAG_COLLISION_TYPE_SHIFT 4 // shifting to get to the collision type bits
|
||||
#define W3D_MESH_FLAG_COLLISION_TYPE_PHYSICAL 0x00000010 // physical collisions
|
||||
#define W3D_MESH_FLAG_COLLISION_TYPE_PROJECTILE 0x00000020 // projectiles (rays) collide with this
|
||||
|
||||
#define W3D_MESH_FLAG_HIDDEN 0x00001000 // this mesh is hidden by default
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Original (Obsolete) Mesh Header
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
struct W3dMeshHeaderStruct
|
||||
{
|
||||
uint32 Version; // Currently version 0x100
|
||||
char MeshName[W3D_NAME_LEN]; // name of the mesh (Null terminated)
|
||||
uint32 Attributes;
|
||||
|
||||
//
|
||||
// Counts, these can be regarded as an inventory of what is to come in the file.
|
||||
//
|
||||
uint32 NumTris; // number of triangles (OBSOLETE!)
|
||||
uint32 NumQuads; // number of quads; (OBSOLETE!)
|
||||
uint32 NumSrTris; // number of triangles
|
||||
|
||||
uint32 NumPovTris; // (NOT USED)
|
||||
uint32 NumPovQuads; // (NOT USED)
|
||||
|
||||
uint32 NumVertices; // number of unique vertices
|
||||
uint32 NumNormals; // number of unique normals (OBSOLETE!)
|
||||
uint32 NumSrNormals; // number of surrender normals (MUST EQUAL NumVertices or 0)
|
||||
|
||||
uint32 NumTexCoords; // number of unique texture coords (MUST EQUAL NumVertices or 0)
|
||||
uint32 NumMaterials; // number of unique materials needed
|
||||
|
||||
uint32 NumVertColors; // number of vertex colors (MUST EQUAL NumVertices or 0)
|
||||
uint32 NumVertInfluences;// vertex influences(MUST EQUAL NumVertices or 0)
|
||||
uint32 NumDamageStages; // number of damage offset chunks
|
||||
uint32 FutureCounts[5]; // reserve space for future counts (set to zero).
|
||||
|
||||
//
|
||||
// LOD controls
|
||||
//
|
||||
float32 LODMin; // min LOD distance
|
||||
float32 LODMax; // max LOD distance
|
||||
|
||||
//
|
||||
// Collision / rendering quick-rejection
|
||||
//
|
||||
W3dVectorStruct Min; // Min corner of the bounding box
|
||||
W3dVectorStruct Max; // Max corner of the bounding box
|
||||
W3dVectorStruct SphCenter; // Center of bounding sphere
|
||||
float32 SphRadius; // Bounding sphere radius
|
||||
|
||||
//
|
||||
// Default transformation
|
||||
//
|
||||
W3dVectorStruct Translation;
|
||||
float32 Rotation[9];
|
||||
|
||||
//
|
||||
// Physics Properties
|
||||
//
|
||||
W3dVectorStruct MassCenter; // Center of mass in object space
|
||||
float32 Inertia[9]; // Inertia tensor (relative to MassCenter)
|
||||
float32 Volume; // volume of the object
|
||||
|
||||
//
|
||||
// Name of possible hierarchy this mesh should be attached to
|
||||
//
|
||||
char HierarchyTreeName[W3D_NAME_LEN];
|
||||
char HierarchyModelName[W3D_NAME_LEN];
|
||||
uint32 FutureUse[24]; // Reserved for future use
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Version 3 Mesh Header, trimmed out some of the junk that was in the
|
||||
// previous versions.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define W3D_VERTEX_CHANNEL_LOCATION 0x00000001 // object-space location of the vertex
|
||||
#define W3D_VERTEX_CHANNEL_NORMAL 0x00000002 // object-space normal for the vertex
|
||||
#define W3D_VERTEX_CHANNEL_TEXCOORD 0x00000004 // texture coordinate
|
||||
#define W3D_VERTEX_CHANNEL_COLOR 0x00000008 // vertex color
|
||||
#define W3D_VERTEX_CHANNEL_BONEID 0x00000010 // per-vertex bone id for skins
|
||||
|
||||
#define W3D_FACE_CHANNEL_FACE 0x00000001 // basic face info, W3dTriStruct...
|
||||
|
||||
struct W3dMeshHeader3Struct
|
||||
{
|
||||
uint32 Version;
|
||||
uint32 Attributes;
|
||||
|
||||
char MeshName[W3D_NAME_LEN];
|
||||
char HierarchyModelName[W3D_NAME_LEN];
|
||||
|
||||
//
|
||||
// Counts, these can be regarded as an inventory of what is to come in the file.
|
||||
//
|
||||
uint32 NumTris; // number of triangles
|
||||
uint32 NumVertices; // number of unique vertices
|
||||
uint32 NumMaterials; // number of unique materials
|
||||
uint32 NumDamageStages; // number of damage offset chunks
|
||||
uint32 FutureCounts[3]; // future counts
|
||||
|
||||
uint32 VertexChannels; // bits for presence of types of per-vertex info
|
||||
uint32 FaceChannels; // bits for presence of types of per-face info
|
||||
|
||||
//
|
||||
// Bounding volumes
|
||||
//
|
||||
W3dVectorStruct Min; // Min corner of the bounding box
|
||||
W3dVectorStruct Max; // Max corner of the bounding box
|
||||
W3dVectorStruct SphCenter; // Center of bounding sphere
|
||||
float32 SphRadius; // Bounding sphere radius
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// Vertex Influences. For "skins" each vertex can be associated with a
|
||||
// different bone.
|
||||
//
|
||||
struct W3dVertInfStruct
|
||||
{
|
||||
uint16 BoneIdx;
|
||||
uint8 Pad[6];
|
||||
};
|
||||
|
||||
//
|
||||
// Mesh Damage. This can include a new set of materials for the mesh,
|
||||
// new positions for certain vertices in the mesh, and new vertex
|
||||
// colors for certain vertices.
|
||||
//
|
||||
struct W3dMeshDamageStruct
|
||||
{
|
||||
uint32 NumDamageMaterials; // number of materials to replace
|
||||
uint32 NumDamageVerts; // number of vertices to replace
|
||||
uint32 NumDamageColors; // number of vertex colors to replace
|
||||
uint32 DamageIndex; // what index is this damage chunk assigned to
|
||||
uint32 FutureUse[4];
|
||||
};
|
||||
|
||||
struct W3dMeshDamageVertexStruct
|
||||
{
|
||||
uint32 VertexIndex;
|
||||
W3dVectorStruct NewVertex;
|
||||
};
|
||||
|
||||
struct W3dMeshDamageColorStruct
|
||||
{
|
||||
uint32 VertexIndex;
|
||||
W3dRGBStruct NewColor;
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
WHT ( Westwood Hierarchy Tree )
|
||||
|
||||
A hierarchy tree defines a set of coordinate systems which are connected
|
||||
hierarchically. The header defines the name, number of pivots, etc.
|
||||
The pivots chunk will contain a W3dPivotStructs for each node in the
|
||||
tree.
|
||||
|
||||
The W3dPivotFixupStruct contains a transform for each MAX coordinate
|
||||
system and our version of that same coordinate system (bone). It is
|
||||
needed when the user exports the base pose using "Translation Only".
|
||||
These are the matrices which go from the MAX rotated coordinate systems
|
||||
to a system which is unrotated in the base pose. These transformations
|
||||
are needed when exporting a hierarchy animation with the given hierarchy
|
||||
tree file.
|
||||
|
||||
Another explanation of these kludgy "fixup" matrices:
|
||||
|
||||
What are the "fixup" matrices? These are the transforms which
|
||||
were applied to the base pose when the user wanted to force the
|
||||
base pose to use only matrices with certain properties. For
|
||||
example, if we wanted the base pose to use translations only,
|
||||
the fixup transform for each node is a transform which when
|
||||
multiplied by the real node's world transform, yeilds a pure
|
||||
translation matrix. Fixup matrices are used in the mesh
|
||||
exporter since all vertices must be transformed by their inverses
|
||||
in order to make things work. They also show up in the animation
|
||||
exporter because they are needed to make the animation work with
|
||||
the new base pose.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
struct W3dHierarchyStruct
|
||||
{
|
||||
uint32 Version;
|
||||
char Name[W3D_NAME_LEN]; // Name of the hierarchy
|
||||
uint32 NumPivots;
|
||||
W3dVectorStruct Center;
|
||||
};
|
||||
|
||||
struct W3dPivotStruct
|
||||
{
|
||||
char Name[W3D_NAME_LEN]; // Name of the node (UR_ARM, LR_LEG, TORSO, etc)
|
||||
uint32 ParentIdx; // 0xffffffff = root pivot; no parent
|
||||
W3dVectorStruct Translation; // translation to pivot point
|
||||
W3dVectorStruct EulerAngles; // orientation of the pivot point
|
||||
W3dQuaternionStruct Rotation; // orientation of the pivot point
|
||||
};
|
||||
|
||||
struct W3dPivotFixupStruct
|
||||
{
|
||||
float32 TM[4][3]; // this is a direct dump of a MAX 3x4 matrix
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
WHA (Westwood Hierarchy Animation)
|
||||
|
||||
A Hierarchy Animation is a set of data defining deltas from the base
|
||||
position of a hierarchy tree. Translation and Rotation channels can be
|
||||
attached to any node of the hierarchy tree which the animation is
|
||||
associated with.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
struct W3dAnimHeaderStruct
|
||||
{
|
||||
uint32 Version;
|
||||
char Name[W3D_NAME_LEN];
|
||||
char HierarchyName[W3D_NAME_LEN];
|
||||
uint32 NumFrames;
|
||||
uint32 FrameRate;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ANIM_CHANNEL_X = 0,
|
||||
ANIM_CHANNEL_Y,
|
||||
ANIM_CHANNEL_Z,
|
||||
ANIM_CHANNEL_XR,
|
||||
ANIM_CHANNEL_YR,
|
||||
ANIM_CHANNEL_ZR,
|
||||
ANIM_CHANNEL_Q
|
||||
};
|
||||
|
||||
struct W3dAnimChannelStruct
|
||||
{
|
||||
uint16 FirstFrame;
|
||||
uint16 LastFrame;
|
||||
uint16 VectorLen; // length of each vector in this channel
|
||||
uint16 Flags; // channel type.
|
||||
uint16 Pivot; // pivot affected by this channel
|
||||
uint16 pad;
|
||||
float32 Data[1]; // will be (LastFrame - FirstFrame + 1) * VectorLen long
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BIT_CHANNEL_VIS = 0, // turn meshes on and off depending on anim frame.
|
||||
};
|
||||
|
||||
struct W3dBitChannelStruct
|
||||
{
|
||||
uint16 FirstFrame; // all frames outside "First" and "Last" are assumed = DefaultVal
|
||||
uint16 LastFrame;
|
||||
uint16 Flags; // channel type.
|
||||
uint16 Pivot; // pivot affected by this channel
|
||||
uint8 DefaultVal; // default state when outside valid range.
|
||||
uint8 Data[1]; // will be (LastFrame - FirstFrame + 1) / 8 long
|
||||
};
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
(HModel - Hiearchy Model)
|
||||
|
||||
A Hierarchy Model is a set of render objects which should be attached to
|
||||
bones in a hierarchy tree. There can be multiple objects per node
|
||||
in the tree. Or there may be no objects attached to a particular bone.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
struct W3dHModelHeaderStruct
|
||||
{
|
||||
uint32 Version;
|
||||
char Name[W3D_NAME_LEN]; // Name of this connection set (NULL terminated)
|
||||
char HierarchyName[W3D_NAME_LEN]; // Name of hierarchy associated with these connections (NULL terminated)
|
||||
uint16 NumConnections;
|
||||
};
|
||||
|
||||
struct W3dHModelAuxDataStruct
|
||||
{
|
||||
uint32 Attributes;
|
||||
uint32 MeshCount;
|
||||
uint32 CollisionCount;
|
||||
uint32 SkinCount;
|
||||
uint32 ShadowCount;
|
||||
uint32 FutureCounts[7];
|
||||
|
||||
float32 LODMin;
|
||||
float32 LODMax;
|
||||
uint32 FutureUse[32];
|
||||
};
|
||||
|
||||
struct W3dHModelNodeStruct
|
||||
{
|
||||
// Note: the full name of the Render object is expected to be: <HModelName>.<RenderObjName>
|
||||
char RenderObjName[W3D_NAME_LEN];
|
||||
uint16 PivotIdx;
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
(LODModel - Level-Of-Detail Model)
|
||||
|
||||
An LOD Model is a set of render objects which are interchangeable and
|
||||
designed to be different resolution versions of the same object.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
struct W3dLODModelHeaderStruct
|
||||
{
|
||||
uint32 Version;
|
||||
char Name[W3D_NAME_LEN]; // Name of this LOD Model
|
||||
uint16 NumLODs;
|
||||
};
|
||||
|
||||
struct W3dLODStruct
|
||||
{
|
||||
char RenderObjName[2*W3D_NAME_LEN];
|
||||
float32 LODMin; // "artist" inspired switching distances
|
||||
float32 LODMax;
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
|
||||
TileMap
|
||||
|
||||
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
struct W3dTileMapHeaderStruct
|
||||
{
|
||||
uint32 Version;
|
||||
uint32 TileInstanceCount;
|
||||
};
|
||||
|
||||
#define W3D_TILE_ROTATION_0 0x00
|
||||
#define W3D_TILE_ROTATION_90 0x01
|
||||
#define W3D_TILE_ROTATION_180 0x02
|
||||
#define W3D_TILE_ROTATION_270 0x03
|
||||
|
||||
struct W3dTileInstanceStruct
|
||||
{
|
||||
char RenderObjName[2*W3D_NAME_LEN];
|
||||
uint32 Rotation;
|
||||
W3dVectorStruct Position;
|
||||
};
|
||||
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_PARTITION 0x0001
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_LEAF 0x0002
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_XNORMAL 0x0004
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_YNORMAL 0x0008
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_ZNORMAL 0x0010
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_FRONT_CHILD 0x0020
|
||||
#define W3D_TILEMAP_PARTITION_FLAGS_BACK_CHILD 0x0040
|
||||
|
||||
struct W3dTileMapPartitionStruct
|
||||
{
|
||||
uint16 Flags; // type of node, type of plane, flags for presence of children.
|
||||
uint16 InstanceIndex; // if Type==LEAF, this field will store the tile instance index.
|
||||
float32 Dist; // distance along plane axis.
|
||||
W3dVectorStruct Min; // min corner of the bounding box
|
||||
W3dVectorStruct Max; // max corner of the bounding box
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
709
Code/Tools/pluglib/w3dquat.cpp
Normal file
709
Code/Tools/pluglib/w3dquat.cpp
Normal file
@@ -0,0 +1,709 @@
|
||||
/*
|
||||
** 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/w3dquat.cpp 29 2/03/00 4:55p Jason_a $ */
|
||||
/***********************************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Voxel Technology *
|
||||
* *
|
||||
* File Name : QUAT.CPP *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 02/24/97 *
|
||||
* *
|
||||
* Last Update : February 28, 1997 [GH] *
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Quaternion::Quaternion -- constructor *
|
||||
* Quaternion::Set -- Set the quaternion *
|
||||
* Quaternion::operator= -- Assignment operator *
|
||||
* Quaternion::Make_Closest -- Use nearest representation to the given quaternion. *
|
||||
* Trackball -- Computes a "trackball" quaternion given 2D mouse coordinates *
|
||||
* Axis_To_Quat -- Creates a quaternion given an axis and angle of rotation *
|
||||
* Slerp -- Spherical Linear interpolation! *
|
||||
* Build_Quaternion -- Creates a quaternion from a Matrix *
|
||||
* Build_Matrix -- Creates a Matrix from a Quaternion *
|
||||
* Normalize -- normalizes a quaternion *
|
||||
* Quaternion::Quaternion -- constructor *
|
||||
* Slerp_Setup -- Get ready to call "Cached_Slerp" *
|
||||
* Cached_Slerp -- Quaternion slerping, optimized with cached values *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "w3dquat.h"
|
||||
#include "matrix3d.h"
|
||||
#include "matrix4.h"
|
||||
#include "wwmath.h"
|
||||
|
||||
#include <stdio.h>
|
||||
//#include <iostream.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define SLERP_EPSILON 0.001
|
||||
|
||||
static int _nxt[3] = { 1 , 2 , 0 };
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// local functions
|
||||
// ------------------------------------------------------------
|
||||
static float project_to_sphere(float,float,float);
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Quaternion::Quaternion -- constructor *
|
||||
* *
|
||||
* constructs a quaternion from the given axis and angle of rotation (in RADIANS of course) *
|
||||
* *
|
||||
* INPUT: *
|
||||
* axis - axis of the rotation *
|
||||
* angle - rotation angle *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 12/10/97 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion::Quaternion(const Vector3 & axis,float angle)
|
||||
{
|
||||
float s = sinf(angle/2);
|
||||
float c = cosf(angle/2);
|
||||
X = s * axis.X;
|
||||
Y = s * axis.Y;
|
||||
Z = s * axis.Z;
|
||||
W = c;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Quaternion::Normalize -- Normalize to a unit quaternion *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Quaternion::Normalize()
|
||||
{
|
||||
float mag = WWMath::Sqrt(X * X + Y * Y + Z * Z + W * W);
|
||||
|
||||
if (0.0f == mag) {
|
||||
return;
|
||||
} else {
|
||||
X /= mag;
|
||||
Y /= mag;
|
||||
Z /= mag;
|
||||
W /= mag;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Quaternion::operator= -- Assignment operator *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/24/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion & Quaternion::operator = (const Quaternion & source)
|
||||
{
|
||||
X = source[0];
|
||||
Y = source[1];
|
||||
Z = source[2];
|
||||
W = source[3];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Q::Make_Closest -- Use nearest representation to the given quaternion. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/28/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion & Quaternion::Make_Closest(const Quaternion & qto)
|
||||
{
|
||||
float cos_t = qto.X * X + qto.Y * Y + qto.Z * Z + qto.W * W;
|
||||
|
||||
// if we are on opposite hemisphere from qto, negate ourselves
|
||||
if (cos_t < 0.0) {
|
||||
X = -X;
|
||||
Y = -Y;
|
||||
Z = -Z;
|
||||
W = -W;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Trackball -- Computes a "trackball" quaternion given 2D mouse coordinates *
|
||||
* *
|
||||
* INPUT: *
|
||||
* x0,y0 - x1,y1 - "normalized" mouse coordinates for the mouse movement *
|
||||
* sphsize - size of the trackball sphere *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* a quaternion representing the rotation of a trackball *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/28/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion Trackball(float x0, float y0, float x1, float y1, float sphsize)
|
||||
{
|
||||
Vector3 a;
|
||||
Vector3 p1;
|
||||
Vector3 p2;
|
||||
Vector3 d;
|
||||
|
||||
float phi,t;
|
||||
|
||||
if ((x0 == x1) && (y0 == y1)) {
|
||||
return Quaternion(0.0f, 0.0f, 0.0f, 1.0f); // Zero rotation
|
||||
}
|
||||
|
||||
|
||||
// Compute z coordinates for projection of p1 and p2 to
|
||||
// deformed sphere
|
||||
p1[0] = x0;
|
||||
p1[1] = y0;
|
||||
p1[2] = project_to_sphere(sphsize, x0, y0);
|
||||
|
||||
p2[0] = x1;
|
||||
p2[1] = y1;
|
||||
p2[2] = project_to_sphere(sphsize, x1, y1);
|
||||
|
||||
|
||||
// Find their cross product
|
||||
Vector3::Cross_Product(p2,p1,&a);
|
||||
|
||||
// Compute how much to rotate
|
||||
d = p1 - p2;
|
||||
t = d.Length() / (2.0f * sphsize);
|
||||
|
||||
// Avoid problems with out of control values
|
||||
if (t > 1.0f) t = 1.0f;
|
||||
if (t < -1.0f) t = -1.0f;
|
||||
phi = 2.0f * asin(t);
|
||||
|
||||
return Axis_To_Quat(a, phi);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Axis_To_Quat -- Creates a quaternion given an axis and angle of rotation *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/28/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion Axis_To_Quat(const Vector3 &a, float phi)
|
||||
{
|
||||
Quaternion q;
|
||||
Vector3 tmp = a;
|
||||
|
||||
tmp.Normalize();
|
||||
q[0] = tmp[0];
|
||||
q[1] = tmp[1];
|
||||
q[2] = tmp[2];
|
||||
|
||||
q.Scale(sinf(phi / 2.0f));
|
||||
q[3] = cosf(phi / 2.0f);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Slerp -- Spherical Linear interpolation! *
|
||||
* *
|
||||
* INPUT: *
|
||||
* p - start quaternion *
|
||||
* q - end quaternion *
|
||||
* alpha - interpolating parameter *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/28/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion Slerp(const Quaternion & p,const Quaternion & q,float alpha)
|
||||
{
|
||||
float beta; // complementary interploation parameter
|
||||
float theta; // angle between p and q
|
||||
float sin_t,cos_t; // sine, cosine of theta
|
||||
float oo_sin_t;
|
||||
int qflip; // use flip of q?
|
||||
|
||||
// cos theta = dot product of p and q
|
||||
cos_t = p.X * q.X + p.Y * q.Y + p.Z * q.Z + p.W * q.W;
|
||||
|
||||
// if q is on opposite hemisphere from A, use -B instead
|
||||
if (cos_t < 0.0) {
|
||||
cos_t = -cos_t;
|
||||
qflip = true;
|
||||
} else {
|
||||
qflip = false;
|
||||
}
|
||||
|
||||
if (1.0 - cos_t < SLERP_EPSILON) {
|
||||
|
||||
// if q is very close to p, just linearly interpolate
|
||||
// between the two.
|
||||
beta = 1.0 - alpha;
|
||||
|
||||
} else {
|
||||
|
||||
// normal slerp!
|
||||
theta = acos(cos_t);
|
||||
sin_t = sinf(theta);
|
||||
oo_sin_t = 1.0 / sin_t;
|
||||
beta = sinf(theta - alpha*theta) * oo_sin_t;
|
||||
alpha = sinf(alpha*theta) * oo_sin_t;
|
||||
}
|
||||
|
||||
if (qflip) {
|
||||
alpha = -alpha;
|
||||
}
|
||||
|
||||
Quaternion res;
|
||||
res.X = beta*p.X + alpha*q.X;
|
||||
res.Y = beta*p.Y + alpha*q.Y;
|
||||
res.Z = beta*p.Z + alpha*q.Z;
|
||||
res.W = beta*p.W + alpha*q.W;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Slerp_Setup -- Get ready to call "Cached_Slerp" *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/27/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
void Slerp_Setup(const Quaternion & p,const Quaternion & q,SlerpInfoStruct * slerpinfo)
|
||||
{
|
||||
float cos_t;
|
||||
|
||||
assert(slerpinfo != NULL);
|
||||
|
||||
// cos theta = dot product of p and q
|
||||
cos_t = p.X * q.X + p.Y * q.Y + p.Z * q.Z + p.W * q.W;
|
||||
|
||||
// if q is on opposite hemisphere from A, use -B instead
|
||||
if (cos_t < 0.0) {
|
||||
cos_t = -cos_t;
|
||||
slerpinfo->Flip = true;
|
||||
} else {
|
||||
slerpinfo->Flip = false;
|
||||
}
|
||||
|
||||
if (1.0 - cos_t < SLERP_EPSILON) {
|
||||
|
||||
slerpinfo->Linear = true;
|
||||
slerpinfo->Theta = 0.0f;
|
||||
slerpinfo->SinT = 0.0f;
|
||||
|
||||
} else {
|
||||
|
||||
slerpinfo->Linear = false;
|
||||
slerpinfo->Theta = acos(cos_t);
|
||||
slerpinfo->SinT = sinf(slerpinfo->Theta);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Cached_Slerp -- Quaternion slerping, optimized with cached values *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 2/27/98 GTH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo)
|
||||
{
|
||||
float beta; // complementary interploation parameter
|
||||
float oo_sin_t;
|
||||
|
||||
if (slerpinfo->Linear) {
|
||||
|
||||
// if q is very close to p, just linearly interpolate
|
||||
// between the two.
|
||||
beta = 1.0 - alpha;
|
||||
|
||||
} else {
|
||||
|
||||
// normal slerp!
|
||||
oo_sin_t = 1.0 / slerpinfo->Theta;
|
||||
beta = sin(slerpinfo->Theta - alpha*slerpinfo->Theta) * oo_sin_t;
|
||||
alpha = sin(alpha*slerpinfo->Theta) * oo_sin_t;
|
||||
}
|
||||
|
||||
if (slerpinfo->Flip) {
|
||||
alpha = -alpha;
|
||||
}
|
||||
|
||||
Quaternion res;
|
||||
res.X = beta*p.X + alpha*q.X;
|
||||
res.Y = beta*p.Y + alpha*q.Y;
|
||||
res.Z = beta*p.Z + alpha*q.Z;
|
||||
res.W = beta*p.W + alpha*q.W;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo,Quaternion * set_q)
|
||||
{
|
||||
float beta; // complementary interploation parameter
|
||||
float oo_sin_t;
|
||||
|
||||
if (slerpinfo->Linear) {
|
||||
|
||||
// if q is very close to p, just linearly interpolate
|
||||
// between the two.
|
||||
beta = 1.0 - alpha;
|
||||
|
||||
} else {
|
||||
|
||||
// normal slerp!
|
||||
oo_sin_t = 1.0 / slerpinfo->Theta;
|
||||
beta = sin(slerpinfo->Theta - alpha*slerpinfo->Theta) * oo_sin_t;
|
||||
alpha = sin(alpha*slerpinfo->Theta) * oo_sin_t;
|
||||
}
|
||||
|
||||
if (slerpinfo->Flip) {
|
||||
alpha = -alpha;
|
||||
}
|
||||
|
||||
set_q->X = beta*p.X + alpha*q.X;
|
||||
set_q->Y = beta*p.Y + alpha*q.Y;
|
||||
set_q->Z = beta*p.Z + alpha*q.Z;
|
||||
set_q->W = beta*p.W + alpha*q.W;
|
||||
}
|
||||
|
||||
/***********************************************************************************************
|
||||
* Build_Quaternion -- Creates a quaternion from a Matrix *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* Matrix MUST NOT have scaling! *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/28/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Quaternion Build_Quaternion(const Matrix3D & mat)
|
||||
{
|
||||
float tr,s;
|
||||
int i,j,k;
|
||||
Quaternion q;
|
||||
|
||||
// sum the diagonal of the rotation matrix
|
||||
tr = mat[0][0] + mat[1][1] + mat[2][2];
|
||||
|
||||
if (tr > 0.0f) {
|
||||
|
||||
s = sqrt(tr + 1.0);
|
||||
q[3] = s * 0.5;
|
||||
s = 0.5 / s;
|
||||
|
||||
q[0] = (mat[2][1] - mat[1][2]) * s;
|
||||
q[1] = (mat[0][2] - mat[2][0]) * s;
|
||||
q[2] = (mat[1][0] - mat[0][1]) * s;
|
||||
|
||||
} else {
|
||||
|
||||
i=0;
|
||||
if (mat[1][1] > mat[0][0]) i = 1;
|
||||
if (mat[2][2] > mat[i][i]) i = 2;
|
||||
j = _nxt[i];
|
||||
k = _nxt[j];
|
||||
|
||||
s = sqrt((mat[i][i] - (mat[j][j] + mat[k][k])) + 1.0);
|
||||
|
||||
q[i] = s * 0.5;
|
||||
if (s != 0.0) {
|
||||
s = 0.5 / s;
|
||||
}
|
||||
|
||||
q[3] = ( mat[k][j] - mat[j][k] ) * s;
|
||||
q[j] = ( mat[j][i] + mat[i][j] ) * s;
|
||||
q[k] = ( mat[k][i] + mat[i][k] ) * s;
|
||||
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
Quaternion Build_Quaternion(const Matrix3 & mat)
|
||||
{
|
||||
float tr,s;
|
||||
int i,j,k;
|
||||
Quaternion q;
|
||||
|
||||
// sum the diagonal of the rotation matrix
|
||||
tr = mat[0][0] + mat[1][1] + mat[2][2];
|
||||
|
||||
if (tr > 0.0) {
|
||||
|
||||
s = sqrt(tr + 1.0);
|
||||
q[3] = s * 0.5;
|
||||
s = 0.5 / s;
|
||||
|
||||
q[0] = (mat[2][1] - mat[1][2]) * s;
|
||||
q[1] = (mat[0][2] - mat[2][0]) * s;
|
||||
q[2] = (mat[1][0] - mat[0][1]) * s;
|
||||
|
||||
} else {
|
||||
|
||||
i = 0;
|
||||
if (mat[1][1] > mat[0][0]) i = 1;
|
||||
if (mat[2][2] > mat[i][i]) i = 2;
|
||||
|
||||
j = _nxt[i];
|
||||
k = _nxt[j];
|
||||
|
||||
s = sqrt( (mat[i][i] - (mat[j][j]+mat[k][k])) + 1.0);
|
||||
|
||||
q[i] = s * 0.5;
|
||||
|
||||
if (s != 0.0) {
|
||||
s = 0.5/s;
|
||||
}
|
||||
|
||||
q[3] = ( mat[k][j] - mat[j][k] ) * s;
|
||||
q[j] = ( mat[j][i] + mat[i][j] ) * s;
|
||||
q[k] = ( mat[k][i] + mat[i][k] ) * s;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
Quaternion Build_Quaternion(const Matrix4 & mat)
|
||||
{
|
||||
float tr,s;
|
||||
int i,j,k;
|
||||
Quaternion q;
|
||||
|
||||
// sum the diagonal of the rotation matrix
|
||||
tr = mat[0][0] + mat[1][1] + mat[2][2];
|
||||
|
||||
if (tr > 0.0) {
|
||||
|
||||
s = sqrt(tr + 1.0);
|
||||
q[3] = s * 0.5;
|
||||
s = 0.5 / s;
|
||||
|
||||
q[0] = (mat[2][1] - mat[1][2]) * s;
|
||||
q[1] = (mat[0][2] - mat[2][0]) * s;
|
||||
q[2] = (mat[1][0] - mat[0][1]) * s;
|
||||
|
||||
} else {
|
||||
|
||||
i = 0;
|
||||
if (mat[1][1] > mat[0][0]) i = 1;
|
||||
if (mat[2][2] > mat[i][i]) i = 2;
|
||||
|
||||
j = _nxt[i];
|
||||
k = _nxt[j];
|
||||
|
||||
s = sqrt( (mat[i][i] - (mat[j][j]+mat[k][k])) + 1.0);
|
||||
|
||||
q[i] = s * 0.5;
|
||||
if (s != 0.0) {
|
||||
s = 0.5/s;
|
||||
}
|
||||
q[3] = ( mat[k][j] - mat[j][k] ) * s;
|
||||
q[j] = ( mat[j][i] + mat[i][j] ) * s;
|
||||
q[k] = ( mat[k][i] + mat[i][k] ) * s;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
* Build_Matrix -- Creates a Matrix from a Quaternion *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 02/28/1997 GH : Created. *
|
||||
*=============================================================================================*/
|
||||
Matrix3 Build_Matrix3(const Quaternion & q)
|
||||
{
|
||||
Matrix3 m;
|
||||
|
||||
m[0][0] = (float)(1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]));
|
||||
m[0][1] = (float)(2.0 * (q[0] * q[1] - q[2] * q[3]));
|
||||
m[0][2] = (float)(2.0 * (q[2] * q[0] + q[1] * q[3]));
|
||||
|
||||
m[1][0] = (float)(2.0 * (q[0] * q[1] + q[2] * q[3]));
|
||||
m[1][1] = (float)(1.0 - 2.0f * (q[2] * q[2] + q[0] * q[0]));
|
||||
m[1][2] = (float)(2.0 * (q[1] * q[2] - q[0] * q[3]));
|
||||
|
||||
m[2][0] = (float)(2.0 * (q[2] * q[0] - q[1] * q[3]));
|
||||
m[2][1] = (float)(2.0 * (q[1] * q[2] + q[0] * q[3]));
|
||||
m[2][2] =(float)(1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
Matrix3D Build_Matrix3D(const Quaternion & q)
|
||||
{
|
||||
Matrix3D m;
|
||||
|
||||
// initialize the rotation sub-matrix
|
||||
m[0][0] = (float)(1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]));
|
||||
m[0][1] = (float)(2.0 * (q[0] * q[1] - q[2] * q[3]));
|
||||
m[0][2] = (float)(2.0 * (q[2] * q[0] + q[1] * q[3]));
|
||||
|
||||
m[1][0] = (float)(2.0 * (q[0] * q[1] + q[2] * q[3]));
|
||||
m[1][1] = (float)(1.0 - 2.0f * (q[2] * q[2] + q[0] * q[0]));
|
||||
m[1][2] = (float)(2.0 * (q[1] * q[2] - q[0] * q[3]));
|
||||
|
||||
m[2][0] = (float)(2.0 * (q[2] * q[0] - q[1] * q[3]));
|
||||
m[2][1] = (float)(2.0 * (q[1] * q[2] + q[0] * q[3]));
|
||||
m[2][2] =(float)(1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]));
|
||||
|
||||
// no translation
|
||||
m[0][3] = m[1][3] = m[2][3] = 0.0f;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
Matrix4 Build_Matrix4(const Quaternion & q)
|
||||
{
|
||||
Matrix4 m;
|
||||
|
||||
// initialize the rotation sub-matrix
|
||||
m[0][0] = (float)(1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]));
|
||||
m[0][1] = (float)(2.0 * (q[0] * q[1] - q[2] * q[3]));
|
||||
m[0][2] = (float)(2.0 * (q[2] * q[0] + q[1] * q[3]));
|
||||
|
||||
m[1][0] = (float)(2.0 * (q[0] * q[1] + q[2] * q[3]));
|
||||
m[1][1] = (float)(1.0 - 2.0f * (q[2] * q[2] + q[0] * q[0]));
|
||||
m[1][2] = (float)(2.0 * (q[1] * q[2] - q[0] * q[3]));
|
||||
|
||||
m[2][0] = (float)(2.0 * (q[2] * q[0] - q[1] * q[3]));
|
||||
m[2][1] = (float)(2.0 * (q[1] * q[2] + q[0] * q[3]));
|
||||
m[2][2] = (float)(1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]));
|
||||
|
||||
// no translation
|
||||
m[0][3] = m[1][3] = m[2][3] = 0.0f;
|
||||
|
||||
// last row
|
||||
m[3][0] = m[3][1] = m[3][2] = 0.0f;
|
||||
m[3][3] = 1.0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
void Quaternion::Rotate_X(float theta)
|
||||
{
|
||||
// TODO: optimize this
|
||||
*this = (*this) * Quaternion(Vector3(1,0,0),theta);
|
||||
}
|
||||
|
||||
void Quaternion::Rotate_Y(float theta)
|
||||
{
|
||||
// TODO: optimize this
|
||||
*this = (*this) * Quaternion(Vector3(0,1,0),theta);
|
||||
}
|
||||
|
||||
void Quaternion::Rotate_Z(float theta)
|
||||
{
|
||||
// TODO: optimize this
|
||||
*this = (*this) * Quaternion(Vector3(0,0,1),theta);
|
||||
}
|
||||
|
||||
float project_to_sphere(float r, float x, float y)
|
||||
{
|
||||
const float SQRT2 = 1.41421356f;
|
||||
float t, z;
|
||||
float d = WWMath::Sqrt(x * x + y * y);
|
||||
|
||||
if (d < r * (SQRT2/(2.0f))) // inside sphere
|
||||
z = WWMath::Sqrt(r * r - d * d);
|
||||
else { // on hyperbola
|
||||
t = r / SQRT2;
|
||||
z = t * t / d;
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
void Quaternion::Randomize(void)
|
||||
{
|
||||
X = ((float) (rand() & 0xFFFF)) / 65536.0f;
|
||||
Y = ((float) (rand() & 0xFFFF)) / 65536.0f;
|
||||
Z = ((float) (rand() & 0xFFFF)) / 65536.0f;
|
||||
W = ((float) (rand() & 0xFFFF)) / 65536.0f;
|
||||
|
||||
Normalize();
|
||||
}
|
||||
|
||||
|
||||
262
Code/Tools/pluglib/w3dquat.h
Normal file
262
Code/Tools/pluglib/w3dquat.h
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
** 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/w3dquat.h 27 2/03/00 4:55p Jason_a $ */
|
||||
/***************************************************************************
|
||||
*** Confidential - Westwood Studios ***
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Voxel Technology *
|
||||
* *
|
||||
* File Name : QUAT.H *
|
||||
* *
|
||||
* Programmer : Greg Hjelstrom *
|
||||
* *
|
||||
* Start Date : 02/24/97 *
|
||||
* *
|
||||
* Last Update : February 24, 1997 [GH] *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef QUAT_H
|
||||
#define QUAT_H
|
||||
|
||||
#include "always.h"
|
||||
#include "wwmath.h"
|
||||
#include "wwmatrix3.h"
|
||||
#include "vector3.h"
|
||||
|
||||
|
||||
class Quaternion
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
// X,Y,Z are the imaginary parts of the quaterion
|
||||
// W is the real part
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
float W;
|
||||
|
||||
public:
|
||||
|
||||
Quaternion(void) {};
|
||||
explicit Quaternion(bool init) { if (init) { X = 0.0f; Y = 0.0f; Z = 0.0f; W = 1.0f; } }
|
||||
explicit Quaternion(float a, float b, float c, float d) { X=a; Y=b; Z=c; W=d; }
|
||||
explicit Quaternion(const Vector3 & axis,float angle);
|
||||
Quaternion & operator=(const Quaternion & source);
|
||||
|
||||
void Set(float a = 0.0, float b = 0.0, float c = 0.0, float d = 1.0) { X = a; Y = b; Z = c; W = d; }
|
||||
void Make_Identity(void) { Set(); };
|
||||
void Scale(float s) { X = (float)(s*X); Y = (float)(s*Y); Z = (float)(s*Z); W = (float)(s*W); }
|
||||
|
||||
// Array access
|
||||
float & operator [](int i) { return (&X)[i]; }
|
||||
const float & operator [](int i) const { return (&X)[i]; }
|
||||
|
||||
// Unary operators.
|
||||
// Remember that q and -q represent the same 3D rotation.
|
||||
Quaternion operator-() const { return(Quaternion(-X,-Y,-Z,-W)); }
|
||||
Quaternion operator+() const { return *this; }
|
||||
|
||||
// Every 3D rotation can be expressed by two different quaternions, This
|
||||
// function makes the current quaternion convert itself to the representation
|
||||
// which is closer on the 4D unit-hypersphere to the given quaternion.
|
||||
Quaternion & Make_Closest(const Quaternion & qto);
|
||||
|
||||
// Square of the magnitude of the quaternion
|
||||
float Length2(void) const { return (X*X + Y*Y + Z*Z + W*W); }
|
||||
|
||||
// Magnitude of the quaternion
|
||||
float Length(void) const { return WWMath::Sqrt(Length2()); }
|
||||
|
||||
// Make the quaternion unit length
|
||||
void Normalize(void);
|
||||
|
||||
// post-concatenate rotations about the coordinate axes
|
||||
void Rotate_X(float theta);
|
||||
void Rotate_Y(float theta);
|
||||
void Rotate_Z(float theta);
|
||||
|
||||
// initialize this quaternion randomly (creates a random *unit* quaternion)
|
||||
void Randomize(void);
|
||||
|
||||
// transform (rotate) a vector with this quaternion
|
||||
Vector3 Rotate_Vector(const Vector3 & v) const;
|
||||
void Rotate_Vector(const Vector3 & v,Vector3 * set_result) const;
|
||||
|
||||
// verify that none of the members of this quaternion are invalid floats
|
||||
bool Is_Valid(void) const;
|
||||
};
|
||||
|
||||
// Inverse of the quaternion (1/q)
|
||||
inline Quaternion Inverse(const Quaternion & a)
|
||||
{
|
||||
return Quaternion(-a[0],-a[1],-a[2],a[3]);
|
||||
}
|
||||
|
||||
// Conjugate of the quaternion
|
||||
inline Quaternion Conjugate(const Quaternion & a)
|
||||
{
|
||||
return Quaternion(-a[0],-a[1],-a[2],a[3]);
|
||||
}
|
||||
|
||||
// Add two quaternions
|
||||
inline Quaternion operator + (const Quaternion & a,const Quaternion & b)
|
||||
{
|
||||
return Quaternion(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]);
|
||||
}
|
||||
|
||||
// Subract two quaternions
|
||||
inline Quaternion operator - (const Quaternion & a,const Quaternion & b)
|
||||
{
|
||||
return Quaternion(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]);
|
||||
}
|
||||
|
||||
// Multiply a quaternion by a scalar:
|
||||
inline Quaternion operator * (float scl, const Quaternion & a)
|
||||
{
|
||||
return Quaternion(scl*a[0], scl*a[1], scl*a[2], scl*a[3]);
|
||||
}
|
||||
|
||||
// Multiply a quaternion by a scalar
|
||||
inline Quaternion operator * (const Quaternion & a, float scl)
|
||||
{
|
||||
return scl*a;
|
||||
}
|
||||
|
||||
// Multiply two quaternions
|
||||
inline Quaternion operator * (const Quaternion & a,const Quaternion & b)
|
||||
{
|
||||
return Quaternion
|
||||
(
|
||||
a.W*b.X + b.W*a.X + (a.Y*b.Z - b.Y*a.Z),
|
||||
a.W*b.Y + b.W*a.Y - (a.X*b.Z - b.X*a.Z),
|
||||
a.W*b.Z + b.W*a.Z + (a.X*b.Y - b.X*a.Y),
|
||||
a.W * b.W - (a.X * b.X + a.Y * b.Y + a.Z * b.Z)
|
||||
);
|
||||
}
|
||||
|
||||
// Divide two quaternions
|
||||
inline Quaternion operator / (const Quaternion & a,const Quaternion & b)
|
||||
{
|
||||
return a * Inverse(b);
|
||||
}
|
||||
|
||||
// Normalized version of the quaternion
|
||||
inline Quaternion Normalize(const Quaternion & a)
|
||||
{
|
||||
float mag = a.Length();
|
||||
if (0.0f == mag) {
|
||||
return a;
|
||||
} else {
|
||||
float oomag = 1.0f / mag;
|
||||
return Quaternion(a[0] * oomag, a[1] * oomag, a[2] * oomag, a[3] * oomag);
|
||||
}
|
||||
}
|
||||
|
||||
// This function computes a quaternion based on an axis
|
||||
// (defined by the given Vector a) and an angle about
|
||||
// which to rotate. The angle is expressed in radians.
|
||||
Quaternion Axis_To_Quat(const Vector3 &a, float angle);
|
||||
|
||||
// Pass the x and y coordinates of the last and current position
|
||||
// of the mouse, scaled so they are from -1.0 to 1.0
|
||||
// The quaternion is the computed as the rotation of a trackball
|
||||
// between the two points projected onto a sphere. This can
|
||||
// be used to implement an intuitive viewing control system.
|
||||
Quaternion Trackball(float x0, float y0, float x1, float y1, float sphsize);
|
||||
|
||||
// Spherical Linear interpolation of quaternions
|
||||
Quaternion Slerp(const Quaternion & a,const Quaternion & b,float t);
|
||||
|
||||
// Convert a rotation matrix into a quaternion
|
||||
Quaternion Build_Quaternion(const Matrix3 & matrix);
|
||||
Quaternion Build_Quaternion(const Matrix3D & matrix);
|
||||
Quaternion Build_Quaternion(const Matrix4 & matrix);
|
||||
|
||||
// Convert a quaternion into a rotation matrix
|
||||
Matrix3 Build_Matrix3(const Quaternion & quat);
|
||||
Matrix3D Build_Matrix3D(const Quaternion & quat);
|
||||
Matrix4 Build_Matrix4(const Quaternion & quat);
|
||||
|
||||
|
||||
// Some values can be cached if you are performing multiple slerps
|
||||
// between the same two quaternions...
|
||||
struct SlerpInfoStruct
|
||||
{
|
||||
float SinT;
|
||||
float Theta;
|
||||
bool Flip;
|
||||
bool Linear;
|
||||
};
|
||||
|
||||
// Cached slerp implementation
|
||||
void Slerp_Setup(const Quaternion & p,const Quaternion & q,SlerpInfoStruct * slerpinfo);
|
||||
void Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo,Quaternion * set_q);
|
||||
Quaternion Cached_Slerp(const Quaternion & p,const Quaternion & q,float alpha,SlerpInfoStruct * slerpinfo);
|
||||
|
||||
inline Vector3 Quaternion::Rotate_Vector(const Vector3 & v) const
|
||||
{
|
||||
float x = W*v.X + (Y*v.Z - v.Y*Z);
|
||||
float y = W*v.Y - (X*v.Z - v.X*Z);
|
||||
float z = W*v.Z + (X*v.Y - v.X*Y);
|
||||
float w = -(X*v.X + Y*v.Y + Z*v.Z);
|
||||
|
||||
return Vector3
|
||||
(
|
||||
w*(-X) + W*x + (y*(-Z) - (-Y)*z),
|
||||
w*(-Y) + W*y - (x*(-Z) - (-X)*z),
|
||||
w*(-Z) + W*z + (x*(-Y) - (-X)*y)
|
||||
);
|
||||
}
|
||||
|
||||
inline void Quaternion::Rotate_Vector(const Vector3 & v,Vector3 * result) const
|
||||
{
|
||||
assert(result != NULL);
|
||||
|
||||
float x = W*v.X + (Y*v.Z - v.Y*Z);
|
||||
float y = W*v.Y - (X*v.Z - v.X*Z);
|
||||
float z = W*v.Z + (X*v.Y - v.X*Y);
|
||||
float w = -(X*v.X + Y*v.Y + Z*v.Z);
|
||||
|
||||
result->X = w*(-X) + W*x + (y*(-Z) - (-Y)*z);
|
||||
result->Y = w*(-Y) + W*y - (x*(-Z) - (-X)*z);
|
||||
result->Z = w*(-Z) + W*z + (x*(-Y) - (-X)*y);
|
||||
}
|
||||
|
||||
inline bool Quaternion::Is_Valid(void) const
|
||||
{
|
||||
return ( WWMath::Is_Valid_Float(X) &&
|
||||
WWMath::Is_Valid_Float(Y) &&
|
||||
WWMath::Is_Valid_Float(Z) &&
|
||||
WWMath::Is_Valid_Float(W) );
|
||||
}
|
||||
|
||||
#endif /* QUAT_H */
|
||||
|
||||
|
||||
|
||||
118
Code/Tools/pluglib/watcom.h
Normal file
118
Code/Tools/pluglib/watcom.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /G/wwlib/WATCOM.H $*
|
||||
* *
|
||||
* $Author:: Eric_c $*
|
||||
* *
|
||||
* $Modtime:: 4/02/99 11:56a $*
|
||||
* *
|
||||
* $Revision:: 3 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#if !defined(WATCOM_H) && defined(__WATCOMC__)
|
||||
#define WATCOM_H
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
** The "bool" integral type was defined by the C++ comittee in
|
||||
** November of '94. Until the compiler supports this, use the following
|
||||
** definition.
|
||||
*/
|
||||
#include "bool.h"
|
||||
|
||||
// Turn all warnings into errors.
|
||||
#pragma warning * 0
|
||||
|
||||
// Disables warning when "sizeof" is used on an object with virtual functions.
|
||||
#pragma warning 549 9
|
||||
|
||||
// Disable the "Integral value may be truncated during assignment or initialization".
|
||||
#pragma warning 389 9
|
||||
|
||||
// Allow constructing a temporary to be used as a parameter.
|
||||
#pragma warning 604 9
|
||||
|
||||
// Disable the construct resolved as an expression warning.
|
||||
#pragma warning 595 9
|
||||
|
||||
// Disable the strange "construct resolved as a declaration/type" warning.
|
||||
#pragma warning 594 9
|
||||
|
||||
// Disable the "pre-compiled header file cannot be used" warning.
|
||||
#pragma warning 698 9
|
||||
|
||||
// Disable the "temporary object used to initialize a non-constant reference" warning.
|
||||
#pragma warning 665 9
|
||||
|
||||
// Disable the "pointer or reference truncated by cast. Cast is supposed to REMOVE warnings, not create them.
|
||||
#pragma warning 579 9
|
||||
|
||||
// Disable the warning that suggests a null destructor be placed in class definition.
|
||||
#pragma warning 656 9
|
||||
|
||||
// Disable the warning about moving empty constructors/destructors to the class declaration.
|
||||
#pragma warning 657 9
|
||||
|
||||
// No virtual destructor is not an error in C&C.
|
||||
#pragma warning 004 9
|
||||
|
||||
// Integral constant will be truncated warning is usually ok when dealing with bitfields.
|
||||
#pragma warning 388 9
|
||||
|
||||
// Turns off unreferenced function parameter warning.
|
||||
//#pragma off(unreferenced)
|
||||
|
||||
/*
|
||||
** The "bool" integral type was defined by the C++ comittee in
|
||||
** November of '94. Until the compiler supports this, use the following
|
||||
** definition.
|
||||
*/
|
||||
#include "bool.h"
|
||||
|
||||
#if !defined(__BORLANDC__)
|
||||
#define M_E 2.71828182845904523536
|
||||
#define M_LOG2E 1.44269504088896340736
|
||||
#define M_LOG10E 0.434294481903251827651
|
||||
#define M_LN2 0.693147180559945309417
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#define M_PI_4 0.785398163397448309616
|
||||
#define M_1_PI 0.318309886183790671538
|
||||
#define M_2_PI 0.636619772367581343076
|
||||
#define M_1_SQRTPI 0.564189583547756286948
|
||||
#define M_2_SQRTPI 1.12837916709551257390
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#define M_SQRT_2 0.707106781186547524401
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
91
Code/Tools/pluglib/win.h
Normal file
91
Code/Tools/pluglib/win.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/win.h $*
|
||||
* *
|
||||
* $Author:: Ian_l $*
|
||||
* *
|
||||
* $Modtime:: 10/16/01 2:42p $*
|
||||
* *
|
||||
* $Revision:: 11 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef WIN_H
|
||||
#define WIN_H
|
||||
|
||||
/*
|
||||
** This header file includes the Windows headers. If there are any special pragmas that need
|
||||
** to occur around this process, they are performed here. Typically, certain warnings will need
|
||||
** to be disabled since the Windows headers are repleat with illegal and dangerous constructs.
|
||||
**
|
||||
** Within the windows headers themselves, Microsoft has disabled the warnings 4290, 4514,
|
||||
** 4069, 4200, 4237, 4103, 4001, 4035, 4164. Makes you wonder, eh?
|
||||
*/
|
||||
|
||||
// When including windows, lets just bump the warning level back to 3...
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
// this define should also be in the DSP just in case someone includes windows stuff directly
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
//#include <mmsystem.h>
|
||||
//#include <windowsx.h>
|
||||
//#include <winnt.h>
|
||||
//#include <winuser.h>
|
||||
|
||||
#if (_MSC_VER >= 1200)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
extern HINSTANCE ProgramInstance;
|
||||
extern HWND MainWindow;
|
||||
extern bool GameInFocus;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
void __cdecl Print_Win32Error(unsigned long win32Error);
|
||||
|
||||
#else // _DEBUG
|
||||
|
||||
#define Print_Win32Error
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
#else // _WINDOWS
|
||||
//#include <unistd.h>
|
||||
#endif // _WINDOWS
|
||||
|
||||
#endif // WIN_H
|
||||
113
Code/Tools/pluglib/wwfile.h
Normal file
113
Code/Tools/pluglib/wwfile.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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 : Command & Conquer *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwlib/wwfile.h $*
|
||||
* *
|
||||
* $Author:: Ian_l $*
|
||||
* *
|
||||
* $Modtime:: 10/31/01 2:00p $*
|
||||
* *
|
||||
* $Revision:: 9 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
#if _MSC_VER >= 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER >= 1000
|
||||
|
||||
#ifndef WWFILE_Hx
|
||||
#define WWFILE_Hx
|
||||
|
||||
#ifdef _UNIX
|
||||
#include "osdep.h"
|
||||
#endif
|
||||
|
||||
#define YEAR(dt) (((dt & 0xFE000000) >> (9 + 16)) + 1980)
|
||||
#define MONTH(dt) ((dt & 0x01E00000) >> (5 + 16))
|
||||
#define DAY(dt) ((dt & 0x001F0000) >> (0 + 16))
|
||||
#define HOUR(dt) ((dt & 0x0000F800) >> 11)
|
||||
#define MINUTE(dt) ((dt & 0x000007E0) >> 5)
|
||||
#define SECOND(dt) ((dt & 0x0000001F) << 1)
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0 // Seek from start of file.
|
||||
#define SEEK_CUR 1 // Seek relative from current location.
|
||||
#define SEEK_END 2 // Seek from end of file.
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
class FileClass
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
PRINTF_BUFFER_SIZE = 1024
|
||||
};
|
||||
|
||||
virtual ~FileClass(void) {};
|
||||
virtual char const * File_Name(void) const = 0;
|
||||
virtual char const * Set_Name(char const *filename) = 0;
|
||||
virtual int Create(void) = 0;
|
||||
virtual int Delete(void) = 0;
|
||||
virtual bool Is_Available(int forced=false) = 0;
|
||||
virtual bool Is_Open(void) const = 0;
|
||||
virtual int Open(char const *filename, int rights=READ) = 0;
|
||||
virtual int Open(int rights=READ) = 0;
|
||||
virtual int Read(void *buffer, int size) = 0;
|
||||
virtual int Seek(int pos, int dir=SEEK_CUR) = 0;
|
||||
virtual int Tell(void) { return Seek(0); }
|
||||
virtual int Size(void) = 0;
|
||||
virtual int Write(void const *buffer, int size) = 0;
|
||||
virtual void Close(void) = 0;
|
||||
virtual unsigned long Get_Date_Time(void) {return(0);}
|
||||
virtual bool Set_Date_Time(unsigned long ) {return(false);}
|
||||
virtual void Error(int error, int canretry = false, char const * filename=NULL) = 0;
|
||||
virtual void * Get_File_Handle(void) { return reinterpret_cast<void *>(-1); }
|
||||
virtual void Bias(int start, int length=-1) = 0;
|
||||
|
||||
operator char const * ()
|
||||
{
|
||||
return File_Name();
|
||||
}
|
||||
|
||||
// this form uses a stack buffer of PRINTF_BUFFER_SIZE
|
||||
int Printf(char *str, ...);
|
||||
|
||||
// this form uses the supplied buffer if PRINTF_BUFFER_SIZE is expected to be too small.
|
||||
int Printf(char *buffer, int bufferSize, char *str, ...);
|
||||
|
||||
// this form uses the stack buffer but will prepend any output with the indicated number of tab characters '\t'
|
||||
int Printf_Indented(unsigned depth, char *str, ...);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
47
Code/Tools/pluglib/wwmath.cpp
Normal file
47
Code/Tools/pluglib/wwmath.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/wwmath.cpp $*
|
||||
* *
|
||||
* Author:: Eric_c *
|
||||
* *
|
||||
* $Modtime:: 3/18/99 10:39a $*
|
||||
* *
|
||||
* $Revision:: 5 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "wwmath.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
float WWMath::Random_Float(void)
|
||||
{
|
||||
return ((float)(rand() & 0xFFF)) / (float)(0xFFF);
|
||||
}
|
||||
257
Code/Tools/pluglib/wwmath.h
Normal file
257
Code/Tools/pluglib/wwmath.h
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** 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/wwmath/wwmath.h $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 3/16/00 8:28p $*
|
||||
* *
|
||||
* $Revision:: 40 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef WWMATH_H
|
||||
#define WWMATH_H
|
||||
|
||||
#include "always.h"
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
** Some global constants.
|
||||
*/
|
||||
#define WWMATH_EPSILON 0.0001f
|
||||
#define WWMATH_EPSILON2 WWMATH_EPSILON * WWMATH_EPSILON
|
||||
#define WWMATH_PI 3.141592654f
|
||||
#define WWMATH_FLOAT_MAX (FLT_MAX)
|
||||
#define WWMATH_SQRT2 1.414213562f
|
||||
#define WWMATH_SQRT3 1.732050808f
|
||||
#define WWMATH_OOSQRT2 0.707106781f
|
||||
#define WWMATH_OOSQRT3 0.577350269f
|
||||
|
||||
|
||||
/*
|
||||
** Macros to convert between degrees and radians
|
||||
*/
|
||||
#ifndef RAD_TO_DEG
|
||||
#define RAD_TO_DEG(x) (((double)x)*180.0/WWMATH_PI)
|
||||
#endif
|
||||
|
||||
#ifndef DEG_TO_RAD
|
||||
#define DEG_TO_RAD(x) (((double)x)*WWMATH_PI/180.0)
|
||||
#endif
|
||||
|
||||
#ifndef RAD_TO_DEGF
|
||||
#define RAD_TO_DEGF(x) (((float)x)*180.0f/WWMATH_PI)
|
||||
#endif
|
||||
|
||||
#ifndef DEG_TO_RADF
|
||||
#define DEG_TO_RADF(x) (((float)x)*WWMATH_PI/180.0f)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Some simple math functions which work on the built-in types.
|
||||
** Include the various other header files in the WWMATH library
|
||||
** in order to get matrices, quaternions, etc.
|
||||
*/
|
||||
class WWMath
|
||||
{
|
||||
public:
|
||||
|
||||
static float Fabs(float val) { return (float)fabs(val); }
|
||||
static float Sqrt(float val) { return (float)sqrt(val); }
|
||||
static float Inv_Sqrt(float val) { return 1.0f / (float)sqrt(val); }
|
||||
static float Sign(float val);
|
||||
static float Floor(float val) { return (float)floor(val); }
|
||||
static bool Fast_Is_Float_Positive(const float & val);
|
||||
|
||||
static float Random_Float(void);
|
||||
static float Random_Float(float min,float max);
|
||||
static float Clamp(float val, float min = 0.0f, float max = 1.0f);
|
||||
static double Clamp(double val, double min = 0.0f, double max = 1.0f);
|
||||
static float Wrap(float val, float min = 0.0f, float max = 1.0f);
|
||||
static double Wrap(double val, double min = 0.0f, double max = 1.0f);
|
||||
static float Min(float a, float b);
|
||||
static float Max(float a, float b);
|
||||
|
||||
static float Lerp(float a, float b, float lerp );
|
||||
static double Lerp(double a, double b, float lerp );
|
||||
|
||||
static long Float_To_Long(float f);
|
||||
static long Float_To_Long(double f);
|
||||
|
||||
static unsigned char Unit_Float_To_Byte(float f) { return (unsigned char)(f*255.0f); }
|
||||
static float Byte_To_Unit_Float(unsigned char byte) { return ((float)byte) / 255.0f; }
|
||||
|
||||
static bool Is_Valid_Float(float x);
|
||||
static bool Is_Valid_Double(double x);
|
||||
|
||||
};
|
||||
|
||||
inline float WWMath::Sign(float val)
|
||||
{
|
||||
if (val > 0.0f) {
|
||||
return +1.0f;
|
||||
}
|
||||
if (val < 0.0f) {
|
||||
return -1.0f;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
inline bool WWMath::Fast_Is_Float_Positive(const float & val)
|
||||
{
|
||||
return !((*(int *)(&val)) & 0x80000000);
|
||||
}
|
||||
|
||||
inline float WWMath::Random_Float(float min,float max)
|
||||
{
|
||||
return Random_Float() * (max-min) + min;
|
||||
}
|
||||
|
||||
inline float WWMath::Clamp(float val, float min /*= 0.0f*/, float max /*= 1.0f*/)
|
||||
{
|
||||
if(val < min) return min;
|
||||
if(val > max) return max;
|
||||
return val;
|
||||
}
|
||||
|
||||
inline double WWMath::Clamp(double val, double min /*= 0.0f*/, double max /*= 1.0f*/)
|
||||
{
|
||||
if(val < min) return min;
|
||||
if(val > max) return max;
|
||||
return val;
|
||||
}
|
||||
|
||||
inline float WWMath::Wrap(float val, float min /*= 0.0f*/, float max /*= 1.0f*/)
|
||||
{
|
||||
// Implemented as an if rather than a while, to long loops
|
||||
if ( val >= max ) val -= (max-min);
|
||||
if ( val < min ) val += (max-min);
|
||||
|
||||
if ( val < min ) {
|
||||
val = min;
|
||||
}
|
||||
if ( val > max ) {
|
||||
val = max;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
inline double WWMath::Wrap(double val, double min /*= 0.0f*/, double max /*= 1.0f*/)
|
||||
{
|
||||
// Implemented as an if rather than a while, to long loops
|
||||
if ( val >= max ) val -= (max-min);
|
||||
if ( val < min ) val += (max-min);
|
||||
if ( val < min ) {
|
||||
val = min;
|
||||
}
|
||||
if ( val > max ) {
|
||||
val = max;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
inline float WWMath::Min(float a, float b)
|
||||
{
|
||||
if (a<b) return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
inline float WWMath::Max(float a, float b)
|
||||
{
|
||||
if (a>b) return a;
|
||||
return b;
|
||||
}
|
||||
|
||||
inline float WWMath::Lerp(float a, float b, float lerp )
|
||||
{
|
||||
return (a + (b - a)*lerp);
|
||||
}
|
||||
|
||||
inline double WWMath::Lerp(double a, double b, float lerp )
|
||||
{
|
||||
return (a + (b - a)*lerp);
|
||||
}
|
||||
|
||||
|
||||
inline long WWMath::Float_To_Long (float f)
|
||||
{
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
long retval;
|
||||
__asm fld dword ptr [f]
|
||||
__asm fistp dword ptr [retval]
|
||||
return retval;
|
||||
#else
|
||||
return (long) f;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline long WWMath::Float_To_Long (double f)
|
||||
{
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
long retval;
|
||||
__asm fld qword ptr [f]
|
||||
__asm fistp dword ptr [retval]
|
||||
return retval;
|
||||
#else
|
||||
return (long) f;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool WWMath::Is_Valid_Float(float x)
|
||||
{
|
||||
unsigned long * plong = (unsigned long *)(&x);
|
||||
unsigned long exponent = ((*plong) & 0x7F800000) >> (32-9);
|
||||
|
||||
// if exponent is 0xFF, this is a NAN
|
||||
if (exponent == 0xFF) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool WWMath::Is_Valid_Double(double x)
|
||||
{
|
||||
unsigned long * plong = (unsigned long *)(&x) + 1;
|
||||
unsigned long exponent = ((*plong) & 0x7FF00000) >> (32-12);
|
||||
|
||||
// if exponent is 0x7FF, this is a NAN
|
||||
if (exponent == 0x7FF) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user