mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2026-06-17 18:57:44 +02:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
224
Code/wwphys/dynamicaabtreecull.h
Normal file
224
Code/wwphys/dynamicaabtreecull.h
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
** 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
|
||||
Reference in New Issue
Block a user