pscene_saveload.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWPhys *
  23. * *
  24. * $Archive:: /Commando/Code/wwphys/pscene_saveload.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Bhayes $*
  29. * *
  30. * $Modtime:: 1/07/03 2:22p $*
  31. * *
  32. * $Revision:: 22 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #include "pscene.h"
  38. #include "chunkio.h"
  39. #include "staticaabtreecull.h"
  40. #include "dynamicaabtreecull.h"
  41. #include "physgridcull.h"
  42. #include "staticphys.h"
  43. #include "staticanimphys.h"
  44. #include "lightcull.h"
  45. #include "light.h"
  46. #include "persistfactory.h"
  47. #include "wwmemlog.h"
  48. /*
  49. ** This module contains the save-load related methods of PhysicsSceneClass.
  50. */
  51. /*
  52. ** Chunk-ID's for PhysicsSceneClass
  53. **
  54. ** LOAD-SAVE NOTES:
  55. ** The data in the physics scene will be broken into two different files, the LSD (Level Static Data)
  56. ** file and the LDD (Level Dynamic Data) file. The primary reason for this is simply so that
  57. ** save-games can simply be a new export of the LDD file and not contain the data which is completely
  58. ** static throughout the run of the level.
  59. **
  60. */
  61. enum
  62. {
  63. // Chunk ID's used by the physics scene when saving the 'Static Data' (PhysStaticDataSaveSystem)
  64. PSCENE_SD_CHUNK_STATIC_OBJECT_AABTREE = 0x00004500,
  65. PSCENE_SD_CHUNK_STATIC_LIGHT_AABTREE = 0x00004501,
  66. PSCENE_SD_CHUNK_DYNAMIC_OBJECT_GRID = 0x00004600, // OBSOLETE!!!
  67. PSCENE_SD_CHUNK_DYNAMIC_OBJECT_VIS_AABTREE = 0x00004601,
  68. PSCENE_SD_CHUNK_VISIBILITY_DATA = 0x00004700,
  69. PSCENE_SD_CHUNK_SUNLIGHT = 0x00004800,
  70. PSCENE_SD_CHUNK_SCENECLASS = 0x00004810,
  71. PSCENE_SD_CHUNK_VARIABLES = 0x00004820,
  72. PSCENE_SD_VARIABLE_AMBIENT = 0x00,
  73. // Chunk ID's used by the physics scene when saving the 'Static Objects' (PhysStaticObjectsSaveSystem)
  74. PSCENE_SO_CHUNK_STATIC_OBJECTS = 0x00770100,
  75. PSCENE_SO_CHUNK_STATIC_OBJECT,
  76. PSCENE_SO_CHUNK_STATIC_OBJECT_AABLINK,
  77. PSCENE_SO_CHUNK_STATIC_LIGHTS = 0x00770200,
  78. PSCENE_SO_CHUNK_STATIC_LIGHT,
  79. PSCENE_SO_CHUNK_STATIC_LIGHT_AABLINK,
  80. // Chunk ID's used by the physics scene when saving the dynamic data and objects (PhysDynamicDataSaveSystem)
  81. XXX_PSCENE_DD_CHUNK_SCENECLASS = 0x00890000,
  82. PSCENE_DD_CHUNK_VARIABLES = 0x00890001,
  83. PSCENE_DD_CHUNK_COLLISION_FLAGS = 0x00890002, // OBSOLETE!!!
  84. PSCENE_DD_CHUNK_DYNAMIC_OBJECTS = 0x00890100,
  85. PSCENE_DD_CHUNK_DYNAMIC_OBJECT,
  86. PSCENE_DD_CHUNK_DYNAMIC_OBJECT_GRIDLINK,
  87. // Chunk ID's used to save the states of static objects
  88. PSCENE_DD_CHUNK_STATIC_OBJECT_STATES = 0x00890200,
  89. PSCENE_DD_CHUNK_STATIC_OBJECT_STATE,
  90. PSCENE_DD_CHUNK_STATIC_OBJECT_ID,
  91. PSCENE_DD_CHUNK_STATIC_OLD_PTR,
  92. // Micro Chunk ID's used by dynamic data variables
  93. PSCENE_DD_VARIABLE_DYNAMICPOLYBUDGET = 0x00,
  94. PSCENE_DD_VARIABLE_STATICPOLYBUDGET = 0x01,
  95. };
  96. /*
  97. ** Structure for saving the sun settings
  98. */
  99. struct IOSunLightStruct
  100. {
  101. uint32 Enabled;
  102. float32 Yaw;
  103. float32 Pitch;
  104. float32 Intensity;
  105. IOVector3Struct Color;
  106. };
  107. void PhysicsSceneClass::Export_Vis_Data(ChunkSaveClass & csave)
  108. {
  109. VisTableManager.Save(csave);
  110. }
  111. void PhysicsSceneClass::Import_Vis_Data(ChunkLoadClass & cload)
  112. {
  113. Internal_Vis_Reset();
  114. VisTableManager.Load(cload);
  115. }
  116. void PhysicsSceneClass::Save_Level_Static_Data(ChunkSaveClass & csave)
  117. {
  118. /*
  119. ** If the visibility system has been invalidated, reset it so that
  120. ** we dont save garbage data!
  121. */
  122. Internal_Vis_Reset();
  123. /*
  124. ** Things to save here:
  125. ** - Parent class settings (SceneClass -> fog color, depth ranges, polyrender mode, etc)
  126. ** - StaticCullingSystem structure (but not the objects in it)
  127. ** - DynamicCullingSystem structure (not objects)
  128. ** - LightCullingSystem structure (not objects)
  129. ** - Visibility Tables
  130. ** - Sunlight settings
  131. */
  132. csave.Begin_Chunk(PSCENE_SD_CHUNK_SCENECLASS);
  133. SceneClass::Save(csave);
  134. csave.End_Chunk();
  135. csave.Begin_Chunk(PSCENE_SD_CHUNK_STATIC_OBJECT_AABTREE);
  136. StaticCullingSystem->Save_Static_Data(csave);
  137. csave.End_Chunk();
  138. csave.Begin_Chunk(PSCENE_SD_CHUNK_STATIC_LIGHT_AABTREE);
  139. StaticLightingSystem->Save_Static_Data(csave);
  140. csave.End_Chunk();
  141. // csave.Begin_Chunk(PSCENE_SD_CHUNK_DYNAMIC_OBJECT_GRID);
  142. // DynamicCullingSystem->Save_Static_Data(csave);
  143. // csave.End_Chunk();
  144. csave.Begin_Chunk(PSCENE_SD_CHUNK_DYNAMIC_OBJECT_VIS_AABTREE);
  145. DynamicObjVisSystem->Save_Static_Data(csave);
  146. csave.End_Chunk();
  147. csave.Begin_Chunk(PSCENE_SD_CHUNK_VISIBILITY_DATA);
  148. VisTableManager.Save(csave);
  149. csave.End_Chunk();
  150. csave.Begin_Chunk(PSCENE_SD_CHUNK_SUNLIGHT);
  151. Save_Sun_Light(csave);
  152. csave.End_Chunk();
  153. csave.Begin_Chunk(PSCENE_SD_CHUNK_VARIABLES);
  154. WRITE_MICRO_CHUNK(csave,PSCENE_SD_VARIABLE_AMBIENT,SceneAmbientLight);
  155. csave.End_Chunk();
  156. }
  157. void PhysicsSceneClass::Load_Level_Static_Data(ChunkLoadClass & cload)
  158. {
  159. WWMEMLOG(MEM_PHYSICSDATA);
  160. VisResetNeeded = false;
  161. LastValidVisId = -1;
  162. /*
  163. ** Things to load here:
  164. ** - StaticCullingSystem structure (but not the objects in it)
  165. ** - LightCullingSystem structure (not objects)
  166. ** - DynamicCullingSystem structure (not objects)
  167. ** - Visibility Tables
  168. */
  169. VisTableManager.Reset();
  170. while (cload.Open_Chunk()) {
  171. switch (cload.Cur_Chunk_ID()) {
  172. case PSCENE_SD_CHUNK_SCENECLASS:
  173. SceneClass::Load(cload);
  174. break;
  175. case PSCENE_SD_CHUNK_STATIC_OBJECT_AABTREE:
  176. StaticCullingSystem->Load_Static_Data(cload);
  177. break;
  178. case PSCENE_SD_CHUNK_STATIC_LIGHT_AABTREE:
  179. StaticLightingSystem->Load_Static_Data(cload);
  180. break;
  181. // case PSCENE_SD_CHUNK_DYNAMIC_OBJECT_GRID:
  182. // DynamicCullingSystem->Load(cload);
  183. // break;
  184. case PSCENE_SD_CHUNK_DYNAMIC_OBJECT_VIS_AABTREE:
  185. DynamicObjVisSystem->Load_Static_Data(cload);
  186. break;
  187. case PSCENE_SD_CHUNK_VISIBILITY_DATA:
  188. VisTableManager.Load(cload);
  189. break;
  190. case PSCENE_SD_CHUNK_SUNLIGHT:
  191. Load_Sun_Light(cload);
  192. break;
  193. case PSCENE_SD_CHUNK_VARIABLES:
  194. while (cload.Open_Micro_Chunk()) {
  195. switch(cload.Cur_Micro_Chunk_ID()) {
  196. READ_MICRO_CHUNK(cload,PSCENE_SD_VARIABLE_AMBIENT,SceneAmbientLight);
  197. }
  198. cload.Close_Micro_Chunk();
  199. }
  200. break;
  201. }
  202. cload.Close_Chunk();
  203. }
  204. }
  205. void PhysicsSceneClass::Post_Load_Level_Static_Data(void)
  206. {
  207. Vector3 wmin,wmax;
  208. Get_Level_Extents(wmin,wmax);
  209. DynamicCullingSystem->Re_Partition(wmin,wmax,10.0f);
  210. Compute_Vis_Mesh_Ram();
  211. }
  212. void PhysicsSceneClass::Save_Level_Static_Objects(ChunkSaveClass & csave)
  213. {
  214. /*
  215. ** Things to save here:
  216. ** - Objects which have absolutely no dynamic state and cannot be created or destroyed during a level.
  217. ** - Lights which also follow the same rules...
  218. */
  219. if (!StaticObjList.Is_Empty()) {
  220. csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_OBJECTS);
  221. Save_Static_Objects(csave);
  222. csave.End_Chunk();
  223. }
  224. if (!StaticLightList.Is_Empty()) {
  225. csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_LIGHTS);
  226. Save_Static_Lights(csave);
  227. csave.End_Chunk();
  228. }
  229. }
  230. void PhysicsSceneClass::Load_Level_Static_Objects(ChunkLoadClass & cload)
  231. {
  232. /*
  233. ** Things to load here:
  234. ** - Static objects and lights
  235. */
  236. WWASSERT(StaticObjList.Is_Empty());
  237. WWASSERT(StaticLightList.Is_Empty());
  238. while (cload.Open_Chunk()) {
  239. switch (cload.Cur_Chunk_ID())
  240. {
  241. case PSCENE_SO_CHUNK_STATIC_OBJECTS:
  242. Load_Static_Objects(cload);
  243. break;
  244. case PSCENE_SO_CHUNK_STATIC_LIGHTS:
  245. Load_Static_Lights(cload);
  246. break;
  247. }
  248. cload.Close_Chunk();
  249. }
  250. }
  251. void PhysicsSceneClass::Post_Load_Level_Static_Objects(void)
  252. {
  253. }
  254. void PhysicsSceneClass::Save_Level_Dynamic_Data(ChunkSaveClass & csave)
  255. {
  256. /*
  257. ** Things to save here
  258. ** - CollisionFlags
  259. ** - DynamicPolyBudget
  260. ** - StaticPolyBudget
  261. ** - List of dynamic objects (embed each in a chunk, embed cull linkage, build the list again at load time)
  262. ** - List of static objects (embed each in a chunk, ... )
  263. ** - List of static lights (embed each in a chunk, ... )
  264. ** - DirtyCullList - this will have to be a "de-swizzle" list.
  265. ** NOTES:
  266. ** - each phys obj should tell their render object that they were added in post-load
  267. */
  268. csave.Begin_Chunk(PSCENE_DD_CHUNK_VARIABLES);
  269. Save_LDD_Variables(csave);
  270. csave.End_Chunk();
  271. if (!ObjList.Is_Empty()) {
  272. csave.Begin_Chunk(PSCENE_DD_CHUNK_DYNAMIC_OBJECTS);
  273. Save_Dynamic_Objects(csave);
  274. csave.End_Chunk();
  275. }
  276. if (!StaticAnimList.Is_Empty()) {
  277. csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OBJECT_STATES);
  278. Save_Static_Object_States(csave);
  279. csave.End_Chunk();
  280. }
  281. #if 0 // Do I need to do this?
  282. if (!DirtyCullList.Is_Empty()) {
  283. csave.Begin_Chunk(PSCENE_LDD_CHUNK_DIRTY_CULL_LIST);
  284. Save_LDD_Dirty_Cull_List();
  285. csave.End_Chunk();
  286. }
  287. #endif
  288. }
  289. void PhysicsSceneClass::Load_Level_Dynamic_Data(ChunkLoadClass & cload)
  290. {
  291. WWMEMLOG(MEM_PHYSICSDATA);
  292. while (cload.Open_Chunk()) {
  293. switch(cload.Cur_Chunk_ID()) {
  294. case PSCENE_DD_CHUNK_VARIABLES:
  295. Load_LDD_Variables(cload);
  296. break;
  297. case PSCENE_DD_CHUNK_DYNAMIC_OBJECTS:
  298. Load_Dynamic_Objects(cload);
  299. break;
  300. case PSCENE_DD_CHUNK_STATIC_OBJECT_STATES:
  301. Load_Static_Object_States(cload);
  302. break;
  303. #if 0 // Do I need to do this?
  304. case PSCENE_LDD_CHUNK_DIRTY_CULL_LIST:
  305. Load_LDD_Dirty_Cull_List(cload);
  306. break;
  307. #endif
  308. default:
  309. WWDEBUG_SAY(("Unhandled Chunk: 0x%X in file: %s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  310. break;
  311. }
  312. cload.Close_Chunk();
  313. }
  314. }
  315. void PhysicsSceneClass::Save_LDD_Variables(ChunkSaveClass & csave)
  316. {
  317. }
  318. void PhysicsSceneClass::Load_LDD_Variables(ChunkLoadClass & cload)
  319. {
  320. while (cload.Open_Micro_Chunk()) {
  321. switch (cload.Cur_Micro_Chunk_ID()) {
  322. OBSOLETE_MICRO_CHUNK(PSCENE_DD_VARIABLE_DYNAMICPOLYBUDGET);
  323. OBSOLETE_MICRO_CHUNK(PSCENE_DD_VARIABLE_STATICPOLYBUDGET);
  324. default:
  325. WWDEBUG_SAY(("Unhandled Micro Chunk: 0x%x in file &s, line %d\n",cload.Cur_Micro_Chunk_ID(),__FILE__,__LINE__));
  326. }
  327. cload.Close_Micro_Chunk();
  328. }
  329. }
  330. void PhysicsSceneClass::Save_Static_Objects(ChunkSaveClass & csave)
  331. {
  332. /*
  333. ** Save each object and save each object's culling linkage
  334. */
  335. RefPhysListIterator it(&StaticObjList);
  336. for (it.First(); !it.Is_Done(); it.Next()) {
  337. PhysClass * obj = it.Peek_Obj();
  338. WWASSERT(obj != NULL);
  339. if ((obj) && (obj->Is_Dont_Save_Enabled() == false)) {
  340. StaticPhysClass * staticobj = obj->As_StaticPhysClass();
  341. WWASSERT(staticobj != NULL);
  342. if (staticobj) {
  343. /*
  344. ** Wrap the factory defined chunk with our own so that it's in its own
  345. ** "chunk-space"
  346. */
  347. csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_OBJECT);
  348. csave.Begin_Chunk(staticobj->Get_Factory().Chunk_ID());
  349. staticobj->Get_Factory().Save(csave,staticobj);
  350. csave.End_Chunk();
  351. csave.End_Chunk();
  352. /*
  353. ** Follow the object data with its linkage data
  354. */
  355. csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_OBJECT_AABLINK);
  356. StaticCullingSystem->Save_Object_Linkage(csave,staticobj);
  357. csave.End_Chunk();
  358. }
  359. }
  360. }
  361. }
  362. void PhysicsSceneClass::Load_Static_Objects(ChunkLoadClass & cload)
  363. {
  364. while (cload.Open_Chunk()) {
  365. if (cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_OBJECT) {
  366. /*
  367. ** Load the object
  368. */
  369. cload.Open_Chunk();
  370. StaticPhysClass * obj = NULL;
  371. PersistFactoryClass * fact = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
  372. WWASSERT(fact != NULL);
  373. if (fact) {
  374. obj = (StaticPhysClass *)fact->Load(cload);
  375. }
  376. cload.Close_Chunk();
  377. cload.Close_Chunk();
  378. /*
  379. ** Load the object's linkage into the Static Culling System
  380. */
  381. cload.Open_Chunk();
  382. if ((cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_OBJECT_AABLINK) && (obj)) {
  383. StaticCullingSystem->Load_Object_Linkage(cload,obj);
  384. }
  385. cload.Close_Chunk();
  386. /*
  387. ** Finish installing the object into the physics scene
  388. ** - Add it to the static objects list
  389. ** - If it requires time-stepping, add to the timestep list
  390. ** - Let the base SceneClass notify the render object that it has been added.
  391. */
  392. Internal_Add_Static_Object(obj);
  393. obj->Release_Ref();
  394. } else {
  395. WWDEBUG_SAY(("Unhandled Chunk: 0x%x in file %s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  396. cload.Close_Chunk();
  397. }
  398. }
  399. }
  400. void PhysicsSceneClass::Save_Static_Lights(ChunkSaveClass & csave)
  401. {
  402. /*
  403. ** Save each object and save each object's culling linkage
  404. */
  405. RefPhysListIterator it(&StaticLightList);
  406. for (it.First(); !it.Is_Done(); it.Next()) {
  407. PhysClass * obj = it.Peek_Obj();
  408. WWASSERT(obj != NULL);
  409. if (obj) {
  410. LightPhysClass * lightobj = obj->As_LightPhysClass();
  411. WWASSERT(lightobj != NULL);
  412. if (lightobj) {
  413. csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_LIGHT);
  414. csave.Begin_Chunk(lightobj->Get_Factory().Chunk_ID());
  415. lightobj->Get_Factory().Save(csave,lightobj);
  416. csave.End_Chunk();
  417. csave.End_Chunk();
  418. csave.Begin_Chunk(PSCENE_SO_CHUNK_STATIC_LIGHT_AABLINK);
  419. StaticLightingSystem->Save_Object_Linkage(csave,lightobj);
  420. csave.End_Chunk();
  421. }
  422. }
  423. }
  424. }
  425. void PhysicsSceneClass::Load_Static_Lights(ChunkLoadClass & cload)
  426. {
  427. while (cload.Open_Chunk()) {
  428. if (cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_LIGHT) {
  429. /*
  430. ** Load the object
  431. */
  432. cload.Open_Chunk();
  433. LightPhysClass * obj = NULL;
  434. PersistFactoryClass * fact = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
  435. WWASSERT(fact != NULL);
  436. if (fact) {
  437. obj = (LightPhysClass *)fact->Load(cload);
  438. }
  439. cload.Close_Chunk();
  440. cload.Close_Chunk();
  441. /*
  442. ** Load the object's linkage into the static light culling system
  443. */
  444. WWASSERT(obj);
  445. cload.Open_Chunk();
  446. if ((cload.Cur_Chunk_ID() == PSCENE_SO_CHUNK_STATIC_LIGHT_AABLINK) && (obj)) {
  447. StaticLightingSystem->Load_Object_Linkage(cload,obj);
  448. }
  449. cload.Close_Chunk();
  450. /*
  451. ** Finish installing the object into the physics scene
  452. */
  453. Internal_Add_Static_Light(obj);
  454. obj->Release_Ref();
  455. } else {
  456. WWDEBUG_SAY(("Unhandled Chunk: 0x%x in file &s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  457. cload.Close_Chunk();
  458. }
  459. }
  460. }
  461. void PhysicsSceneClass::Load_Sun_Light(ChunkLoadClass & cload)
  462. {
  463. WWASSERT(SunLight != NULL);
  464. IOSunLightStruct sun;
  465. cload.Read(&sun,sizeof(sun));
  466. UseSun = (sun.Enabled == 1);
  467. Vector3 color;
  468. color.X = sun.Color.X;
  469. color.Y = sun.Color.Y;
  470. color.Z = sun.Color.Z;
  471. SunLight->Set_Diffuse(color);
  472. SunLight->Set_Intensity(sun.Intensity);
  473. Set_Sun_Light_Orientation(sun.Yaw,sun.Pitch);
  474. }
  475. void PhysicsSceneClass::Save_Sun_Light(ChunkSaveClass & csave)
  476. {
  477. WWASSERT(SunLight != NULL);
  478. IOSunLightStruct sun;
  479. memset(&sun,0,sizeof(sun));
  480. sun.Enabled = (UseSun ? 1 : 0);
  481. sun.Yaw = SunYaw;
  482. sun.Pitch = SunPitch;
  483. sun.Intensity = SunLight->Get_Intensity();
  484. Vector3 c;
  485. SunLight->Get_Diffuse(&c);
  486. sun.Color.X = c.X;
  487. sun.Color.Y = c.Y;
  488. sun.Color.Z = c.Z;
  489. csave.Write(&sun,sizeof(sun));
  490. }
  491. void PhysicsSceneClass::Save_Dynamic_Objects(ChunkSaveClass & csave)
  492. {
  493. /*
  494. ** Save each object and save each object's culling linkage
  495. */
  496. RefPhysListIterator it(&ObjList);
  497. for (it.First(); !it.Is_Done(); it.Next()) {
  498. PhysClass * obj = it.Peek_Obj();
  499. WWASSERT(obj != NULL);
  500. if ((obj) && (obj->Is_Dont_Save_Enabled() == false)) {
  501. csave.Begin_Chunk(PSCENE_DD_CHUNK_DYNAMIC_OBJECT);
  502. csave.Begin_Chunk(obj->Get_Factory().Chunk_ID());
  503. obj->Get_Factory().Save(csave,obj);
  504. csave.End_Chunk();
  505. csave.End_Chunk();
  506. }
  507. }
  508. }
  509. void PhysicsSceneClass::Load_Dynamic_Objects(ChunkLoadClass & cload)
  510. {
  511. while (cload.Open_Chunk()) {
  512. if (cload.Cur_Chunk_ID() == PSCENE_DD_CHUNK_DYNAMIC_OBJECT) {
  513. /*
  514. ** Load the object
  515. */
  516. cload.Open_Chunk();
  517. PhysClass * obj = NULL;
  518. PersistFactoryClass * fact = SaveLoadSystemClass::Find_Persist_Factory(cload.Cur_Chunk_ID());
  519. WWASSERT(fact != NULL);
  520. if (fact) {
  521. obj = (PhysClass *)fact->Load(cload);
  522. }
  523. cload.Close_Chunk();
  524. cload.Close_Chunk();
  525. WWASSERT(obj);
  526. /*
  527. ** Add the object to the dynamic culling system
  528. */
  529. DynamicCullingSystem->Add_Object(obj);
  530. /*
  531. ** Finish installing the object into the physics scene
  532. ** - Add it to the culling system
  533. ** - Add it to the appropriate list
  534. ** - Notify the render object that it was added to the scene
  535. */
  536. Internal_Add_Dynamic_Object(obj);
  537. obj->Release_Ref();
  538. } else {
  539. WWDEBUG_SAY(("Unhandled Chunk: 0x%x in file &s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  540. cload.Close_Chunk();
  541. }
  542. }
  543. }
  544. void PhysicsSceneClass::Save_Static_Object_States(ChunkSaveClass & csave)
  545. {
  546. RefPhysListIterator it(&StaticObjList);
  547. while (!it.Is_Done()) {
  548. if (((StaticPhysClass*)it.Peek_Obj())->Has_Dynamic_State()) {
  549. csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OBJECT_ID);
  550. uint32 id = it.Peek_Obj()->Get_ID();
  551. csave.Write(&id,sizeof(uint32));
  552. csave.End_Chunk();
  553. csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OLD_PTR);
  554. void * old_ptr = it.Peek_Obj();
  555. csave.Write(&old_ptr,sizeof(void *));
  556. csave.End_Chunk();
  557. csave.Begin_Chunk(PSCENE_DD_CHUNK_STATIC_OBJECT_STATE);
  558. ((StaticPhysClass *)it.Peek_Obj())->Save_State(csave);
  559. csave.End_Chunk();
  560. }
  561. it.Next();
  562. }
  563. }
  564. void PhysicsSceneClass::Load_Static_Object_States(ChunkLoadClass & cload)
  565. {
  566. while (cload.Open_Chunk()) {
  567. WWASSERT(cload.Cur_Chunk_ID()==PSCENE_DD_CHUNK_STATIC_OBJECT_ID);
  568. uint32 id;
  569. cload.Read(&id,sizeof(uint32));
  570. cload.Close_Chunk();
  571. StaticPhysClass * sphys = Get_Static_Object_By_ID(id);
  572. cload.Open_Chunk();
  573. WWASSERT(cload.Cur_Chunk_ID()==PSCENE_DD_CHUNK_STATIC_OLD_PTR);
  574. void * old_ptr;
  575. cload.Read(&old_ptr,sizeof(void *));
  576. SaveLoadSystemClass::Register_Pointer(old_ptr, sphys);
  577. cload.Close_Chunk();
  578. cload.Open_Chunk();
  579. WWASSERT(cload.Cur_Chunk_ID()==PSCENE_DD_CHUNK_STATIC_OBJECT_STATE);
  580. if (sphys != NULL) {
  581. sphys->Load_State(cload);
  582. sphys->Release_Ref();
  583. } else {
  584. WWDEBUG_SAY(("Unable to find static object! id = %d\r\n",id));
  585. }
  586. cload.Close_Chunk();
  587. }
  588. }
  589. void PhysicsSceneClass::Post_Load_Level_Dynamic_Data(void)
  590. {
  591. /*
  592. ** Possible TODO List:
  593. ** - Rebuild the dirty cull list?
  594. ** - Rebuild the lists of vertex processors? (tell each model that its been added?)
  595. */
  596. /*
  597. ** Re-generate the static shadows
  598. */
  599. // Generate_Static_Shadow_Projectors();
  600. // We don't necessarily have active device at this point so we can't render the shadows yet.
  601. // The shadows will be generated as soon as the device is available at the start of the game.
  602. Invalidate_Static_Shadow_Projectors();
  603. }
  604. StaticPhysClass * PhysicsSceneClass::Get_Static_Object_By_ID(uint32 id)
  605. {
  606. RefPhysListIterator it(&StaticObjList);
  607. while (!it.Is_Done()) {
  608. if (it.Peek_Obj()->Get_ID() == id) {
  609. return (StaticPhysClass *)it.Get_Obj();
  610. }
  611. it.Next();
  612. }
  613. return NULL;
  614. }