| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /*
- ** 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 : WWPhys *
- * *
- * $Archive:: /Commando/Code/wwphys/dynamicaabtreecull.h $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 7/24/01 1:26p $*
- * *
- * $Revision:: 7 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #ifndef DYNAMICAABTREECULL_H
- #define DYNAMICAABTREECULL_H
- #include "always.h"
- #include "physaabtreecull.h"
- #include "physlist.h"
- class VisTableClass;
- class VisRenderContextClass;
- class VisOptimizationContextClass;
- class AABoxRenderObjClass;
- /**
- ** DynamicAABTreeCullClass
- ** This is a specialized AABTree which is designed to be used with dynamic objects. It
- ** contains both a uniform voxelization of the level and special "seed" boxes which
- ** are generated from a pathfind floodfill. Whenever a dynamic object moves, it is
- ** re-inserted into the smallest leaf node in the tree. So this is basically an AAB-Tree
- ** that partitions the level paying special attention to the areas that you seed
- ** it with. All nodes in the tree are assigned a visiblity id and are tracked in the
- ** vis system.
- **
- ** This AABTree also over-rides the Add_Object and Update_Culling function to behave differently.
- ** The tree is constructed with a set of boxes which cover all of the space in the level.
- ** These boxes are inflated by the MaxObjRadius parameter. When inserting objects into the
- ** tree we test their center-point against the non-inflated boxes and insert the object into
- ** the smallest leaf node that we can find.
- */
- class DynamicAABTreeCullClass : public PhysAABTreeCullClass
- {
- public:
- DynamicAABTreeCullClass(PhysicsSceneClass * pscene);
- ~DynamicAABTreeCullClass(void);
- /*
- ** DynamicAABTreeCullClass over-rides Add_Object and Update_Culling because it
- ** uses custom logic for determining which cell an object should end up in.
- */
- virtual void Add_Object(PhysClass * obj);
- virtual void Update_Culling(CullableClass * obj);
- /*
- ** Objects will request the visibility ID from this system.
- ** Note that if you pass in a pointer to your previous node_id, the lookup will be faster and this
- ** variable will be modified with the updated node id. The first time this method is called,
- ** initialize the node_id to zero.
- */
- uint32 Get_Dynamic_Object_Vis_ID(const AABoxClass & obj_bounds,int * node_id = NULL);
- /*
- ** DynamicObjCullClass adds a new re-partitioning interface to AABTreeCullSystemClass
- ** This interface allows the user to supply the grid parameters and the virtual occludees
- */
- void Re_Partition( DynamicVectorClass<AABoxClass> * virtual_occludees,
- const Vector3 & grid_min,
- const Vector3 & grid_max,
- const Vector3 & min_grid_cell_size,
- int max_grid_cell_count,
- float max_obj_radius );
- /*
- ** DynamicObjCullClass adds a new collect function which takes the pvs data
- ** into account. It also puts objects into one of two lists, separating
- ** world-space-meshes from the other objects.
- */
- void Collect_Visible_Objects( const FrustumClass & frustum,
- VisTableClass * pvs,
- RefPhysListClass & visobjlist );
- /*
- ** Debugging
- ** Render the visible leaf cells.
- ** Tree visualization, walk the tree, rendering all leaf cells of current node.
- */
- enum DisplayModeType {
- DISPLAY_NONE = 0,
- DISPLAY_ACTUAL_BOXES,
- DISPLAY_CENTERS,
- DISPLAY_OCCUPIED,
- };
-
- void Render_Visible_Cells(RenderInfoClass & rinfo,VisTableClass * pvs,DisplayModeType mode);
- void Debug_Reset_Node(void) { DebugIterator.Reset(); }
- bool Debug_Enter_Parent(void) { return DebugIterator.Enter_Parent(); }
- bool Debug_Enter_Sibling(void) { return DebugIterator.Enter_Sibling(); }
- bool Debug_Enter_Front_Child(void) { return DebugIterator.Enter_Front_Child(); }
- bool Debug_Enter_Back_Child(void) { return DebugIterator.Enter_Back_Child(); }
- /*
- ** Visibility Preprocesing. For this culling system, visibility of all of the nodes is tracked
- ** while the objects inside the culling system are ignored because they are assumed to be
- ** dynamic. For this reason, there are no occluders in the dynamic object culling system.
- */
- void Assign_Vis_IDs(void);
- void Evaluate_Non_Occluder_Visibility(VisRenderContextClass & context);
- void Prune_Redundant_Leaf_Nodes(VisOptimizationContextClass & context);
- void Merge_Vis_Object_IDs(uint32 id0,uint32 id1);
- /*
- ** Save/Load system.
- */
- virtual void Save_Static_Data(ChunkSaveClass & csave);
- virtual void Load_Static_Data(ChunkLoadClass & cload);
- protected:
- /*
- ** VisObjCollectContextClass - this object is passed into the recursive function that collects
- ** the visible objects each frame.
- */
- class VisObjCollectContextClass
- {
- public:
- VisObjCollectContextClass(const FrustumClass & frustum,VisTableClass & pvs,RefPhysListClass & visobjlist) :
- Frustum(frustum),
- PVS(pvs),
- VisObjList(visobjlist),
- PlanesPassed(0)
- {
- }
-
- const FrustumClass & Frustum;
- VisTableClass & PVS;
- RefPhysListClass & VisObjList;
- int PlanesPassed;
- };
-
- /*
- ** Internal functions
- */
- void collect_visible_objects_recursive(AABTreeNodeClass * node,VisObjCollectContextClass & context);
- void collect_visible_objects_no_hvis_recursive(AABTreeNodeClass * node,VisObjCollectContextClass & context);
- void render_visible_cells_recursive(AABTreeNodeClass * node,RenderInfoClass & rinfo,VisTableClass * pvs,DisplayModeType mode);
- void evaluate_non_occluder_visibility_recursive(AABTreeNodeClass * node,VisRenderContextClass & context);
- bool subtree_is_visible(AABTreeNodeClass * node,VisRenderContextClass & context);
- void set_tree_visibility(AABTreeNodeClass * node,VisRenderContextClass & context,bool onoff);
- int find_insertion_node(CullableClass * obj);
- void find_optimal_node(AABTreeNodeClass * node,const AABoxClass & box,int & node_index);
- void find_optimal_deflated_node(AABTreeNodeClass * node,const Vector3 & center,int & node_index);
-
- bool deflated_box_contains_point(const AABoxClass & box,const Vector3 & point);
- void prune_redundant_leaf_nodes_recursive(AABTreeNodeClass * node,VisOptimizationContextClass & context);
- void prune_child(AABTreeNodeClass * parent,AABTreeNodeClass * child,VisOptimizationContextClass & context);
- AABoxRenderObjClass * get_render_box(void);
- /*
- ** Members
- */
- float MaxObjRadius; // Object "inflation" radius used when the tree was created.
- AABoxRenderObjClass * RenderBox; // Used to render nodes when debugging
- AABTreeIterator DebugIterator; // Used to walk the tree while debugging. Render_Visible.. starts from this node
- /*
- ** Making Physics Scene a friend so that some of the more ugly vis-system interfaces
- ** can be accessed by it without exposing them to everyone else...
- */
- friend class PhysicsSceneClass;
- };
- /*
- ** Inlines
- */
- inline bool DynamicAABTreeCullClass::deflated_box_contains_point
- (
- const AABoxClass & box,
- const Vector3 & point
- )
- {
- if (WWMath::Fabs(point.X - box.Center.X) > box.Extent.X - MaxObjRadius) return false;
- if (WWMath::Fabs(point.Y - box.Center.Y) > box.Extent.Y - MaxObjRadius) return false;
- if (WWMath::Fabs(point.Z - box.Center.Z) > box.Extent.Z - MaxObjRadius) return false;
- return true;
- }
- #endif //DYNAMICAABTREECULL_H
|