729 lines
20 KiB
C++
729 lines
20 KiB
C++
|
/*
|
||
|
** 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/pscene_saveload.cpp $*
|
||
|
* *
|
||
|
* Original Author:: Greg Hjelstrom *
|
||
|
* *
|
||
|
* $Author:: Bhayes $*
|
||
|
* *
|
||
|
* $Modtime:: 1/07/03 2:22p $*
|
||
|
* *
|
||
|
* $Revision:: 22 $*
|
||
|
* *
|
||
|
*---------------------------------------------------------------------------------------------*
|
||
|
* Functions: *
|
||
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
#include "pscene.h"
|
||
|
#include "chunkio.h"
|
||
|
#include "staticaabtreecull.h"
|
||
|
#include "dynamicaabtreecull.h"
|
||
|
#include "physgridcull.h"
|
||
|
#include "staticphys.h"
|
||
|
#include "staticanimphys.h"
|
||
|
#include "lightcull.h"
|
||
|
#include "light.h"
|
||
|
#include "persistfactory.h"
|
||
|
#include "wwmemlog.h"
|
||
|
|
||
|
|
||
|
/*
|
||
|
** This module contains the save-load related methods of PhysicsSceneClass.
|
||
|
*/
|
||
|
|
||
|
|
||
|
/*
|
||
|
** Chunk-ID's for PhysicsSceneClass
|
||
|
**
|
||
|
** LOAD-SAVE NOTES:
|
||
|
** The data in the physics scene will be broken into two different files, the LSD (Level Static Data)
|
||
|
** file and the LDD (Level Dynamic Data) file. The primary reason for this is simply so that
|
||
|
** save-games can simply be a new export of the LDD file and not contain the data which is completely
|
||
|
** static throughout the run of the level.
|
||
|
**
|
||
|
*/
|
||
|
enum
|
||
|
{
|
||
|
// Chunk ID's used by the physics scene when saving the 'Static Data' (PhysStaticDataSaveSystem)
|
||
|
PSCENE_SD_CHUNK_STATIC_OBJECT_AABTREE = 0x00004500,
|
||
|
PSCENE_SD_CHUNK_STATIC_LIGHT_AABTREE = 0x00004501,
|
||
|
PSCENE_SD_CHUNK_DYNAMIC_OBJECT_GRID = 0x00004600, // OBSOLETE!!!
|
||
|
PSCENE_SD_CHUNK_DYNAMIC_OBJECT_VIS_AABTREE = 0x00004601,
|
||
|
PSCENE_SD_CHUNK_VISIBILITY_DATA = 0x00004700,
|
||
|
PSCENE_SD_CHUNK_SUNLIGHT = 0x00004800,
|
||
|
PSCENE_SD_CHUNK_SCENECLASS = 0x00004810,
|
||
|
PSCENE_SD_CHUNK_VARIABLES = 0x00004820,
|
||
|
|
||
|
PSCENE_SD_VARIABLE_AMBIENT = 0x00,
|
||
|
|
||
|
// Chunk ID's used by the physics scene when saving the 'Static Objects' (PhysStaticObjectsSaveSystem)
|
||
|
PSCENE_SO_CHUNK_STATIC_OBJECTS = 0x00770100,
|
||
|
PSCENE_SO_CHUNK_STATIC_OBJECT,
|
||
|
PSCENE_SO_CHUNK_STATIC_OBJECT_AABLINK,
|
||
|
|
||
|
PSCENE_SO_CHUNK_STATIC_LIGHTS = 0x00770200,
|
||
|
PSCENE_SO_CHUNK_STATIC_LIGHT,
|
||
|
PSCENE_SO_CHUNK_STATIC_LIGHT_AABLINK,
|
||
|
|
||
|
// Chunk ID's used by the physics scene when saving the dynamic data and objects (PhysDynamicDataSaveSystem)
|
||
|
XXX_PSCENE_DD_CHUNK_SCENECLASS = 0x00890000,
|
||
|
PSCENE_DD_CHUNK_VARIABLES = 0x00890001,
|
||
|
PSCENE_DD_CHUNK_COLLISION_FLAGS = 0x00890002, // OBSOLETE!!!
|
||
|
|
||
|
PSCENE_DD_CHUNK_DYNAMIC_OBJECTS = 0x00890100,
|
||
|
PSCENE_DD_CHUNK_DYNAMIC_OBJECT,
|
||
|
PSCENE_DD_CHUNK_DYNAMIC_OBJECT_GRIDLINK,
|
||
|
|
||
|
// Chunk ID's used to save the states of static objects
|
||
|
PSCENE_DD_CHUNK_STATIC_OBJECT_STATES = 0x00890200,
|
||
|
PSCENE_DD_CHUNK_STATIC_OBJECT_STATE,
|
||
|
PSCENE_DD_CHUNK_STATIC_OBJECT_ID,
|
||
|
PSCENE_DD_CHUNK_STATIC_OLD_PTR,
|
||
|
|
||
|
// Micro Chunk ID's used by dynamic data variables
|
||
|
PSCENE_DD_VARIABLE_DYNAMICPOLYBUDGET = 0x00,
|
||
|
PSCENE_DD_VARIABLE_STATICPOLYBUDGET = 0x01,
|
||
|
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
** Structure for saving the sun settings
|
||
|
*/
|
||
|
struct IOSunLightStruct
|
||
|
{
|
||
|
uint32 Enabled;
|
||
|
float32 Yaw;
|
||
|
float32 Pitch;
|
||
|
float32 Intensity;
|
||
|
IOVector3Struct Color;
|
||
|
};
|
||
|
|
||
|
|
||
|
void PhysicsSceneClass::Export_Vis_Data(ChunkSaveClass & csave)
|
||
|
{
|
||
|
VisTableManager.Save(csave);
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Import_Vis_Data(ChunkLoadClass & cload)
|
||
|
{
|
||
|
Internal_Vis_Reset();
|
||
|
VisTableManager.Load(cload);
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Save_Level_Static_Data(ChunkSaveClass & csave)
|
||
|
{
|
||
|
/*
|
||
|
** If the visibility system has been invalidated, reset it so that
|
||
|
** we dont save garbage data!
|
||
|
*/
|
||
|
Internal_Vis_Reset();
|
||
|
|
||
|
/*
|
||
|
** Things to save here:
|
||
|
** - Parent class settings (SceneClass -> fog color, depth ranges, polyrender mode, etc)
|
||
|
** - StaticCullingSystem structure (but not the objects in it)
|
||
|
** - DynamicCullingSystem structure (not objects)
|
||
|
** - LightCullingSystem structure (not objects)
|
||
|
** - Visibility Tables
|
||
|
** - Sunlight settings
|
||
|
*/
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_SCENECLASS);
|
||
|
SceneClass::Save(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_STATIC_OBJECT_AABTREE);
|
||
|
StaticCullingSystem->Save_Static_Data(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_STATIC_LIGHT_AABTREE);
|
||
|
StaticLightingSystem->Save_Static_Data(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
// csave.Begin_Chunk(PSCENE_SD_CHUNK_DYNAMIC_OBJECT_GRID);
|
||
|
// DynamicCullingSystem->Save_Static_Data(csave);
|
||
|
// csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_DYNAMIC_OBJECT_VIS_AABTREE);
|
||
|
DynamicObjVisSystem->Save_Static_Data(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_VISIBILITY_DATA);
|
||
|
VisTableManager.Save(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_SUNLIGHT);
|
||
|
Save_Sun_Light(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SD_CHUNK_VARIABLES);
|
||
|
WRITE_MICRO_CHUNK(csave,PSCENE_SD_VARIABLE_AMBIENT,SceneAmbientLight);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Level_Static_Data(ChunkLoadClass & cload)
|
||
|
{
|
||
|
WWMEMLOG(MEM_PHYSICSDATA);
|
||
|
VisResetNeeded = false;
|
||
|
LastValidVisId = -1;
|
||
|
|
||
|
/*
|
||
|
** Things to load here:
|
||
|
** - StaticCullingSystem structure (but not the objects in it)
|
||
|
** - LightCullingSystem structure (not objects)
|
||
|
** - DynamicCullingSystem structure (not objects)
|
||
|
** - Visibility Tables
|
||
|
*/
|
||
|
VisTableManager.Reset();
|
||
|
while (cload.Open_Chunk()) {
|
||
|
switch (cload.Cur_Chunk_ID()) {
|
||
|
case PSCENE_SD_CHUNK_SCENECLASS:
|
||
|
SceneClass::Load(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_SD_CHUNK_STATIC_OBJECT_AABTREE:
|
||
|
StaticCullingSystem->Load_Static_Data(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_SD_CHUNK_STATIC_LIGHT_AABTREE:
|
||
|
StaticLightingSystem->Load_Static_Data(cload);
|
||
|
break;
|
||
|
|
||
|
// case PSCENE_SD_CHUNK_DYNAMIC_OBJECT_GRID:
|
||
|
// DynamicCullingSystem->Load(cload);
|
||
|
// break;
|
||
|
|
||
|
case PSCENE_SD_CHUNK_DYNAMIC_OBJECT_VIS_AABTREE:
|
||
|
DynamicObjVisSystem->Load_Static_Data(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_SD_CHUNK_VISIBILITY_DATA:
|
||
|
VisTableManager.Load(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_SD_CHUNK_SUNLIGHT:
|
||
|
Load_Sun_Light(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_SD_CHUNK_VARIABLES:
|
||
|
while (cload.Open_Micro_Chunk()) {
|
||
|
switch(cload.Cur_Micro_Chunk_ID()) {
|
||
|
READ_MICRO_CHUNK(cload,PSCENE_SD_VARIABLE_AMBIENT,SceneAmbientLight);
|
||
|
}
|
||
|
cload.Close_Micro_Chunk();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Post_Load_Level_Static_Data(void)
|
||
|
{
|
||
|
Vector3 wmin,wmax;
|
||
|
Get_Level_Extents(wmin,wmax);
|
||
|
DynamicCullingSystem->Re_Partition(wmin,wmax,10.0f);
|
||
|
|
||
|
Compute_Vis_Mesh_Ram();
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Save_Level_Static_Objects(ChunkSaveClass & csave)
|
||
|
{
|
||
|
/*
|
||
|
** Things to save here:
|
||
|
** - Objects which have absolutely no dynamic state and cannot be created or destroyed during a level.
|
||
|
** - Lights which also follow the same rules...
|
||
|
*/
|
||
|
if (!StaticObjList.Is_Empty()) {
|
||
|
csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_OBJECTS);
|
||
|
Save_Static_Objects(csave);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
|
||
|
if (!StaticLightList.Is_Empty()) {
|
||
|
csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_LIGHTS);
|
||
|
Save_Static_Lights(csave);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Level_Static_Objects(ChunkLoadClass & cload)
|
||
|
{
|
||
|
/*
|
||
|
** Things to load here:
|
||
|
** - Static objects and lights
|
||
|
*/
|
||
|
WWASSERT(StaticObjList.Is_Empty());
|
||
|
WWASSERT(StaticLightList.Is_Empty());
|
||
|
|
||
|
while (cload.Open_Chunk()) {
|
||
|
switch (cload.Cur_Chunk_ID())
|
||
|
{
|
||
|
case PSCENE_SO_CHUNK_STATIC_OBJECTS:
|
||
|
Load_Static_Objects(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_SO_CHUNK_STATIC_LIGHTS:
|
||
|
Load_Static_Lights(cload);
|
||
|
break;
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Post_Load_Level_Static_Objects(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Save_Level_Dynamic_Data(ChunkSaveClass & csave)
|
||
|
{
|
||
|
/*
|
||
|
** Things to save here
|
||
|
** - CollisionFlags
|
||
|
** - DynamicPolyBudget
|
||
|
** - StaticPolyBudget
|
||
|
** - List of dynamic objects (embed each in a chunk, embed cull linkage, build the list again at load time)
|
||
|
** - List of static objects (embed each in a chunk, ... )
|
||
|
** - List of static lights (embed each in a chunk, ... )
|
||
|
** - DirtyCullList - this will have to be a "de-swizzle" list.
|
||
|
** NOTES:
|
||
|
** - each phys obj should tell their render object that they were added in post-load
|
||
|
*/
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_VARIABLES);
|
||
|
Save_LDD_Variables(csave);
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
if (!ObjList.Is_Empty()) {
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_DYNAMIC_OBJECTS);
|
||
|
Save_Dynamic_Objects(csave);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
|
||
|
if (!StaticAnimList.Is_Empty()) {
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OBJECT_STATES);
|
||
|
Save_Static_Object_States(csave);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
|
||
|
#if 0 // Do I need to do this?
|
||
|
if (!DirtyCullList.Is_Empty()) {
|
||
|
csave.Begin_Chunk(PSCENE_LDD_CHUNK_DIRTY_CULL_LIST);
|
||
|
Save_LDD_Dirty_Cull_List();
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Level_Dynamic_Data(ChunkLoadClass & cload)
|
||
|
{
|
||
|
WWMEMLOG(MEM_PHYSICSDATA);
|
||
|
while (cload.Open_Chunk()) {
|
||
|
switch(cload.Cur_Chunk_ID()) {
|
||
|
|
||
|
case PSCENE_DD_CHUNK_VARIABLES:
|
||
|
Load_LDD_Variables(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_DD_CHUNK_DYNAMIC_OBJECTS:
|
||
|
Load_Dynamic_Objects(cload);
|
||
|
break;
|
||
|
|
||
|
case PSCENE_DD_CHUNK_STATIC_OBJECT_STATES:
|
||
|
Load_Static_Object_States(cload);
|
||
|
break;
|
||
|
|
||
|
#if 0 // Do I need to do this?
|
||
|
case PSCENE_LDD_CHUNK_DIRTY_CULL_LIST:
|
||
|
Load_LDD_Dirty_Cull_List(cload);
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
WWDEBUG_SAY(("Unhandled Chunk: 0x%X in file: %s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
||
|
break;
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void PhysicsSceneClass::Save_LDD_Variables(ChunkSaveClass & csave)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
void PhysicsSceneClass::Load_LDD_Variables(ChunkLoadClass & cload)
|
||
|
{
|
||
|
while (cload.Open_Micro_Chunk()) {
|
||
|
switch (cload.Cur_Micro_Chunk_ID()) {
|
||
|
OBSOLETE_MICRO_CHUNK(PSCENE_DD_VARIABLE_DYNAMICPOLYBUDGET);
|
||
|
OBSOLETE_MICRO_CHUNK(PSCENE_DD_VARIABLE_STATICPOLYBUDGET);
|
||
|
default:
|
||
|
WWDEBUG_SAY(("Unhandled Micro Chunk: 0x%x in file &s, line %d\n",cload.Cur_Micro_Chunk_ID(),__FILE__,__LINE__));
|
||
|
}
|
||
|
cload.Close_Micro_Chunk();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void PhysicsSceneClass::Save_Static_Objects(ChunkSaveClass & csave)
|
||
|
{
|
||
|
/*
|
||
|
** Save each object and save each object's culling linkage
|
||
|
*/
|
||
|
RefPhysListIterator it(&StaticObjList);
|
||
|
for (it.First(); !it.Is_Done(); it.Next()) {
|
||
|
|
||
|
PhysClass * obj = it.Peek_Obj();
|
||
|
WWASSERT(obj != NULL);
|
||
|
|
||
|
if ((obj) && (obj->Is_Dont_Save_Enabled() == false)) {
|
||
|
StaticPhysClass * staticobj = obj->As_StaticPhysClass();
|
||
|
WWASSERT(staticobj != NULL);
|
||
|
|
||
|
if (staticobj) {
|
||
|
/*
|
||
|
** Wrap the factory defined chunk with our own so that it's in its own
|
||
|
** "chunk-space"
|
||
|
*/
|
||
|
csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_OBJECT);
|
||
|
csave.Begin_Chunk(staticobj->Get_Factory().Chunk_ID());
|
||
|
staticobj->Get_Factory().Save(csave,staticobj);
|
||
|
csave.End_Chunk();
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
/*
|
||
|
** Follow the object data with its linkage data
|
||
|
*/
|
||
|
csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_OBJECT_AABLINK);
|
||
|
StaticCullingSystem->Save_Object_Linkage(csave,staticobj);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Static_Objects(ChunkLoadClass & cload)
|
||
|
{
|
||
|
while (cload.Open_Chunk()) {
|
||
|
|
||
|
if (cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_OBJECT) {
|
||
|
|
||
|
/*
|
||
|
** Load the object
|
||
|
*/
|
||
|
cload.Open_Chunk();
|
||
|
StaticPhysClass * obj = NULL;
|
||
|
PersistFactoryClass * fact = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
|
||
|
WWASSERT(fact != NULL);
|
||
|
if (fact) {
|
||
|
obj = (StaticPhysClass *)fact->Load(cload);
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
/*
|
||
|
** Load the object's linkage into the Static Culling System
|
||
|
*/
|
||
|
cload.Open_Chunk();
|
||
|
if ((cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_OBJECT_AABLINK) && (obj)) {
|
||
|
StaticCullingSystem->Load_Object_Linkage(cload,obj);
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
/*
|
||
|
** Finish installing the object into the physics scene
|
||
|
** - Add it to the static objects list
|
||
|
** - If it requires time-stepping, add to the timestep list
|
||
|
** - Let the base SceneClass notify the render object that it has been added.
|
||
|
*/
|
||
|
Internal_Add_Static_Object(obj);
|
||
|
obj->Release_Ref();
|
||
|
|
||
|
} else {
|
||
|
WWDEBUG_SAY(("Unhandled Chunk: 0x%x in file %s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Save_Static_Lights(ChunkSaveClass & csave)
|
||
|
{
|
||
|
/*
|
||
|
** Save each object and save each object's culling linkage
|
||
|
*/
|
||
|
RefPhysListIterator it(&StaticLightList);
|
||
|
for (it.First(); !it.Is_Done(); it.Next()) {
|
||
|
|
||
|
PhysClass * obj = it.Peek_Obj();
|
||
|
WWASSERT(obj != NULL);
|
||
|
|
||
|
if (obj) {
|
||
|
LightPhysClass * lightobj = obj->As_LightPhysClass();
|
||
|
WWASSERT(lightobj != NULL);
|
||
|
|
||
|
if (lightobj) {
|
||
|
csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_LIGHT);
|
||
|
csave.Begin_Chunk(lightobj->Get_Factory().Chunk_ID());
|
||
|
lightobj->Get_Factory().Save(csave,lightobj);
|
||
|
csave.End_Chunk();
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_LIGHT_AABLINK);
|
||
|
StaticLightingSystem->Save_Object_Linkage(csave,lightobj);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Static_Lights(ChunkLoadClass & cload)
|
||
|
{
|
||
|
while (cload.Open_Chunk()) {
|
||
|
|
||
|
if (cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_LIGHT) {
|
||
|
|
||
|
/*
|
||
|
** Load the object
|
||
|
*/
|
||
|
cload.Open_Chunk();
|
||
|
LightPhysClass * obj = NULL;
|
||
|
PersistFactoryClass * fact = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
|
||
|
WWASSERT(fact != NULL);
|
||
|
if (fact) {
|
||
|
obj = (LightPhysClass *)fact->Load(cload);
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
/*
|
||
|
** Load the object's linkage into the static light culling system
|
||
|
*/
|
||
|
WWASSERT(obj);
|
||
|
cload.Open_Chunk();
|
||
|
if ((cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_LIGHT_AABLINK) && (obj)) {
|
||
|
StaticLightingSystem->Load_Object_Linkage(cload,obj);
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
/*
|
||
|
** Finish installing the object into the physics scene
|
||
|
*/
|
||
|
Internal_Add_Static_Light(obj);
|
||
|
obj->Release_Ref();
|
||
|
|
||
|
} else {
|
||
|
WWDEBUG_SAY(("Unhandled Chunk: 0x%x in file &s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Sun_Light(ChunkLoadClass & cload)
|
||
|
{
|
||
|
WWASSERT(SunLight != NULL);
|
||
|
IOSunLightStruct sun;
|
||
|
cload.Read(&sun,sizeof(sun));
|
||
|
|
||
|
UseSun = (sun.Enabled == 1);
|
||
|
Vector3 color;
|
||
|
color.X = sun.Color.X;
|
||
|
color.Y = sun.Color.Y;
|
||
|
color.Z = sun.Color.Z;
|
||
|
SunLight->Set_Diffuse(color);
|
||
|
SunLight->Set_Intensity(sun.Intensity);
|
||
|
Set_Sun_Light_Orientation(sun.Yaw,sun.Pitch);
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Save_Sun_Light(ChunkSaveClass & csave)
|
||
|
{
|
||
|
WWASSERT(SunLight != NULL);
|
||
|
IOSunLightStruct sun;
|
||
|
memset(&sun,0,sizeof(sun));
|
||
|
|
||
|
sun.Enabled = (UseSun ? 1 : 0);
|
||
|
sun.Yaw = SunYaw;
|
||
|
sun.Pitch = SunPitch;
|
||
|
sun.Intensity = SunLight->Get_Intensity();
|
||
|
|
||
|
Vector3 c;
|
||
|
SunLight->Get_Diffuse(&c);
|
||
|
sun.Color.X = c.X;
|
||
|
sun.Color.Y = c.Y;
|
||
|
sun.Color.Z = c.Z;
|
||
|
|
||
|
csave.Write(&sun,sizeof(sun));
|
||
|
}
|
||
|
|
||
|
|
||
|
void PhysicsSceneClass::Save_Dynamic_Objects(ChunkSaveClass & csave)
|
||
|
{
|
||
|
/*
|
||
|
** Save each object and save each object's culling linkage
|
||
|
*/
|
||
|
RefPhysListIterator it(&ObjList);
|
||
|
for (it.First(); !it.Is_Done(); it.Next()) {
|
||
|
|
||
|
PhysClass * obj = it.Peek_Obj();
|
||
|
WWASSERT(obj != NULL);
|
||
|
|
||
|
if ((obj) && (obj->Is_Dont_Save_Enabled() == false)) {
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_DYNAMIC_OBJECT);
|
||
|
csave.Begin_Chunk(obj->Get_Factory().Chunk_ID());
|
||
|
obj->Get_Factory().Save(csave,obj);
|
||
|
csave.End_Chunk();
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void PhysicsSceneClass::Load_Dynamic_Objects(ChunkLoadClass & cload)
|
||
|
{
|
||
|
while (cload.Open_Chunk()) {
|
||
|
|
||
|
if (cload.Cur_Chunk_ID() == PSCENE_DD_CHUNK_DYNAMIC_OBJECT) {
|
||
|
|
||
|
/*
|
||
|
** Load the object
|
||
|
*/
|
||
|
cload.Open_Chunk();
|
||
|
PhysClass * obj = NULL;
|
||
|
PersistFactoryClass * fact = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
|
||
|
WWASSERT(fact != NULL);
|
||
|
if (fact) {
|
||
|
obj = (PhysClass *)fact->Load(cload);
|
||
|
}
|
||
|
cload.Close_Chunk();
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
WWASSERT(obj);
|
||
|
|
||
|
/*
|
||
|
** Add the object to the dynamic culling system
|
||
|
*/
|
||
|
DynamicCullingSystem->Add_Object(obj);
|
||
|
|
||
|
/*
|
||
|
** Finish installing the object into the physics scene
|
||
|
** - Add it to the culling system
|
||
|
** - Add it to the appropriate list
|
||
|
** - Notify the render object that it was added to the scene
|
||
|
*/
|
||
|
Internal_Add_Dynamic_Object(obj);
|
||
|
obj->Release_Ref();
|
||
|
|
||
|
} else {
|
||
|
WWDEBUG_SAY(("Unhandled Chunk: 0x%x in file &s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Save_Static_Object_States(ChunkSaveClass & csave)
|
||
|
{
|
||
|
RefPhysListIterator it(&StaticObjList);
|
||
|
while (!it.Is_Done()) {
|
||
|
|
||
|
if (((StaticPhysClass*)it.Peek_Obj())->Has_Dynamic_State()) {
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OBJECT_ID);
|
||
|
uint32 id = it.Peek_Obj()->Get_ID();
|
||
|
csave.Write(&id,sizeof(uint32));
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OLD_PTR);
|
||
|
void * old_ptr = it.Peek_Obj();
|
||
|
csave.Write(&old_ptr,sizeof(void *));
|
||
|
csave.End_Chunk();
|
||
|
|
||
|
csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OBJECT_STATE);
|
||
|
((StaticPhysClass *)it.Peek_Obj())->Save_State(csave);
|
||
|
csave.End_Chunk();
|
||
|
}
|
||
|
|
||
|
it.Next();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Load_Static_Object_States(ChunkLoadClass & cload)
|
||
|
{
|
||
|
while (cload.Open_Chunk()) {
|
||
|
WWASSERT(cload.Cur_Chunk_ID()==PSCENE_DD_CHUNK_STATIC_OBJECT_ID);
|
||
|
uint32 id;
|
||
|
cload.Read(&id,sizeof(uint32));
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
StaticPhysClass * sphys = Get_Static_Object_By_ID(id);
|
||
|
|
||
|
cload.Open_Chunk();
|
||
|
WWASSERT(cload.Cur_Chunk_ID()==PSCENE_DD_CHUNK_STATIC_OLD_PTR);
|
||
|
void * old_ptr;
|
||
|
cload.Read(&old_ptr,sizeof(void *));
|
||
|
SaveLoadSystemClass::Register_Pointer(old_ptr, sphys);
|
||
|
cload.Close_Chunk();
|
||
|
|
||
|
cload.Open_Chunk();
|
||
|
WWASSERT(cload.Cur_Chunk_ID()==PSCENE_DD_CHUNK_STATIC_OBJECT_STATE);
|
||
|
if (sphys != NULL) {
|
||
|
sphys->Load_State(cload);
|
||
|
sphys->Release_Ref();
|
||
|
} else {
|
||
|
WWDEBUG_SAY(("Unable to find static object! id = %d\r\n",id));
|
||
|
}
|
||
|
|
||
|
cload.Close_Chunk();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PhysicsSceneClass::Post_Load_Level_Dynamic_Data(void)
|
||
|
{
|
||
|
/*
|
||
|
** Possible TODO List:
|
||
|
** - Rebuild the dirty cull list?
|
||
|
** - Rebuild the lists of vertex processors? (tell each model that its been added?)
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
** Re-generate the static shadows
|
||
|
*/
|
||
|
// Generate_Static_Shadow_Projectors();
|
||
|
// We don't necessarily have active device at this point so we can't render the shadows yet.
|
||
|
// The shadows will be generated as soon as the device is available at the start of the game.
|
||
|
Invalidate_Static_Shadow_Projectors();
|
||
|
}
|
||
|
|
||
|
StaticPhysClass * PhysicsSceneClass::Get_Static_Object_By_ID(uint32 id)
|
||
|
{
|
||
|
RefPhysListIterator it(&StaticObjList);
|
||
|
while (!it.Is_Done()) {
|
||
|
if (it.Peek_Obj()->Get_ID() == id) {
|
||
|
return (StaticPhysClass *)it.Get_Obj();
|
||
|
}
|
||
|
it.Next();
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|