| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024 |
- /*
- ** 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/gridcull.cpp $*
- * *
- * Author:: Greg Hjelstrom *
- * *
- * $Modtime:: 4/27/00 7:00p $*
- * *
- * $Revision:: 18 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * GridCullSystemClass::GridCullSystemClass -- Constructor *
- * GridCullSystemClass::~GridCullSystemClass -- Destructor *
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given point *
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given AABox *
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given OBBox *
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given Frustum *
- * GridCullSystemClass::Re_Partition -- re-compute grid parameters for the given volume *
- * GridCullSystemClass::Collect_And_Unlink_All -- collects all objects and removes them from *
- * GridCullSystemClass::Update_Culling -- updates an objects position in the grid *
- * GridCullSystemClass::Load -- load function *
- * GridCullSystemClass::Save -- Save function *
- * GridCullSystemClass::Reset_Statistics -- reset debugging stats *
- * GridCullSystemClass::Get_Statistics -- returns reference to the statistics structure *
- * GridCullSystemClass::Add_Object_Internal -- links an object into the system *
- * GridCullSystemClass::Remove_Object_Internal -- unlinks an object from the system *
- * GridCullSystemClass::link_object -- figures out which cell the object is in and links it *
- * GridCullSystemClass::unlink_object -- unlinks the object from the cell it is in *
- * GridCullSystemClass::link_object_to_list -- grid list link function *
- * GridCullSystemClass::unlink_object_from_list -- grid list unlink function *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "gridcull.h"
- #include "chunkio.h"
- #include "iostruct.h"
- #include "colmath.h"
- #include "colmathinlines.h"
- /*
- ** Declare the pool for GridLinks
- */
- DEFINE_AUTO_POOL(GridLinkClass,256);
- /*
- ** Current version of the file format
- */
- const uint32 GRID_CURRENT_VERSION = 0x00010000;
- /*
- ** Chunk Id's used by the aabtree code to save itself into a file
- */
- enum
- {
- GRID_CHUNK_VERSION = 0x00000001, // version wrapper, contains 32bit version #
- GRID_CHUNK_PARAMETERS = 0x00000100, // parameters for the grid cull system
- };
- /*
- ** IOGridParametersStruct
- ** Data structure for the contents of a node in the AAB-Tree
- */
- struct IOGridParametersStruct
- {
- IOVector3Struct MinCellSize;
- IOVector3Struct Origin;
- IOVector3Struct CellDim;
- uint32 CellCount[3];
- float32 MaxObjExtent;
- };
- /*************************************************************************
- **
- ** Utility functions for walking the object list in an AABTree Node
- **
- *************************************************************************/
- static inline CullableClass * get_next_object(CullableClass * obj)
- {
- return ((GridLinkClass *)obj->Get_Cull_Link())->Next;
- }
- /*************************************************************************
- **
- ** GridLinkClass Implementation
- **
- *************************************************************************/
- GridLinkClass::GridLinkClass(GridCullSystemClass * system) :
- CullLinkClass(system),
- GridAddress(-1),
- Prev(NULL),
- Next(NULL)
- {
- }
- GridLinkClass::~GridLinkClass(void)
- {
- }
- /*************************************************************************
- **
- ** GridCullSystemClass Implementation
- **
- *************************************************************************/
- /***********************************************************************************************
- * GridCullSystemClass::GridCullSystemClass -- Constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- GridCullSystemClass::GridCullSystemClass(void) :
- MinCellSize(10,10,10),
- MaxObjExtent(15),
- Origin(-100,-100,-100),
- CellDim(10,10,10),
- Cells(NULL),
- NoGridList(NULL),
- ObjCount(0),
- TerminationCellCount(TERMINATION_CELL_COUNT)
- {
- CellCount[0] = CellCount[1] = CellCount[2] = 0;
- Re_Partition(Vector3(-100,-100,-100),Vector3(100,100,100),15);
- Reset_Statistics();
- }
- /***********************************************************************************************
- * GridCullSystemClass::~GridCullSystemClass -- Destructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- GridCullSystemClass::~GridCullSystemClass(void)
- {
- if (Cells != NULL) {
- delete Cells;
- Cells = NULL;
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given point *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Collect_Objects(const Vector3 & point)
- {
- /*
- ** Collect the objects in the grid
- */
- VolumeStruct vol;
- init_volume(point,point,&vol);
- if (!vol.Is_Empty()) {
- int delta_x = vol.Max[0] - vol.Min[0];
- int i,j,k;
- int address = map_indices_to_address(vol.Min[0],vol.Min[1],vol.Min[2]);
-
- for (k=vol.Min[2]; k<vol.Max[2]; k++) {
- for (j=vol.Min[1]; j<vol.Max[1]; j++) {
- for (i=vol.Min[0]; i<vol.Max[0]; i++) {
- GRIDCULL_NODE_TRIVIALLY_ACCEPTED;
- collect_objects_in_leaf(point,Cells[address]);
- address++;
- }
- address -= delta_x;
- address += CellCount[0];
- }
- address = map_indices_to_address(vol.Min[0],vol.Min[1],k+1);
- }
- }
- /*
- ** Collect the objects in the no-grid-list
- */
- collect_objects_in_leaf(point,NoGridList);
- }
- /***********************************************************************************************
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given AABox *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Collect_Objects(const AABoxClass & box)
- {
- /*
- ** Collect the objects in the grid
- */
- VolumeStruct vol;
- init_volume(box,&vol);
- if (!vol.Is_Empty()) {
- int delta_x = vol.Max[0] - vol.Min[0];
- int i,j,k;
- int address = map_indices_to_address(vol.Min[0],vol.Min[1],vol.Min[2]);
-
- for (k=vol.Min[2]; k<vol.Max[2]; k++) {
- for (j=vol.Min[1]; j<vol.Max[1]; j++) {
- for (i=vol.Min[0]; i<vol.Max[0]; i++) {
- GRIDCULL_NODE_TRIVIALLY_ACCEPTED;
- collect_objects_in_leaf(box,Cells[address]);
- address++;
- }
- address -= delta_x;
- address += CellCount[0];
- }
- address = map_indices_to_address(vol.Min[0],vol.Min[1],k+1);
- }
- }
-
- /*
- ** Collect the objects in the no-grid-list
- */
- collect_objects_in_leaf(box,NoGridList);
- }
- /***********************************************************************************************
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given OBBox *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Collect_Objects(const OBBoxClass & box)
- {
- /*
- ** Collect the objects in the grid
- */
- VolumeStruct vol;
- init_volume(box,&vol);
- if (!vol.Is_Empty()) {
- int delta_x = vol.Max[0] - vol.Min[0];
- int i,j,k;
- int address = map_indices_to_address(vol.Min[0],vol.Min[1],vol.Min[2]);
- for (k=vol.Min[2]; k<vol.Max[2]; k++) {
- for (j=vol.Min[1]; j<vol.Max[1]; j++) {
- for (i=vol.Min[0]; i<vol.Max[0]; i++) {
- GRIDCULL_NODE_TRIVIALLY_ACCEPTED;
- collect_objects_in_leaf(box,Cells[address]);
- address++;
- }
- address -= delta_x;
- address += CellCount[0];
- }
- address = map_indices_to_address(vol.Min[0],vol.Min[1],k+1);
- }
- }
- /*
- ** Collect the objects in the no-grid-list
- */
- collect_objects_in_leaf(box,NoGridList);
- }
- /***********************************************************************************************
- * GridCullSystemClass::Collect_Objects -- Collect all objects touching the given Frustum *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Collect_Objects(const FrustumClass & frustum)
- {
- /*
- ** Collect the objects in the grid
- */
- VolumeStruct vol;
- init_volume(frustum,&vol);
- if (!vol.Is_Empty()) {
- int delta_x = vol.Max[0] - vol.Min[0];
- int i,j,k;
- int address = map_indices_to_address(vol.Min[0],vol.Min[1],vol.Min[2]);
-
- for (k=vol.Min[2]; k<vol.Max[2]; k++) {
- for (j=vol.Min[1]; j<vol.Max[1]; j++) {
- for (i=vol.Min[0]; i<vol.Max[0]; i++) {
- GRIDCULL_NODE_TRIVIALLY_ACCEPTED;
- collect_objects_in_leaf(frustum,Cells[address]);
- address++;
- }
- address -= delta_x;
- address += CellCount[0];
- }
- address = map_indices_to_address(vol.Min[0],vol.Min[1],k+1);
- }
- }
-
- /*
- ** Collect the objects in the no-grid-list
- */
- collect_objects_in_leaf(frustum,NoGridList);
- }
- /***********************************************************************************************
- * GridCullSystemClass::Re_Partition -- re-compute grid parameters for the given volume *
- * *
- * *
- * *
- * *
- * INPUT: *
- * input_min - 'min' corner of the world *
- * input_max - 'max' corner of the world *
- * objdim - largest object dimesion that will be allowed in the grid *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Re_Partition(const Vector3 & input_min,const Vector3 & input_max,float objdim)
- {
- /*
- ** grab all objects into the collection list and unlink them from the grid
- */
- Reset_Collection();
- Collect_And_Unlink_All();
- /*
- ** Do a sanity check on the input parameters
- */
- Vector3 min = input_min;
- Vector3 max = input_max;
- if (max.X - min.X < 1.0f) {
- max.X += MinCellSize.X;
- min.X -= MinCellSize.X;
- }
- if (max.Y - min.Y < 1.0f) {
- max.Y += MinCellSize.Y;
- min.Y -= MinCellSize.Y;
- }
- if (max.Z - min.Z < 1.0f) {
- max.Z += MinCellSize.Z;
- min.Z -= MinCellSize.Z;
- }
- /*
- ** Compute the grid parameters
- */
- Origin = min;
- Vector3 world_dim = max - min;
- MaxObjExtent = objdim;
- WWASSERT(world_dim.X > 0.0f);
- WWASSERT(world_dim.Y > 0.0f);
- WWASSERT(world_dim.Z > 0.0f);
- /*
- ** how many cells should we use on each dimension?
- */
- CellCount[0] = CellCount[1] = CellCount[2] = 1;
- CellDim = world_dim;
- bool done = false;
- while (!done) {
- /*
- ** find biggest dimension
- */
- int bigdim = 0;
- if (CellDim[1]/MinCellSize[1] > CellDim[bigdim]/MinCellSize[bigdim]) bigdim = 1;
- if (CellDim[2]/MinCellSize[2] > CellDim[bigdim]/MinCellSize[bigdim]) bigdim = 2;
- /*
- ** split dimension in two if possible
- */
- if (CellDim[bigdim] >= 2.0f * MinCellSize[bigdim]) {
- CellDim[bigdim] /= 2.0f;
- CellCount[bigdim] *= 2;
- }
- /*
- ** check termination conditions
- */
- if (total_cell_count() >= TerminationCellCount) {
- done = true;
- }
- if ( (CellDim[0] < 2.0*MinCellSize[0]) &&
- (CellDim[1] < 2.0*MinCellSize[1]) &&
- (CellDim[2] < 2.0*MinCellSize[2]) ) {
- done = true;
- }
- }
- OOCellDim.X = 1.0f / CellDim.X;
- OOCellDim.Y = 1.0f / CellDim.Y;
- OOCellDim.Z = 1.0f / CellDim.Z;
- if (Cells != NULL) {
- delete[] Cells;
- }
- Cells = new CullableClass * [total_cell_count()];
- memset(&(Cells[0]),0,total_cell_count() * sizeof(CullableClass *));
- /*
- ** iterate the collection list and re-insert all objects into the grid
- */
- CullableClass * obj;
- for ( obj = Get_First_Collected_Object_Internal();
- obj != NULL;
- obj = Get_Next_Collected_Object_Internal(obj))
- {
- link_object(obj);
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::Collect_And_Unlink_All -- collects all objects and removes them from t *
- * *
- * This is used when re-partitioning the grid. All objects are pulled out and linked into *
- * the collection list. When the grid has been re-initialized, the objects are put back in. *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Collect_And_Unlink_All(void)
- {
- Reset_Collection();
- /*
- ** pull all objects out of the grid
- */
- for (int k=0; k<CellCount[2]; k++) {
- for (int j=0; j<CellCount[1]; j++) {
- for (int i=0; i<CellCount[0]; i++) {
- /*
- ** collect and unlink all objects in cell(i,j,k)
- */
- CullableClass * obj = Cells[map_indices_to_address(i,j,k)];
- while (obj) {
- CullableClass * nextobj = get_next_object(obj);
-
- unlink_object(obj);
- Add_To_Collection(obj);
- obj = nextobj;
- }
- }
- }
- }
- /*
- ** pull all objects out of the "no-grid" list
- */
- CullableClass * obj = NoGridList;
- while (obj) {
- CullableClass * nextobj = get_next_object(obj);
-
- unlink_object(obj);
- Add_To_Collection(obj);
- obj = nextobj;
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::Update_Culling -- updates an objects position in the grid *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Update_Culling(CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
-
- int address;
- GridLinkClass * link = (GridLinkClass *)obj->Get_Cull_Link();
- map_point_to_address(obj->Get_Cull_Box().Center,address);
-
- if (address != link->GridAddress) {
- unlink_object(obj);
- link_object(obj,address);
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::Load -- load function *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Load(ChunkLoadClass & cload)
- {
- /*
- ** read the version chunk
- */
- uint32 version;
- cload.Open_Chunk();
- WWASSERT(cload.Cur_Chunk_ID() == GRID_CHUNK_VERSION);
- cload.Read(&version,sizeof(version));
- cload.Close_Chunk();
- /*
- ** read the parameters chunk
- */
- IOGridParametersStruct params;
- memset(¶ms,0,sizeof(params));
- cload.Open_Chunk();
- WWASSERT(cload.Cur_Chunk_ID() == GRID_CHUNK_PARAMETERS);
- cload.Read(¶ms,sizeof(params));
- cload.Close_Chunk();
- /*
- ** unlink all objects
- */
- Collect_And_Unlink_All();
- /*
- ** partition the grid according to the loaded parameters
- */
- CellCount[0] = params.CellCount[0];
- CellCount[1] = params.CellCount[1];
- CellCount[2] = params.CellCount[2];
- CellDim.X = params.CellDim.X;
- CellDim.Y = params.CellDim.Y;
- CellDim.Z = params.CellDim.Z;
- MaxObjExtent = params.MaxObjExtent;
- MinCellSize.X = params.MinCellSize.X;
- MinCellSize.Y = params.MinCellSize.Y;
- MinCellSize.Z = params.MinCellSize.Z;
- Origin.X = params.Origin.X;
- Origin.Y = params.Origin.Y;
- Origin.Z = params.Origin.Z;
- OOCellDim.X = 1.0f / CellDim.X;
- OOCellDim.Y = 1.0f / CellDim.Y;
- OOCellDim.Z = 1.0f / CellDim.Z;
- if (Cells != NULL) {
- delete [] Cells;
- Cells = NULL;
- }
- Cells = new CullableClass * [total_cell_count()];
- memset(&(Cells[0]),0,total_cell_count() * sizeof(CullableClass *));
- /*
- ** re-link the objects in
- */
- CullableClass * obj;
- for ( obj = Get_First_Collected_Object_Internal();
- obj != NULL;
- obj = Get_Next_Collected_Object_Internal(obj))
- {
- link_object(obj);
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::Save -- Save function *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Save(ChunkSaveClass & csave)
- {
- /*
- ** write the version chunk
- */
- uint32 version = GRID_CURRENT_VERSION;
- csave.Begin_Chunk(GRID_CHUNK_VERSION);
- csave.Write(&version,sizeof(version));
- csave.End_Chunk();
- /*
- ** write the grid parameters
- */
- IOGridParametersStruct params;
- memset(¶ms,0,sizeof(params));
- params.CellCount[0] = CellCount[0];
- params.CellCount[1] = CellCount[1];
- params.CellCount[2] = CellCount[2];
- params.CellDim.X = CellDim.X;
- params.CellDim.Y = CellDim.Y;
- params.CellDim.Z = CellDim.Z;
- params.MaxObjExtent = MaxObjExtent;
- params.MinCellSize.X = MinCellSize.X;
- params.MinCellSize.Y = MinCellSize.Y;
- params.MinCellSize.Z = MinCellSize.Z;
- params.Origin.X = Origin.X;
- params.Origin.Y = Origin.Y;
- params.Origin.Z = Origin.Z;
- csave.Begin_Chunk(GRID_CHUNK_PARAMETERS);
- csave.Write(¶ms,sizeof(params));
- csave.End_Chunk();
- }
- /***********************************************************************************************
- * GridCullSystemClass::Reset_Statistics -- reset debugging stats *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Reset_Statistics(void)
- {
- // number of (virtual) nodes = 2n-1
- Stats.NodeCount = 2 * (CellCount[0] * CellCount[1] * CellCount[2]) - 1;
- Stats.NodesAccepted = 0;
- Stats.NodesTriviallyAccepted = 0;
- Stats.NodesRejected = 0;
- }
- /***********************************************************************************************
- * GridCullSystemClass::Get_Statistics -- returns reference to the statistics structure *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- const GridCullSystemClass::StatsStruct & GridCullSystemClass::Get_Statistics(void)
- {
- return Stats;
- }
- /***********************************************************************************************
- * GridCullSystemClass::Add_Object_Internal -- links an object into the system *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Add_Object_Internal(CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == NULL);
- GridLinkClass * link = new GridLinkClass(this);
- obj->Set_Cull_Link(link);
- link_object(obj);
-
- ObjCount++;
- obj->Add_Ref();
- }
- /***********************************************************************************************
- * GridCullSystemClass::Remove_Object_Internal -- unlinks an object from the system *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::Remove_Object_Internal(CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
- GridLinkClass * link = (GridLinkClass *)obj->Get_Cull_Link();
- unlink_object(obj);
- link->Set_Culling_System(NULL);
- delete link;
- obj->Set_Cull_Link(NULL);
- ObjCount--;
- obj->Release_Ref();
- }
- /***********************************************************************************************
- * GridCullSystemClass::link_object -- figures out which cell the object is in and links it *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::link_object(CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
- int address;
- map_point_to_address(obj->Get_Cull_Box().Center,address);
- link_object(obj,address);
- }
- void GridCullSystemClass::link_object(CullableClass * obj,int address)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
- GridLinkClass * link = (GridLinkClass *)obj->Get_Cull_Link();
- WWASSERT(link != NULL);
- /*
- ** if obj cannot be inserted into the grid, add it to the NoGridList
- ** otherwise, insert it into the cell
- */
- const AABoxClass & box = obj->Get_Cull_Box();
- if (
- (box.Extent.X > MaxObjExtent) ||
- (box.Extent.Y > MaxObjExtent) ||
- (box.Extent.Z > MaxObjExtent) ||
- (address == UNGRIDDED_ADDRESS)
- )
- {
- link->GridAddress = UNGRIDDED_ADDRESS;
- link_object_to_list(&NoGridList,obj);
- } else {
- link->GridAddress = address;
- link_object_to_list(&(Cells[address]),obj);
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::unlink_object -- unlinks the object from the cell it is in *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::unlink_object(CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
- GridLinkClass * link = (GridLinkClass *)obj->Get_Cull_Link();
- if (link->GridAddress == UNGRIDDED_ADDRESS) {
- unlink_object_from_list(&NoGridList,obj);
- } else {
- unlink_object_from_list(&(Cells[link->GridAddress]),obj);
- }
- }
- /***********************************************************************************************
- * GridCullSystemClass::link_object_to_list -- grid list link function *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::link_object_to_list(CullableClass ** head,CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
- GridLinkClass * link = (GridLinkClass *)obj->Get_Cull_Link();
- /*
- ** Insert this object as the new head of the list.
- */
- link->Next = *head;
- link->Prev = NULL;
- if (link->Next != NULL) {
- GridLinkClass * next_link = (GridLinkClass *)link->Next->Get_Cull_Link();
- WWASSERT(next_link != NULL);
- next_link->Prev = obj;
- }
- *head = obj;
- }
- /***********************************************************************************************
- * GridCullSystemClass::unlink_object_from_list -- grid list unlink function *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 4/27/2000 gth : Created. *
- *=============================================================================================*/
- void GridCullSystemClass::unlink_object_from_list(CullableClass ** head,CullableClass * obj)
- {
- WWASSERT(obj);
- WWASSERT(obj->Get_Culling_System() == this);
- GridLinkClass * link = (GridLinkClass *)obj->Get_Cull_Link();
- /*
- ** check to see that the object is actually in this list
- */
- #ifdef WWDEBUG
- CullableClass * tmp = *head;
- bool found = false;
- while (tmp && !found) {
- if (tmp == obj) found = true;
- tmp = ((GridLinkClass *)(tmp->Get_Cull_Link()))->Next;
- }
- WWASSERT(found);
- #endif
- /*
- ** If we were the head of the list, make the head point to the next object
- */
- if (obj == *head) {
- *head = link->Next;
- }
-
- /*
- ** Link the object previous to us to our next...
- */
- if (link->Prev) {
- GridLinkClass * prev_link = (GridLinkClass *)link->Prev->Get_Cull_Link();
- prev_link->Next = link->Next;
- }
- /*
- ** Link the objects after us to our previous...
- */
- if (link->Next) {
- GridLinkClass * next_link = (GridLinkClass *)link->Next->Get_Cull_Link();
- next_link->Prev = link->Prev;
- }
- link->Prev = NULL;
- link->Next = NULL;
- }
- /*************************************************************************
- **
- ** GridCullSystem Internal Leaf-iterating collection functions
- **
- *************************************************************************/
- void GridCullSystemClass::collect_objects_in_leaf(const Vector3 & point,CullableClass * head)
- {
- if (head != NULL) {
- GridListIterator it(head);
- for (;!it.Is_Done(); it.Next()) {
- CullableClass * obj = it.Peek_Obj();
- if (obj->Get_Cull_Box ().Contains (point) == true) {
- Add_To_Collection(obj);
- }
- }
- }
- }
- void GridCullSystemClass::collect_objects_in_leaf(const AABoxClass & box,CullableClass * head)
- {
- if (head != NULL) {
- GridListIterator it(head);
- for (;!it.Is_Done(); it.Next()) {
- CullableClass * obj = it.Peek_Obj();
- if (CollisionMath::Overlap_Test(box,obj->Get_Cull_Box()) != CollisionMath::OUTSIDE) {
- Add_To_Collection(obj);
- }
- }
- }
- }
- void GridCullSystemClass::collect_objects_in_leaf(const OBBoxClass & obbox,CullableClass * head)
- {
- if (head != NULL) {
- GridListIterator it(head);
- for (;!it.Is_Done(); it.Next()) {
- CullableClass * obj = it.Peek_Obj();
- if (CollisionMath::Overlap_Test(obbox,obj->Get_Cull_Box()) != CollisionMath::OUTSIDE) {
- Add_To_Collection(obj);
- }
- }
- }
- }
- void GridCullSystemClass::collect_objects_in_leaf(const FrustumClass & frustum,CullableClass * head)
- {
- if (head != NULL) {
- GridListIterator it(head);
- for (;!it.Is_Done(); it.Next()) {
- CullableClass * obj = it.Peek_Obj();
- if (CollisionMath::Overlap_Test(frustum,obj->Get_Cull_Box()) != CollisionMath::OUTSIDE) {
- Add_To_Collection(obj);
- }
- }
- }
- }
|