Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

View 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/>.
*/
/* $Header: /Commando/Code/Tests/mathtest/P_timer.cpp 2 7/22/97 1:14p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Voxel Technology *
* *
* File Name : P_TIMER.CPP *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 02/24/97 *
* *
* Last Update : February 24, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "p_timer.h"
#ifndef __WATCOMC__
unsigned Get_CPU_Clock ( void )
{
__asm {
_emit 0x0f
_emit 0x31
}
}
#endif

View File

@@ -0,0 +1,54 @@
/*
** 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/>.
*/
//****************************************************************************
// Get_CPU_Clock -- Fetches the current CPU clock time.
//
// This routine will return the internal Pentium clock accumulator. This
// accumulator is incremented every clock tick. Since this clock value can
// get very very large, the value returned is in 64 bits. The low half is
// returned directly, the high half is stored in location specified.
//
// INPUT: high -- Reference to the high value of the 64 bit clock number.
//
// OUTPUT: Returns with the low half of the CPU clock value.
//
// WARNINGS: This instruction is only available on Pentium or later
// processors.
//
// HISTORY:
// 07/17/1996 JLB : Created.
//============================================================================
#ifdef __BORLANDC__
extern "C" unsigned Get_CPU_Clock ( void );
#else
unsigned Get_CPU_Clock ( void );
#ifdef __WATCOMC__
#pragma aux Get_CPU_Clock \
modify [edx] \
value [eax] = \
"db 0fh,031h"
#endif
#endif

View File

@@ -0,0 +1,321 @@
/*
** 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 Test Program *
* *
* $Archive:: /Commando/Code/Tests/mathtest/aaboxtest.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/13/00 4:33p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "aaboxtest.h"
#include "output.h"
#include "vector3.h"
#include "tri.h"
#include "aabox.h"
#include "wwmath.h"
#include "colmath.h"
#include "p_timer.h"
#include <stdio.h>
class AABoxTriTestClass
{
public:
AABoxClass Box;
Vector3 BoxMove;
Vector3 V0;
Vector3 V1;
Vector3 V2;
Vector3 N;
TriClass Tri;
float Fraction;
bool StartBad;
AABoxTriTestClass
(
const Vector3 c, // center of box
const Vector3 e, // extent of box
const Vector3 m, // move for the box
const Vector3 v0, // v0 of triangle
const Vector3 v1, // v1 of triangle
const Vector3 v2, // v2 of triangle
float frac, // expected fraction
bool sol // expected start solid
)
{
BoxMove = m;
V0 = v0;
V1 = v1;
V2 = v2;
Fraction = frac;
StartBad = sol;
/*
** Initialize the triangle
*/
Tri.V[0] = &V0;
Tri.V[1] = &V1;
Tri.V[2] = &V2;
Tri.N = & N;
Tri.Compute_Normal();
/*
** Initialize the box
*/
Box.Center = c;
Box.Extent = e;
}
};
AABoxTriTestClass Test0
(
Vector3(0,0,0), // box starting at origing
Vector3(2,1,1), // 2 units along x, 1 y, 1 z
Vector3(1,0,0), // moving 5 along x axis
Vector3(6,-3,-1), // triangle crossing x and y extent but not colliding
Vector3(8,-1,2),
Vector3(9,0,-1),
1.0f,
false
);
AABoxTriTestClass Test1
(
Vector3(3,0,0),
Vector3(1,2,1),
Vector3(0,-2,0),
Vector3(1,-3,0),
Vector3(2,-3,5),
Vector3(6,-3,1),
0.5f,
false
);
AABoxTriTestClass Test2
(
Vector3(-3.5,-1.5,0), // sweeping a 3x3 box along pos x and neg y
Vector3(1.5,1.5,1.5),
Vector3(4,-4,0),
Vector3(-4,-4,-1), // into a polygon in y-z plane
Vector3(-2,-4,5),
Vector3(0,-4,1),
0.25f, // should only move 25%
false
);
AABoxTriTestClass Test3
(
Vector3(-3.5,-1.5,0) + 0.25f * Vector3(4,-4,0),
Vector3(1.5,1.5,1.5), // starting at end of test2's move, should be 0.0 but not StartBad!
Vector3(4,-4,0),
Vector3(-4,-4,-1), // into a polygon in y-z plane
Vector3(-2,-4,5),
Vector3(0,-4,1),
0.0f,
false
);
AABoxTriTestClass Test4
(
Vector3(-3.5f,-1.5f,0), // Same as test 2
Vector3(1.5f,1.5f,1.5f),
Vector3(4,-4,0),
Vector3(-9,-4,-1), // into a polygon in y-z plane *but* just barely not in the way
Vector3(-8,-4,5),
Vector3(-4.001f,-4,0),
1.0f, // should move 100%
false
);
AABoxTriTestClass Test5
(
Vector3(-3.5,-1.5,0), // Same as test 3 with box brushing polygon vertex.
Vector3(1.5,1.5,1.5),
Vector3(4,-4,0),
Vector3(-9,-4,-1), // into a polygon in y-z plane just touching path of box
Vector3(-8,-4,5),
Vector3(-4,-4,0),
1.0f, // should move 100%
false
);
AABoxTriTestClass Test6
(
Vector3(-3.5,-1.5,0), // Same as test 3 with box brushing polygon vertex.
Vector3(1.5,1.5,1.5),
Vector3(4,-4,0),
Vector3(-9,-4,-1), // into a polygon in y-z plane just touching path of box
Vector3(-8,-4,5),
Vector3(-4,-4,0),
1.0f, // should move 100%
false
);
AABoxTriTestClass Test7
(
Vector3(0,0,0), // This is a case where the box starts out intersecting
Vector3(5,5,5),
Vector3(4,4,0),
Vector3(1,4,-1),
Vector3(2,4,5),
Vector3(5,4,0),
0.0f,
true
);
AABoxTriTestClass Test8
(
Vector3(-2.5,2,0),
Vector3(1.5,1,1),
Vector3(3,0,0),
Vector3(1,2,0),
Vector3(3,4,5),
Vector3(4,5,-1),
0.66666667f,
true
);
AABoxTriTestClass * AABoxTriTestCases[] =
{
&Test0,
&Test1,
&Test2,
&Test3,
&Test4,
&Test5,
&Test6,
&Test7,
&Test8
};
void Test_AABoxes(void)
{
int i;
Print_Title("Testing AABox volume sweeping.");
/*
** Test the sweep function with a bunch of boxes and triangles
*/
CastResultStruct result;
int numtests = sizeof(AABoxTriTestCases)/sizeof(AABoxTriTestClass *);
unsigned cycles;
// prime the cache
AABoxTriTestClass * testcase = AABoxTriTestCases[4];
cycles = Get_CPU_Clock();
CollisionMath::Collide(testcase->Box,testcase->BoxMove,testcase->Tri,&result);
cycles = Get_CPU_Clock() - cycles;
// Now time and test the routine. Repeating and averaging time for each test
float * cycle_counts = new float[numtests];
for (i=0; i<numtests;i++) {
cycle_counts[i] = 0.0f;
}
int num_repetitions = 50;
for (int repeat = 0; repeat < num_repetitions; repeat++) {
for (i=0; i<numtests; i++) {
testcase = AABoxTriTestCases[i];
result.Fraction = 1.0;
result.StartBad = false;
result.Normal.Set(0,0,0);
cycles = Get_CPU_Clock();
CollisionMath::Collide(testcase->Box,testcase->BoxMove,testcase->Tri,&result);
cycles = Get_CPU_Clock() - cycles;
printf("AABox -> Tri cycles: %d\n",cycles);
cycle_counts[i] += cycles;
if ((WWMath::Fabs(testcase->Fraction - result.Fraction) > WWMATH_EPSILON) ||
(testcase->StartBad != result.StartBad))
{
printf("test %d failed!\n",i);
} else {
printf("test %d passed...\n",i);
}
}
}
printf("\n");
for (i=0; i<numtests;i++) {
cycle_counts[i] /= (float)num_repetitions;
printf("Test%d Average Cycles: %f\r\n",i,cycle_counts[i]);
}
/*
** Test a box moving down the z-axis to a polygon, then moving along
** the x-axis along the surface of the polygon.
*/
AABoxClass testbox;
Vector3 move;
Vector3 v0,v1,v2,n;
TriClass testtri;
v0.Set(0,1,0);
v1.Set(-1,-1,0);
v2.Set(1,1,0);
testtri.V[0] = &v0;
testtri.V[1] = &v1;
testtri.V[2] = &v2;
testtri.N = &n;
testtri.Compute_Normal();
testbox.Center.Set(0,0,2.363f);
testbox.Extent.Set(1,1,1);
move.Set(0,0,-5.0f);
CastResultStruct cres;
cres.StartBad = 0;
cres.Fraction = 1.0f;
CollisionMath::Collide(testbox,move,testtri,&cres);
printf("fraction = %f\n",cres.Fraction);
testbox.Center += cres.Fraction * move;
move.Set(1.0f,1.0f,0.0f);
cres.StartBad = 0;
cres.Fraction = 1.0f;
CollisionMath::Collide(testbox,move,testtri,&cres);
printf("fraction = %f\n",cres.Fraction);
testbox.Center += cres.Fraction * move;
}

View 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/>.
*/
/***********************************************************************************************
*** 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 Test Program *
* *
* $Archive:: /Commando/Code/Tests/mathtest/aaboxtest.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/27/98 9:42a $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef AABOXTEST_H
#define AABOXTEST_H
void Test_AABoxes(void);
#endif

View 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/>.
*/
/*
This file contains some math functions that Jan worked on while visiting westwood
between Meltdown and Siggraph 2001.
*/
#include <iostream>
#include <iomanip>
#include <cmath>
#include "p_timer.h"
#include "wwmath.h"
using namespace std;
#undef for
#define for if(false); else for
/* (1-u)(1-u)(1-u)
--------------- 1/6 0/6
6
3*u*u*u - 6u*u +4
--------------- 4/6 1/6
6
-3*u*u*u + 3*u*u + 3*u + 1
--------------- 1/6 4/6
6
u*u*u
--------------- 0/6 1/6
6
*/
const double pi = 3.1415926535897932384626433832795;
const int SINTABLESIZE = 16;
float sinTable[SINTABLESIZE+1][3];
/*
float sinTable[SINTABLESIZE+1][3] =
{
0.f, 0.0327249329938f, 0.0654498139838f,
0.0980171403296f, 0.130584524375f, 0.16299423692f,
0.195090322016f, 0.22718650856f, 0.258968953094f,
0.290284677254f, 0.321600570763f, 0.352449632798f,
0.382683432365f, 0.412917427848f, 0.442536062284f,
0.471396736826f, 0.5002577f, 0.528360611467f,
0.55557023302f, 0.582780177536f, 0.609096734804f,
0.634393284164f, 0.659690191419f, 0.683966978964f,
0.707106781187f, 0.730247032377f, 0.752250161646f,
0.773010453363f, 0.79377112016f, 0.813288873188f,
0.831469612303f, 0.849650815039f, 0.866495135964f,
0.881921264348f, 0.897347904711f, 0.911356511164f,
0.923879532511f, 0.936403079986f, 0.947441092993f,
0.956940335732f, 0.966440181792f, 0.974401217255f,
0.980785280403f, 0.987169903631f, 0.991977366409f,
0.995184726672f, 0.998392578191f, 1.0000003005f,
1.f, 1.0000003005f, 0.998392578191f,
};
*/
void init_bez_sin()
{
for(int i=0; i<SINTABLESIZE+1; i++)
{
double x = sin(pi/2*(i*3)/(SINTABLESIZE*3));
double y = sin(pi/2*(i*3+1)/(SINTABLESIZE*3)); // * 1.00053f;
double z = sin(pi/2*(i*3+2)/(SINTABLESIZE*3)); // * 1.00053f;
double w = sin(pi/2*(i*3+3)/(SINTABLESIZE*3));
double mse = 4.0;
double my = 1.0;
double mz = 1.0;
// * nu2 * nu;
// nu2;
// u * nu;
// * u2 * u;
double wy = 4.0;
for(double dy=1.000178; dy<1.000537; dy+=0.0000001)
{
bool b = false;
double wz = 4.0;
for(double dz=1.000534; dz<1.000715; dz+=0.0000001)
{
double by = x * 8.0 / 27.0 +
y * dy * 12.0 / 27.0 +
z * dz * 6.0 / 27.0 +
w / 27.0;
double bz = x / 27.0 +
y * dy * 6.0 / 27.0 +
z * dz * 12.0 / 27.0 +
w * 8.0 / 27.0;
if(y*dy < 0.0 || y*dy > 1.0)
continue;
if(z*dz < 0.0 || z*dz > 1.0)
continue;
double yerr, zerr;
// if(by > y)
// yerr = by/y;
// else
yerr = y/by;
// if(bz > z)
// zerr = bz/z;
// else
zerr = z/bz;
yerr -= 1.0;
zerr -= 1.0;
double se = yerr*yerr + zerr*zerr;
if(mse > se)
{
wy = se;
wz = se;
mse = se;
my = dy;
mz = dz;
b = false;
}
else
{
// if(se > wy)
// b = true;
// if(se > wz)
// break;
}
}
// if(b)
// break;
}
sinTable[i][0] = float(x);
sinTable[i][1] = float(y * my);
sinTable[i][2] = float(z * mz);
cout << setprecision(12);
cout << setw(16) << x << "f, " << setw(16) << y*my << "f, " << setw(16) << z*mz << "f," << endl;
}
}
const int ACOSTABLESIZE = 32;
//float acosTable[ACOSTABLESIZE+1][3];
float acosTable[ACOSTABLESIZE+1][3] =
{
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
2.09439510239f, 2.07033956061f, 2.04678164613f,
2.02361292154f, 2.00044498842f, 1.97766674853f,
1.95519310129f, 1.93271994669f, 1.91055213001f,
1.88862003072f, 1.86668845355f, 1.84499333386f,
1.82347658194f, 1.80196011523f, 1.7806223216f,
1.75941271297f, 1.73820326172f, 1.71712229397f,
1.69612415796f, 1.67512622765f, 1.65421121018f,
1.63333708859f, 1.61246303408f, 1.59162963139f,
1.57079632679f, 1.54996304584f, 1.52912960772f,
1.508255565f, 1.48738138962f, 1.46646655946f,
1.44546849563f, 1.42447034954f, 1.40338938542f,
1.38217994062f, 1.36097042076f, 1.33963248005f,
1.31811607165f, 1.29659929615f, 1.27490425438f,
1.25297262287f, 1.23104063033f, 1.20887262684f,
1.1863995523f, 1.16392587108f, 1.14114765337f,
1.11797973205f, 1.09481095108f, 1.07125317716f,
1.0471975512f, 1.0231405f, 0.998586616212f,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0
};
double calc_cos_plus_45(double cx)
{
double sx = sqrt(1-cx*cx);
cx = cx*cos(pi/4) - sx*sin(pi/4);
return cx;
}
void init_bez_acos()
{
for(int i=0; i<ACOSTABLESIZE; i++)
{
// if(i < ACOSTABLESIZE/4 || i > ACOSTABLESIZE/4*3)
// continue;
double x = acos(float(i*3)/(ACOSTABLESIZE*3)*2-1);
double y = acos(float(i*3+1)/(ACOSTABLESIZE*3)*2-1); // * 1.00053f;
double z = acos(float(i*3+2)/(ACOSTABLESIZE*3)*2-1); // * 1.00053f;
double w;
if(i != ACOSTABLESIZE-1)
w = acos(float(i*3+3)/(ACOSTABLESIZE*3)*2-1);
else
w = 0.0;//-acos(float(i*3+1)/(ACOSTABLESIZE*3)*2-1);
double mse = 4.0;
double my = 1.0;
double mz = 1.0;
double wy = 4.0;
for(double dy=0.9996944; dy<=1.0006926; dy+=16.0/8388608)
{
bool b = false;
double wz = 4.0;
for(double dz=0.9997872; dz<=1.0011092; dz+=16.0/8388608)
{
double by = x * 8.0 / 27.0 +
y * dy * 12.0 / 27.0 +
z * dz * 6.0 / 27.0 +
w / 27.0;
double bz = x / 27.0 +
y * dy * 6.0 / 27.0 +
z * dz * 12.0 / 27.0 +
w * 8.0 / 27.0;
if(y*dy < 0.0 || y*dy > pi)
continue;
if(z*dz < 0.0 || z*dz > pi)
continue;
double yerr, zerr;
// if(by > y)
// yerr = by/y;
// else
yerr = y/by;
// if(bz > z)
// zerr = bz/z;
// else
zerr = z/bz;
yerr -= 1.0;
zerr -= 1.0;
double se = yerr*yerr + zerr*zerr;
if(mse > se)
{
wy = se;
wz = se;
mse = se;
my = dy;
mz = dz;
b = false;
}
else
{
// if(se > wy)
// b = true;
// if(se > wz)
// break;
}
}
// if(b)
// break;
}
acosTable[i][0] = float(x);
acosTable[i][1] = float(y * my);
acosTable[i][2] = float(z * mz);
cout << setprecision(12);
cout << setw(16) << x << "f, " << setw(16) << y*my << "f, " << setw(16) << z*mz << "f," << endl;
// cout << my << " " << mz << endl;
}
acosTable[ACOSTABLESIZE][0] = 0.f;
}
float bez_sin(float x)
{
x *= (SINTABLESIZE*4)/(pi*2);
int ix0 = int(floor(x));
float u = x - ix0;
float nu = 1.f-u;
float sign = 1.f;
ix0 &= SINTABLESIZE*4-1;
if(ix0 >= SINTABLESIZE*2)
{
sign = -1.f;
ix0 -= SINTABLESIZE*2;
}
if(ix0 >= SINTABLESIZE)
{
ix0 = (SINTABLESIZE-1)-(ix0-SINTABLESIZE);
float t = u;
u = nu;
nu = t;
}
int ix1 = ix0+1;
// ix0 &= SINTABLESIZE-1;
// ix1 &= SINTABLESIZE-1;
float u2 = u*u;
float nu2 = nu*nu;
float r0 = sinTable[ix0][0] * nu2 * nu;
float r1 = sinTable[ix0][1] * 3 * u * nu2;
float r2 = sinTable[ix0][2] * 3 * u2 * nu;
float r3 = sinTable[ix1][0] * u2 * u;
r0 += r1;
r2 += r3;
return (r0+r2) * sign;
}
float bez_acos(float x)
{
// double sx = sqrt(1-x*x);
// x = x*cos(pi/4) - sx*sin(pi/4);
x = calc_cos_plus_45(x);
x += 1.f;
x *= ACOSTABLESIZE/2;
int ix0 = int(floor(x));
float u = x - ix0;
float nu = 1.f-u;
if(ix0 < 0)
return pi-pi/4; // -infinite...
if(ix0 >= ACOSTABLESIZE)
return 0.f;
int ix1 = ix0+1;
float u2 = u*u;
float nu2 = nu*nu;
float r0 = acosTable[ix0][0] * nu2 * nu;
float r1 = acosTable[ix0][1] * 3 * u * nu2;
float r2 = acosTable[ix0][2] * 3 * u2 * nu;
float r3 = acosTable[ix1][0] * u2 * u;
r0 += r1;
r2 += r3;
return (r0+r2)-pi/4;
}
float mcos(float c, float m)
{
float ac = acos(c);
float c1 = cos(ac*m);
float c2 = cos(ac*(1-m));
float c3 = c * cos(m);
return c1;
}
float cheb_asin(float x)
{
float table[] =
{
1.101460576f,
+.5764093225f,
-.09735417608f,
+.003083774398f,
-.000844493744f,
+.005722363752f,
-.005962135984f
};
float r = table[0] + table[1]*x;
r -= sqrt(1-x*x);
x = 2.f*x-1.f;
float x2 = x;
x *= x;
for(int i=2; i<sizeof(table)/sizeof(table[0]); i++)
{
r += x * table[i];
x *= x2;
}
return r;
}
float taylor_acos(float x)
{
/*
(1) /(2*3),
(3) /(2*4*5),
(3*5) /(2*4*6*7),
(3*5*7) /(2*4*6*8*9),
(3*5*7*9) /(2*4*6*8*10*11),
(3*5*7*9*11) /(2*4*6*8*10*12*13),
(3*5*7*9*11*13) /(2*4*6*8*10*12*14*15),
(3*5*7*9*11*13*15) /(2*4*6*8*10*12*14*16*17),
(3*5*7*9*11*13*15*17) /(2*4*6*8*10*12*14*16*18*19),
*/
float table[] =
{
1.f,
float(1) /(2*3),
float(3) /(2*4*5),
float(5) /(2*4*2*7),
float(5*7) /(2*4*2*8*9),
float(7*9) /(2*4*2*8*2*11),
float(7*9*11) /(2*4*2*8*2*12*13),
float(9*11*13) /(2*4*2*8*2*12*2*15),
float(9*11*13*15) /(2*4*2*8*2*12*2*16*17),
float(11*13*15*17) /(2*4*2*8*2*12*2*16*2*19),
};
// x = sqrt((1.f+x)/2.f);
bool flip = false;
if(x > 0.707106781186547524400844362104849f)
{
x = 0.707106781186547524400844362104849f - (x-0.707106781186547524400844362104849f);
flip = true;
}
float r = 1.57079632679489661923132169163975f;
float x2 = x*x;
for(int i=0; i<sizeof(table)/sizeof(table[0]); i++)
{
r -= x * table[i];
x *= x2;
}
if(flip)
{
r = 1.57079632679489661923132169163975f-r;
}
return r;
}
/*
taylor acos
3 5 7 9 11
%PI X 3 X 5 X 35 X 63 X
--- - X - -- - ---- - ---- - ----- - ------
2 6 40 112 1152 2816
taylor(sin(x),x,0,9);
3 5 7 9
X X X X
X - -- + --- - ---- + ------ + . . .
3! 5! 7! 9!
taylor cos
2 4 6 8
X X X X
1 - -- + -- - --- + ----- + . . .
2! 4! 6! 8!
*/
int intChop(const float& f)
{
int a = *reinterpret_cast<const int*>(&f); // take bit pattern of float into a register
int sign = (a>>31); // sign = 0xFFFFFFFF if original value is negative, 0 if positive
int mantissa = (a&((1<<23)-1))|(1<<23); // extract mantissa and add the hidden bit
int exponent = ((a&0x7fffffff)>>23)-127; // extract the exponent
int r = (unsigned int(mantissa)<<8)>>(31-exponent); // ((1<<exponent)*mantissa)>>24 -- (we know that mantissa > (1<<24))
return ((r ^ (sign)) - sign ) &~ (exponent>>31); // add original sign. If exponent was negative, make return value 0.
}
int intFloor (const float& f)
{
int a = *reinterpret_cast<const int*>(&f); // take bit pattern of float into a register
int sign = (a>>31); // sign = 0xFFFFFFFF if original value is negative, 0 if positive
a&=0x7fffffff; // we don't need the sign any more
int exponent = (a>>23)-127; // extract the exponent
int expsign = ~(exponent>>31); // 0xFFFFFFFF if exponent is positive, 0 otherwise
int imask = ( (1<<(31-(exponent))))-1; // mask for true integer values
int mantissa = (a&((1<<23)-1)); // extract mantissa (without the hidden bit)
int r = (unsigned int(mantissa|(1<<23))<<8)>>(31-exponent); // ((1<<exponent)*(mantissa|hidden bit))>>24 -- (we know that mantissa > (1<<24))
r = ((r & expsign) ^ (sign)) + ((!((mantissa<<8)&imask)&(expsign^((a-1)>>31)))&sign); // if (fabs(value)<1.0) value = 0; copy sign; if (value < 0 && value==(int)(value)) value++;
return r;
}
const int CACHE_TRASH_BUFFER_SIZE = 4024000;
int * CacheTrashBuffer = NULL;
volatile int ReadVar;
void trash_the_cache(void)
{
// read a million random bytes and overwrite them with a new value
for (int j=0; j<1024000; j++) {
int address = rand() % CACHE_TRASH_BUFFER_SIZE;
ReadVar = CacheTrashBuffer[address];
CacheTrashBuffer[address] = ReadVar+1;
//cout<<ReadVar;
}
}
int jan_main(int argc, char* argv[])
{
// init_bez_sin();
init_bez_acos();
CacheTrashBuffer = new int[CACHE_TRASH_BUFFER_SIZE];
for (int i=0; i<CACHE_TRASH_BUFFER_SIZE; i++) {
CacheTrashBuffer[i] = rand();
}
for(int i=0; i<10; i++)
{
// float foo = i/float(47) * pi * 2;
float foo = float(i)/64.f;
float r0 = 0.0f;
float r1 = 0.0f;
float r2 = 0.0f;
unsigned long acos_cycles = 0;
unsigned long bez_cycles = 0;
unsigned long table_cycles = 0;
unsigned long acos_sum = 0;
unsigned long bez_sum = 0;
unsigned long table_sum = 0;
const int SAMPLE_COUNT = 20;
{
for (int j=0; j<SAMPLE_COUNT; j++) {
foo = WWMath::Random_Float();
acos_cycles = Get_CPU_Clock();
r0 = acos(foo);
acos_sum += Get_CPU_Clock() - acos_cycles;
trash_the_cache();
}
}
{
for (int j=0; j<SAMPLE_COUNT; j++) {
foo = WWMath::Random_Float();
bez_cycles = Get_CPU_Clock();
r1 = bez_acos(foo);
bez_sum += Get_CPU_Clock() - bez_cycles;
trash_the_cache();
}
}
{
for (int j=0; j<SAMPLE_COUNT; j++) {
foo = WWMath::Random_Float();
table_cycles = Get_CPU_Clock();
r2 = WWMath::Fast_Acos(foo);
table_sum += Get_CPU_Clock() - table_cycles;
trash_the_cache();
}
}
// cout << "x: " << setw(8) << foo << " sin(x): " << setw(8) << r0 << " bez_sin(x): " << setw(8) << r1 << " ratio: " << setw(8) << r0-r1 << endl;
// cout << "x: " << setw(8) << foo << " acos(x): " << setw(8) << r0 << " bez_acos(x): " << setw(8) << r1 << " ratio: " << setw(8) << r0/r1 << endl;
cout << "acos clocks: "<<acos_sum<<" bez clocks: "<<bez_sum<<" table clocks: "<<table_sum << endl;
}
delete CacheTrashBuffer;
return 0;
}

View File

@@ -0,0 +1,27 @@
/*
** 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/>.
*/
/*
This file contains some math functions that Jan worked on while visiting westwood
between Meltdown and Siggraph 2001.
*/
int jan_main(int argc, char* argv[]);

1125
Code/Tests/mathtest/main.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
# Microsoft Developer Studio Project File - Name="mathtest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=mathtest - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "mathtest.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "mathtest.mak" CFG="mathtest - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "mathtest - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "mathtest - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "mathtest - Win32 Profile" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tests/mathtest", ZOGAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "mathtest - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\..\library" /I "..\..\wwmath" /I "..\..\wwdebug" /I "..\..\wwlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wwmath.lib wwdebug.lib wwsaveload.lib wwlib.lib /nologo /subsystem:console /machine:I386 /out:"run/mathtest_r.exe" /libpath:"..\..\libs\release"
# SUBTRACT LINK32 /debug
!ELSEIF "$(CFG)" == "mathtest - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "..\..\library" /I "..\..\wwmath" /I "..\..\wwdebug" /I "..\..\wwlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wwmath.lib wwdebug.lib wwsaveload.lib wwlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"run/mathtest_d.exe" /libpath:"..\..\libs\Debug"
!ELSEIF "$(CFG)" == "mathtest - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "mathtest"
# PROP BASE Intermediate_Dir "mathtest"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /Zd /O2 /I "..\..\library" /I "..\..\wwmath" /I "..\..\wwdebug" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Op /Ob2 /I "..\..\library" /I "..\..\wwmath" /I "..\..\wwdebug" /I "..\..\wwlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wwmath.lib wwdebug.lib /nologo /subsystem:console /debug /machine:I386 /out:"run/mathtest_r.exe" /libpath:"..\..\libs\Release"
# ADD LINK32 winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib wwmath.lib wwdebug.lib wwsaveload.lib wwlib.lib /nologo /subsystem:console /profile /debug /machine:I386 /out:"run/mathtest_p.exe" /libpath:"..\..\libs\Profile"
!ENDIF
# Begin Target
# Name "mathtest - Win32 Release"
# Name "mathtest - Win32 Debug"
# Name "mathtest - Win32 Profile"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c"
# Begin Source File
SOURCE=.\aaboxtest.cpp
# End Source File
# Begin Source File
SOURCE=.\jan_math.cpp
# End Source File
# Begin Source File
SOURCE=.\main.cpp
# End Source File
# Begin Source File
SOURCE=.\mempooltest.cpp
# End Source File
# Begin Source File
SOURCE=.\obboxtest.cpp
# End Source File
# Begin Source File
SOURCE=.\output.cpp
# End Source File
# Begin Source File
SOURCE=.\P_timer.cpp
# End Source File
# Begin Source File
SOURCE=.\raytest.cpp
# End Source File
# Begin Source File
SOURCE=.\uarraytest.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=.\aaboxtest.h
# End Source File
# Begin Source File
SOURCE=.\jan_math.h
# End Source File
# Begin Source File
SOURCE=.\mempooltest.h
# End Source File
# Begin Source File
SOURCE=.\obboxtest.h
# End Source File
# Begin Source File
SOURCE=.\odetest.h
# End Source File
# Begin Source File
SOURCE=.\output.h
# End Source File
# Begin Source File
SOURCE=.\P_timer.h
# End Source File
# Begin Source File
SOURCE=.\raytest.h
# End Source File
# Begin Source File
SOURCE=.\uarraytest.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,96 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/mempooltest.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 7/29/99 6:01p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "mempool.h"
#include <stdio.h>
class B : public AutoPoolClass<B,5>
{
public:
// B(void) : AutoPoolClass<B,5>() { /*x = 2; y = 3;*/ }
int x;
int y;
};
class D
{
public:
D(void);
~D(void);
char * ptr;
int x;
};
D::D(void)
{
ptr = new char[500];
x = 7;
}
D::~D(void)
{
delete[] ptr;
x = 2;
}
DEFINE_AUTO_POOL(B,5);
ObjectPoolClass<D,5> DAllocator;
void test_mempool(void)
{
// allocate and delete a single 'B'
B * test0 = new B;
delete test0;
// allocate and delete a single 'D' make sure constructor
// and destructor are called.
D * test1 = DAllocator.Allocate_Object();
DAllocator.Free_Object(test1);
#define NUM_OBJECTS 6
B * Test[ NUM_OBJECTS ];
int i;
for ( i = 0; i < NUM_OBJECTS; i++ ) Test[i] = new B;
for ( i = 0; i < NUM_OBJECTS; i++ ) printf( "%d) %p\n", i, Test[i] );
for ( i = 0; i < NUM_OBJECTS; i++ ) delete Test[i];
for ( i = 0; i < NUM_OBJECTS; i++ ) Test[i] = new B;
for ( i = 0; i < NUM_OBJECTS; i++ ) printf( "%d) %p\n", i, Test[i] );
for ( i = 0; i < NUM_OBJECTS; i++ ) delete Test[i];
}

View 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/mempooltest.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 7/29/99 6:03p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef MEMPOOLTEST_H
#define MEMPOOLTEST_H
void test_mempool(void);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
/*
** 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/Tests/mathtest/obboxtest.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 4/02/99 2:28p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef OBBOXTEST_H
#define OBBOXTEST_H
void Test_OBBoxes(void);
#endif

View 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/>.
*/
/***********************************************************************************************
*** 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 Test Program *
* *
* $Archive:: /Commando/Code/Tests/mathtest/odetest.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 6/29/99 11:29a $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ODETEST_H
#define ODETEST_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef VECTOR3_H
#include "vector3.h"
#endif
#ifndef ODE_H
#include "ode.h"
#endif
class ODETestClass : public ODESystemClass
{
public:
ODETestClass(void) : Point(1.0,0.0,0.0), AngVel(0.5) { }
Vector3 Point;
double AngVel;
virtual void Get_State(StateVectorClass & set_state)
{
set_state.Add(Point.X);
set_state.Add(Point.Y);
set_state.Add(Point.Z);
}
virtual int Set_State(const StateVectorClass & new_state,int start_index)
{
Point.X = new_state[start_index++];
Point.Y = new_state[start_index++];
Point.Z = new_state[start_index++];
return start_index;
}
virtual int Compute_Derivatives(float t,StateVectorClass * test_state,StateVectorClass * set_derivs,int index)
{
if (test_state != NULL) {
Set_State(*test_state,index);
}
Vector3 Vel;
Vector3::Cross_Product(Vector3(0,0,AngVel) , Point , &Vel);
(*set_derivs)[index++] = Vel[0];
(*set_derivs)[index++] = Vel[1];
(*set_derivs)[index++] = Vel[2];
return index;
}
};
#endif /*ODETEST_H*/

View File

@@ -0,0 +1,65 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/output.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/02/98 1:58p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "stdio.h"
#include "stdarg.h"
void Print(const char * format,...)
{
va_list va;
va_start(va, format);
vprintf(format, va);
va_end(va);
}
void Print_Title(const char * title)
{
Print("\n");
Print("-------------------------------------------------------------------\n");
Print("%s\n",title);
Print("-------------------------------------------------------------------\n");
}
void Pass_Message(int num)
{
Print("test %d passed.\n",num);
}
void Fail_Message(int num)
{
Print("*** test %d failed! ***\n",num);
}

View File

@@ -0,0 +1,44 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/output.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/02/98 1:52p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void Print(const char * format,...);
void Print_Title(const char * title);
void Pass_Message(int test_index);
void Fail_Message(int test_index);
#define CHECK(index,expr) if (expr) { Pass_Message(index); } else { Fail_Message(index); }

View File

@@ -0,0 +1,458 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/raytest.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/17/00 9:34a $*
* *
* $Revision:: 10 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "raytest.h"
#include "output.h"
#include "wwmath.h"
#include "tri.h"
#include "vector3.h"
#include "lineseg.h"
#include "aabox.h"
#include "obbox.h"
#include "colmath.h"
#include "p_timer.h"
#include <stdio.h>
void line_box_test(const LineSegClass & line,const OBBoxClass & box,CastResultStruct * res);
/************************************************************************************************
**
** Ray - Triangle Test Cases
**
************************************************************************************************/
class RayTriTestClass
{
public:
Vector3 P0;
Vector3 P1;
Vector3 V0;
Vector3 V1;
Vector3 V2;
Vector3 N;
float Fraction;
bool StartBad;
LineSegClass LineSeg;
TriClass Tri;
RayTriTestClass
(
const Vector3 p0, // p0 of ray
const Vector3 p1, // p1 of ray
const Vector3 v0, // v0 of triangle
const Vector3 v1, // v1 of triangle
const Vector3 v2, // v2 of triangle
float frac, // expected fraction
bool sol // expected start solid
) :
P0(p0),P1(p1),V0(v0),V1(v1),V2(v2),Fraction(frac),StartBad(sol),LineSeg(P0,P1)
{
Tri.V[0] = &V0;
Tri.V[1] = &V1;
Tri.V[2] = &V2;
Tri.N = & N;
Tri.Compute_Normal();
}
};
RayTriTestClass RayTriTestCases[] =
{
RayTriTestClass
(
Vector3(0,0,0),
Vector3(1,0,0),
Vector3(1,1,1),
Vector3(1,-1,1),
Vector3(1,0,-1),
1.0,
false
),
RayTriTestClass // ray going down +x, hitting a triangle at x=0.75
(
Vector3(0,0,0),
Vector3(1,0,0),
Vector3(0.5,1,1),
Vector3(1,-1,1),
Vector3(0.75,0,-1),
0.75,
false
),
RayTriTestClass // ray going down the -z axis hitting an x-y triangle
(
Vector3(0,0,5), // ray start
Vector3(0,0,-5), // ray end
Vector3(0,1,0), // p0
Vector3(-1,-1,0), // p1
Vector3(1,-1,0), // p2
0.5,
false
),
RayTriTestClass // ray going down the -z axis, hitting back of an x-y triangle
(
Vector3(0,0,5), // ray start
Vector3(0,0,-5), // ray end
Vector3(0,1,0), // p0
Vector3(1,-1,0), // p1
Vector3(-1,-1,0), // p2
0.5,
false
),
RayTriTestClass // ray going down the +x axis, hitting a y-z triangle
(
Vector3(0,0,0), // ray start
Vector3(5,0,0), // ray end
Vector3(2,0,1), // p0
Vector3(2,1,-1), // p1
Vector3(2,-1,-1), // p2
2.0f / 5.0f,
false
),
RayTriTestClass // ray going down the -z axis, hitting vertex 2 of the triangle
(
Vector3(0,0,5), // ray start
Vector3(0,0,-5), // ray end
Vector3(0,1,0), // p0
Vector3(0,0,0), // p1
Vector3(1,0,0), // p2
0.5f,
false
),
RayTriTestClass // ray going down the -z axis, hitting center of edge between p0 and p2
(
Vector3(0,0,5), // ray start
Vector3(0,0,-5), // ray end
Vector3(-1,1,0), // p0
Vector3(-1,-1,0), // p1
Vector3(1,-1,0), // p2
0.5f,
false
),
};
/************************************************************************************************
**
** Ray - AABox Test Cases
**
************************************************************************************************/
class RayAABoxTestClass
{
public:
Vector3 P0;
Vector3 P1;
AABoxClass Box;
float Fraction;
bool StartBad;
LineSegClass LineSeg;
TriClass Tri;
RayAABoxTestClass
(
const Vector3 p0, // p0 of ray
const Vector3 p1, // p1 of ray
const Vector3 center, // center of the box
const Vector3 extent, // extent of the box
float frac, // expected fraction
bool sol // expected start solid
) :
P0(p0),P1(p1),Box(center,extent),Fraction(frac),StartBad(sol),LineSeg(P0,P1)
{
}
};
RayAABoxTestClass RayAABoxTestCases[] =
{
RayAABoxTestClass
(
Vector3(5,0,0), // p0 of ray
Vector3(0,0,0), // p1 of ray
Vector3(0,0,0), // center of the box
Vector3(1,1,1), // extent of the box
4.0f / 5.0f, // expected fraction
false
),
RayAABoxTestClass
(
Vector3(-2,-5,0), // p0 of ray
Vector3(0,0,0), // p1 of ray
Vector3(0,0,0), // center of the box
Vector3(2,2,2), // extent of the box
3.0f / 5.0f, // expected fraction
false
),
RayAABoxTestClass
(
Vector3(-2,5,0), // p0 of ray
Vector3(0,0,0), // p1 of ray
Vector3(0,0,0), // center of the box
Vector3(10,1,1), // extent of the box
4.0f / 5.0f, // expected fraction
false
),
RayAABoxTestClass // ray just clips the corner of the box (in x-y plane)
(
Vector3(2,0,0), // p0 of ray
Vector3(0,2,0), // p1 of ray
Vector3(0,0,0), // center of the box
Vector3(1,1,1), // extent of the box
0.5f, // expected fraction
false
),
RayAABoxTestClass // ray misses box
(
Vector3(1.01f,-3,0), // p0 of ray
Vector3(1.01f,3,0), // p1 of ray
Vector3(0,0,0), // center of the box
Vector3(1,1,1), // extent of the box
1.0f, // expected fraction
false
),
};
void Test_Rays(void)
{
CastResultStruct result;
CastResultStruct result_check;
volatile unsigned cycles;
int numtests;
int i;
/*
** Test the Cast_Ray function with a bunch of ray-triangle pairs.
*/
Print_Title("Testing ray-triangle intersection.");
numtests = sizeof(RayTriTestCases)/sizeof(RayTriTestClass);
for (i=0; i<numtests; i++) {
RayTriTestClass * testcase = &(RayTriTestCases[i]);
result.Fraction = 1.0;
result.StartBad = false;
result.Normal.Set(0,0,0);
cycles = Get_CPU_Clock();
CollisionMath::Collide(testcase->LineSeg,testcase->Tri,&result);
cycles = Get_CPU_Clock() - cycles;
printf("Ray -> Tri cycles: %d\n",cycles);
CHECK(i,(fabs(testcase->Fraction - result.Fraction) < 0.001f));
}
/*
** Test the Cast_Ray function with a bunch of ray-aabox pairs.
*/
Print_Title("Testing ray-aabox intersection.");
numtests = sizeof(RayAABoxTestCases)/sizeof(RayAABoxTestClass);
for (i=0; i<numtests; i++) {
RayAABoxTestClass * testcase = &(RayAABoxTestCases[i]);
result.Fraction = 1.0;
result.StartBad = false;
result.Normal.Set(0,0,0);
cycles = Get_CPU_Clock();
CollisionMath::Collide(testcase->LineSeg,testcase->Box,&result);
cycles = Get_CPU_Clock() - cycles;
printf("Ray -> AABox cycles: %d\n",cycles);
CHECK(i,(fabs(testcase->Fraction - result.Fraction) < 0.001f));
}
/*
** Test the Cast_Ray function on some random oriented boxes
*/
Print_Title("Testing ray-obbox intersection.");
for (i=0; i<30; i++) {
result.Fraction = 1.0;
result.StartBad = false;
result.Normal.Set(0,0,0);
// create a random box
OBBoxClass box;
box.Init_Random(1.0f,2.75f);
// create a random line
LineSegClass line;
line.Set_Random(Vector3(-3,-3,-3),Vector3(3,3,3));
// use the ray-box test
cycles = Get_CPU_Clock();
CollisionMath::Collide(line,box,&result);
cycles = Get_CPU_Clock() - cycles;
// double-check the result
result_check.Fraction = 1.0f;
result_check.StartBad = false;
result_check.Normal.Set(0,0,0);
line_box_test(line,box,&result_check);
// print what happened
bool passed = false;
if (fabs(result_check.Fraction - result.Fraction) < 0.001f) {
passed = true;
}
printf("test %3d cycles: %6d\tfraction: %1.8f\t",i,cycles,result.Fraction);
if (passed) {
printf("passed\n");
} else if (result.StartBad) {
printf("(start inside)\n");
} else {
printf("<<failed!>>\n");
}
}
/*
** Test the Overlap_Test function on some random AABoxes
*/
int total_tests = 0;
int total_cycles = 0;
int outside_tests = 0;
int outside_cycles = 0;
int overlap_tests = 0;
int overlap_cycles = 0;
CollisionMath::OverlapType overlap;
Print_Title("Testing ray-aabox overlap.");
for (i=0; i<10000; i++) {
// create a random box
AABoxClass box;
box.Init_Random(-1.0f,1.0f,1.0f,2.0f);
// create a random line
const float DIMENSION = 5.0f;
LineSegClass line;
line.Set_Random(Vector3(-DIMENSION,-DIMENSION,-DIMENSION),Vector3(DIMENSION,DIMENSION,DIMENSION));
// use the overlap_test
cycles = Get_CPU_Clock();
overlap = CollisionMath::Overlap_Test(box,line);
cycles = Get_CPU_Clock() - cycles;
// print what happened
printf("test %3d cycles: %6d\tfraction: %1.8f\t",i,cycles,result.Fraction);
if (overlap == CollisionMath::OUTSIDE) {
printf("outside\n");
} else if (overlap == CollisionMath::INSIDE) {
printf("inside\n");
} else {
printf("overlapped\n");
}
// stats
total_tests++;
total_cycles += cycles;
if (overlap == CollisionMath::OUTSIDE) {
outside_tests++;
outside_cycles += cycles;
} else {
overlap_tests++;
overlap_cycles += cycles;
}
}
printf("Total Tests: %d\n",total_tests);
printf("Average Cycles: %f\n",(float)total_cycles / (float)total_tests);
printf("Outside Tests: %d\n",outside_tests);
printf("Average Outside Cycles: %f\n",(float)outside_cycles / (float)outside_tests);
printf("Overlap Tests: %d\n",overlap_tests);
printf("Average Overlap Cycles: %f\n",(float)overlap_cycles / (float)overlap_tests);
}
void line_box_test(const LineSegClass & line,const OBBoxClass & box,CastResultStruct * res)
{
Vector3 point[8];
point[0] = box.Center + box.Basis * Vector3( box.Extent.X, box.Extent.Y, box.Extent.Z);
point[1] = box.Center + box.Basis * Vector3(-box.Extent.X, box.Extent.Y, box.Extent.Z);
point[2] = box.Center + box.Basis * Vector3(-box.Extent.X,-box.Extent.Y, box.Extent.Z);
point[3] = box.Center + box.Basis * Vector3( box.Extent.X,-box.Extent.Y, box.Extent.Z);
point[4] = box.Center + box.Basis * Vector3( box.Extent.X, box.Extent.Y,-box.Extent.Z);
point[5] = box.Center + box.Basis * Vector3(-box.Extent.X, box.Extent.Y,-box.Extent.Z);
point[6] = box.Center + box.Basis * Vector3(-box.Extent.X,-box.Extent.Y,-box.Extent.Z);
point[7] = box.Center + box.Basis * Vector3( box.Extent.X,-box.Extent.Y,-box.Extent.Z);
static int triverts[12][3] =
{
{ 0,1,2 },
{ 0,2,3 },
{ 4,5,1 },
{ 4,1,0 },
{ 1,5,6 },
{ 1,6,2 },
{ 3,2,6 },
{ 3,6,7 },
{ 4,0,3 },
{ 4,3,7 },
{ 4,7,6 },
{ 4,6,5 }
};
// first, check if ray starts inside box?
// now, check for collision with each triangle
for (int i=0; i<12; i++) {
TriClass tri;
Vector3 normal;
tri.V[0] = &point[triverts[i][0]];
tri.V[1] = &point[triverts[i][1]];
tri.V[2] = &point[triverts[i][2]];
tri.N = &normal;
tri.Compute_Normal();
CollisionMath::Collide(line,tri,res);
}
}

View File

@@ -0,0 +1,45 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/raytest.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 2/23/98 11:58a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef RAYTEST_H
#define RAYTEST_H
void Test_Rays(void);
#endif

View File

@@ -0,0 +1,105 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/uarraytest.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/17/00 9:08a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "uarraytest.h"
#include "output.h"
#include "vector3.h"
#include "uarray.h"
Vector3 InputVectors[] =
{
Vector3(0,0,0),
Vector3(1,0,0),
Vector3(1,0,0),
Vector3(1,0,0),
Vector3(1,0,0),
Vector3(1,0,0),
Vector3(5.4f,2.3f,4.5f),
Vector3(0,0,0),
Vector3(5.4f,2.3f,4.5f),
};
class VectorHasherClass : public HashCalculatorClass<Vector3>
{
public:
virtual bool Items_Match(const Vector3 & a, const Vector3 & b)
{
// looking for an exact match for normals...
return ((a.X == b.X) && (a.Y == b.Y) && (a.Z == b.Z));
}
virtual void Compute_Hash(const Vector3 & item)
{
HashVal = (int)(item.X*12345.6f + item.Y*1714.38484f + item.Z*27561.3f)&1023;
}
virtual int Num_Hash_Bits(void)
{
return 12; // 12bit hash value.
}
virtual int Num_Hash_Values(void)
{
return 1; // only one hash value for normals, require *exact* match
}
virtual int Get_Hash_Value(int index)
{
return HashVal;
}
private:
int HashVal;
};
void Test_Uarray(void)
{
VectorHasherClass vectorhasher;
UniqueArrayClass<Vector3> UniqueVectors(4,4,&vectorhasher);
int num_input_vectors = sizeof(InputVectors) / sizeof(Vector3);
int add_index;
for (int vi=0; vi<num_input_vectors; vi++) {
add_index = UniqueVectors.Add(InputVectors[vi]);
}
}

View File

@@ -0,0 +1,43 @@
/*
** 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 : MathTest *
* *
* $Archive:: /Commando/Code/Tests/mathtest/uarraytest.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/27/98 9:42a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef UARRAYTEST_H
#define UARRAYTEST_H
void Test_Uarray(void);
#endif