mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
271
Code/wwphys/dynamicphys.cpp
Normal file
271
Code/wwphys/dynamicphys.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
** 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/dynamicphys.cpp $*
|
||||
* *
|
||||
* Original Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 3/29/02 2:49p $*
|
||||
* *
|
||||
* $Revision:: 17 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "dynamicphys.h"
|
||||
#include "chunkio.h"
|
||||
#include "pscene.h"
|
||||
#include "wwprofile.h"
|
||||
#include "physcoltest.h"
|
||||
|
||||
#if (UMBRASUPPORT)
|
||||
#include <umbra.hpp>
|
||||
#endif
|
||||
|
||||
#include "umbrasupport.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
**
|
||||
** DynamicPhysClass Implementation
|
||||
** Note that this is not a concrete class. It therefore does not have factories defined...
|
||||
**
|
||||
***********************************************************************************************/
|
||||
|
||||
const int MIN_VIS_UPDATE_TICK_DELAY = 250; // min number of milliseconds between dynamic vis id updates
|
||||
|
||||
bool DynamicPhysClass::_DisableDynamicPhysSimulation = false;
|
||||
bool DynamicPhysClass::_DisableDynamicPhysRendering = false;
|
||||
|
||||
|
||||
/*
|
||||
** Chunk ID's used by DynamicPhysClass
|
||||
*/
|
||||
enum
|
||||
{
|
||||
DYNAMICPHYS_CHUNK_PHYS = 813001100,
|
||||
};
|
||||
|
||||
|
||||
DynamicPhysClass::DynamicPhysClass(void) :
|
||||
DirtyVisObjectID(true),
|
||||
VisNodeID(0),
|
||||
VisStatusLastUpdated(0)
|
||||
{
|
||||
}
|
||||
|
||||
DynamicPhysClass::~DynamicPhysClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
void DynamicPhysClass::Init(const DynamicPhysDefClass & definition)
|
||||
{
|
||||
PhysClass::Init(definition);
|
||||
}
|
||||
|
||||
void DynamicPhysClass::Set_Model(RenderObjClass * model)
|
||||
{
|
||||
PhysClass::Set_Model(model);
|
||||
|
||||
#if (UMBRASUPPORT)
|
||||
if (model != NULL) {
|
||||
/*
|
||||
** Create a new test-model for the bounding box of this object
|
||||
*/
|
||||
AABoxClass obj_box;
|
||||
model->Get_Obj_Space_Bounding_Box(obj_box);
|
||||
|
||||
/*
|
||||
** Insert it into our Umbra object
|
||||
*/
|
||||
WWASSERT(UmbraObject);
|
||||
UmbraObject->setTestModel(UmbraSupport::Create_Box_Model(obj_box));
|
||||
UmbraObject->setCost(100000,100000,5);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DynamicPhysClass::Update_Visibility_Status(void)
|
||||
{
|
||||
/*
|
||||
** Invalidate our cached vis object ID
|
||||
*/
|
||||
DirtyVisObjectID = true;
|
||||
|
||||
/*
|
||||
** Invalidate the lighting cache. Next time this object is rendered the cache will be updated.
|
||||
*/
|
||||
Invalidate_Static_Lighting_Cache();
|
||||
}
|
||||
|
||||
int DynamicPhysClass::Get_Vis_Object_ID(void)
|
||||
{
|
||||
if (DirtyVisObjectID) {
|
||||
Internal_Update_Visibility_Status();
|
||||
}
|
||||
return VisObjectID;
|
||||
}
|
||||
|
||||
void DynamicPhysClass::Internal_Update_Visibility_Status(void)
|
||||
{
|
||||
/*
|
||||
** Don't update our VIS-ID more often than 4 times per second
|
||||
*/
|
||||
unsigned current_time=WW3D::Get_Sync_Time();
|
||||
unsigned delta = current_time - VisStatusLastUpdated;
|
||||
|
||||
if (delta < MIN_VIS_UPDATE_TICK_DELAY) return;
|
||||
VisStatusLastUpdated=current_time;
|
||||
|
||||
/*
|
||||
** Update our VIS-ID
|
||||
*/
|
||||
VisObjectID = PhysicsSceneClass::Get_Instance()->Get_Dynamic_Object_Vis_ID(Model->Get_Bounding_Box(),&VisNodeID);
|
||||
if ((int)VisObjectID >= PhysicsSceneClass::Get_Instance()->Get_Vis_Table_Size()) {
|
||||
|
||||
int size = PhysicsSceneClass::Get_Instance()->Get_Vis_Table_Size();
|
||||
// int id = PhysicsSceneClass::Get_Instance()->Get_Dynamic_Object_Vis_ID(Model->Get_Bounding_Box(),&VisNodeID);
|
||||
|
||||
WWDEBUG_SAY(("Invalid VisObjectID: %d for object: %s (max vis id = %d)\n",VisObjectID,Model->Get_Name(),size));
|
||||
VisObjectID = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Clear the dirty bit
|
||||
*/
|
||||
DirtyVisObjectID = false;
|
||||
|
||||
/*
|
||||
** Update our Umbra Object
|
||||
*/
|
||||
#if (UMBRASUPPORT)
|
||||
UmbraSupport::Update_Umbra_Object(this);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool DynamicPhysClass::Save(ChunkSaveClass &csave)
|
||||
{
|
||||
csave.Begin_Chunk(DYNAMICPHYS_CHUNK_PHYS);
|
||||
PhysClass::Save(csave);
|
||||
csave.End_Chunk();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicPhysClass::Load(ChunkLoadClass &cload)
|
||||
{
|
||||
while (cload.Open_Chunk()) {
|
||||
|
||||
switch(cload.Cur_Chunk_ID())
|
||||
{
|
||||
case DYNAMICPHYS_CHUNK_PHYS:
|
||||
PhysClass::Load(cload);
|
||||
break;
|
||||
|
||||
default:
|
||||
WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
||||
break;
|
||||
}
|
||||
|
||||
cload.Close_Chunk();
|
||||
}
|
||||
SaveLoadSystemClass::Register_Post_Load_Callback(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicPhysClass::On_Post_Load(void)
|
||||
{
|
||||
PhysClass::On_Post_Load();
|
||||
|
||||
// update cached vis object id, vis node id, and sunlight status...
|
||||
Update_Cull_Box();
|
||||
Update_Visibility_Status();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************************
|
||||
**
|
||||
** DynamicPhysDefClass Implementation
|
||||
** This holds the description for a DynamicPhysClass. Again, this class isn't concrete
|
||||
** so it doesn't have factories...
|
||||
**
|
||||
***********************************************************************************************/
|
||||
|
||||
enum
|
||||
{
|
||||
DYNAMICPHYSDEF_CHUNK_PHYSDEF = 813001104, // parent class data.
|
||||
};
|
||||
|
||||
|
||||
DynamicPhysDefClass::DynamicPhysDefClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool DynamicPhysDefClass::Is_Valid_Config(StringClass &message)
|
||||
{
|
||||
return PhysDefClass::Is_Valid_Config(message);
|
||||
}
|
||||
|
||||
bool DynamicPhysDefClass::Is_Type(const char * type_name)
|
||||
{
|
||||
if (stricmp(type_name,DynamicPhysDefClass::Get_Type_Name()) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return PhysDefClass::Is_Type(type_name);
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicPhysDefClass::Save(ChunkSaveClass &csave)
|
||||
{
|
||||
csave.Begin_Chunk(DYNAMICPHYSDEF_CHUNK_PHYSDEF);
|
||||
PhysDefClass::Save(csave);
|
||||
csave.End_Chunk();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicPhysDefClass::Load(ChunkLoadClass &cload)
|
||||
{
|
||||
while (cload.Open_Chunk()) {
|
||||
|
||||
switch(cload.Cur_Chunk_ID()) {
|
||||
|
||||
case DYNAMICPHYSDEF_CHUNK_PHYSDEF:
|
||||
PhysDefClass::Load(cload);
|
||||
break;
|
||||
}
|
||||
|
||||
cload.Close_Chunk();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user