staticphys.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  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/staticphys.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 3/29/02 2:49p $*
  29. * *
  30. * $Revision:: 49 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * StaticPhysClass::StaticPhysClass -- Constructor *
  35. * StaticPhysClass::~StaticPhysClass -- Destructor *
  36. * StaticPhysClass::Init -- Initialize this object from a definition *
  37. * StaticPhysClass::Set_Vis_Sector_ID -- Sets the vis sector ID for this object *
  38. * StaticPhysClass::Set_Model -- Set the model for this static object *
  39. * StaticPhysClass::Update_Cached_Model_Parameters -- update our state *
  40. * StaticPhysClass::Render_Vis_Meshes -- renders any vis meshes in this model *
  41. * StaticPhysClass::Get_Bounding_Box -- Returns the bounding box of this object *
  42. * StaticPhysClass::Get_Transform -- Returns the transform of this object *
  43. * StaticPhysClass::Set_Transform -- Set the transform for this object *
  44. * StaticPhysClass::Is_Occluder -- Returns whether this static object is an occluder *
  45. * StaticPhysClass::Is_Model_Pre_Lit -- determines if the render object is pre-lit *
  46. * StaticPhysClass::Is_Vis_Sector -- Is_Vis_Sector *
  47. * StaticPhysClass::Update_Sun_Status -- determine if this object is in the sun *
  48. * StaticPhysClass::Get_Factory -- Returns the persist factory for StaticPhysClass *
  49. * StaticPhysClass::Save -- Save method, persistant object support *
  50. * StaticPhysClass::Load -- Load method, persistant object support *
  51. * StaticPhysClass::On_Post_Load -- Post-Load callback *
  52. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  53. #include "staticphys.h"
  54. #include "colmathaabox.h"
  55. #include "vistable.h"
  56. #include "chunkio.h"
  57. #include "assetmgr.h"
  58. #include "progcall.h"
  59. #include "matrix3.h"
  60. #include "persistfactory.h"
  61. #include "simpledefinitionfactory.h"
  62. #include "wwphysids.h"
  63. #include "wwhack.h"
  64. #include "mesh.h"
  65. #include "meshmdl.h"
  66. #include "lightexclude.h"
  67. #include <memory.h>
  68. #include "part_emt.h"
  69. #include "renegadeterrainpatch.h"
  70. #if UMBRASUPPORT
  71. #include <umbra.hpp>
  72. #include "umbrasupport.h"
  73. #endif
  74. DECLARE_FORCE_LINK(staticphys);
  75. /***********************************************************************************************
  76. **
  77. ** StaticPhysClass Implementation
  78. **
  79. ***********************************************************************************************/
  80. bool StaticPhysClass::_DisableStaticPhysSimulation = false;
  81. bool StaticPhysClass::_DisableStaticPhysRendering = false;
  82. /*
  83. ** Declare a PersistFactory for StaticPhysClasses
  84. */
  85. SimplePersistFactoryClass<StaticPhysClass,PHYSICS_CHUNKID_STATICPHYS> _StaticPhysFactory;
  86. /*
  87. ** Chunk-ID's used by StaticPhysClass
  88. */
  89. enum
  90. {
  91. STATICPHYS_CHUNK_PHYS = 14430100,
  92. STATICPHYS_CHUNK_VARIABLES,
  93. STATICPHYS_VARIABLE_VISOBJECTID = 0x00,
  94. STATICPHYS_VARIABLE_VISSECTORID,
  95. };
  96. /***********************************************************************************************
  97. * StaticPhysClass::StaticPhysClass -- Constructor *
  98. * *
  99. * INPUT: *
  100. * *
  101. * OUTPUT: *
  102. * *
  103. * WARNINGS: *
  104. * I'm initializing the VisObjectID to zero, the "always visible" object ID *
  105. * I'm initializing the VisSectorID to -1 to indicate that no table is allocated for this obj *
  106. * *
  107. * HISTORY: *
  108. * 1/10/00 gth : Created. *
  109. *=============================================================================================*/
  110. StaticPhysClass::StaticPhysClass(void) :
  111. VisSectorID(0xFFFFFFFF)
  112. {
  113. Set_Collision_Group( 15 ); // HACK? All terrain should be group 15?
  114. }
  115. /***********************************************************************************************
  116. * StaticPhysClass::~StaticPhysClass -- Destructor *
  117. * *
  118. * INPUT: *
  119. * *
  120. * OUTPUT: *
  121. * *
  122. * WARNINGS: *
  123. * *
  124. * HISTORY: *
  125. * 1/10/00 gth : Created. *
  126. *=============================================================================================*/
  127. StaticPhysClass::~StaticPhysClass(void)
  128. {
  129. }
  130. /***********************************************************************************************
  131. * StaticPhysClass::Init -- Initialize this object from a definition *
  132. * *
  133. * INPUT: *
  134. * *
  135. * OUTPUT: *
  136. * *
  137. * WARNINGS: *
  138. * *
  139. * HISTORY: *
  140. * 1/10/00 gth : Created. *
  141. *=============================================================================================*/
  142. void StaticPhysClass::Init(const StaticPhysDefClass & def)
  143. {
  144. PhysClass::Init(def);
  145. if (Model != NULL && Model->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER) {
  146. ((ParticleEmitterClass *)Model)->Start ();
  147. }
  148. }
  149. /***********************************************************************************************
  150. * StaticPhysClass::Set_Vis_Sector_ID -- Sets the vis sector ID for this object *
  151. * *
  152. * If a static object contains a VIS mesh, a vis sector ID is allocated for it. This is the *
  153. * ID of the visibility table for this object which tracks what objects are visible when the *
  154. * camera is above one of its VIS meshes. *
  155. * *
  156. * INPUT: *
  157. * *
  158. * OUTPUT: *
  159. * *
  160. * WARNINGS: *
  161. * *
  162. * HISTORY: *
  163. * 6/27/2000 gth : Created. *
  164. *=============================================================================================*/
  165. void StaticPhysClass::Set_Vis_Sector_ID(int new_id)
  166. {
  167. VisSectorID = new_id;
  168. }
  169. /***********************************************************************************************
  170. * StaticPhysClass::Set_Model -- Set the model for this static object *
  171. * *
  172. * INPUT: *
  173. * *
  174. * OUTPUT: *
  175. * *
  176. * WARNINGS: *
  177. * *
  178. * HISTORY: *
  179. * 1/10/00 gth : Created. *
  180. *=============================================================================================*/
  181. void StaticPhysClass::Set_Model(RenderObjClass * model)
  182. {
  183. // call parent class
  184. PhysClass::Set_Model(model);
  185. Update_Cached_Model_Parameters();
  186. }
  187. /***********************************************************************************************
  188. * StaticPhysClass::Update_Cached_Model_Parameters -- update our state *
  189. * *
  190. * This function must be called in three places: In the constructor, whenever the model is *
  191. * set, and in the post-load callback *
  192. * *
  193. * INPUT: *
  194. * *
  195. * OUTPUT: *
  196. * *
  197. * WARNINGS: *
  198. * *
  199. * HISTORY: *
  200. * 1/14/00 gth : Created. *
  201. *=============================================================================================*/
  202. void StaticPhysClass::Update_Cached_Model_Parameters(void)
  203. {
  204. if (Model == NULL) return;
  205. // if the model is a light-mapped mesh, we want to exclude it from the static lights
  206. Enable_Is_Pre_Lit(Is_Model_Pre_Lit());
  207. // if our model is a mesh and its in world space, enable the world-space-mesh optimizations
  208. if ((Model->Class_ID() == RenderObjClass::CLASSID_MESH) && (Get_Transform() == Matrix3D::Identity)) {
  209. Enable_Is_World_Space_Mesh(true);
  210. } else {
  211. Enable_Is_World_Space_Mesh(false);
  212. }
  213. #if (UMBRASUPPORT)
  214. // update the umbra model(s)
  215. Umbra::Model * test_model = NULL;
  216. if (Model->Class_ID() == RenderObjClass::CLASSID_MESH) {
  217. MeshClass & mesh = *((MeshClass *)Model);
  218. test_model = UmbraSupport::Create_Mesh_Model(mesh);
  219. } else {
  220. AABoxClass obj_box;
  221. Model->Get_Obj_Space_Bounding_Box(obj_box);
  222. test_model = UmbraSupport::Create_Box_Model(obj_box);
  223. }
  224. UmbraObject->setTestModel(test_model);
  225. if ((Model->Class_ID() == RenderObjClass::CLASSID_MESH) && (Is_Occluder())) {
  226. test_model->set(Umbra::Model::WRITABLE,true);
  227. UmbraObject->setWriteModel(test_model);
  228. }
  229. //UmbraObject->setCost(100000,100000,5);
  230. #endif //UMBRASUPPORT
  231. }
  232. /***********************************************************************************************
  233. * StaticPhysClass::Render_Vis_Meshes -- renders any vis meshes in this model *
  234. * *
  235. * INPUT: *
  236. * *
  237. * OUTPUT: *
  238. * *
  239. * WARNINGS: *
  240. * *
  241. * HISTORY: *
  242. * 3/17/2000 gth : Created. *
  243. *=============================================================================================*/
  244. void StaticPhysClass::Render_Vis_Meshes(RenderInfoClass & rinfo)
  245. {
  246. if (Model == NULL) return;
  247. // Note, this only works with Mesh vis sectors. Theoretically vis sectors could
  248. // be embedded in a hierarchical model as well...
  249. if (Model->Get_Collision_Type() & COLLISION_TYPE_VIS) {
  250. // Force hidden meshes to render...
  251. int is_hidden = Model->Is_Hidden();
  252. int is_anim_hidden = Model->Is_Animation_Hidden();
  253. Model->Set_Hidden(false);
  254. Model->Set_Animation_Hidden(false);
  255. Model->Render(rinfo);
  256. Model->Set_Hidden(is_hidden);
  257. Model->Set_Animation_Hidden(is_anim_hidden);
  258. }
  259. }
  260. /***********************************************************************************************
  261. * StaticPhysClass::Get_Bounding_Box -- Returns the bounding box of this object *
  262. * *
  263. * INPUT: *
  264. * *
  265. * OUTPUT: *
  266. * *
  267. * WARNINGS: *
  268. * *
  269. * HISTORY: *
  270. * 1/10/00 gth : Created. *
  271. *=============================================================================================*/
  272. const AABoxClass & StaticPhysClass::Get_Bounding_Box(void) const
  273. {
  274. assert(Model);
  275. return Model->Get_Bounding_Box();
  276. }
  277. /***********************************************************************************************
  278. * StaticPhysClass::Get_Transform -- Returns the transform of this object *
  279. * *
  280. * INPUT: *
  281. * *
  282. * OUTPUT: *
  283. * *
  284. * WARNINGS: *
  285. * *
  286. * HISTORY: *
  287. * 1/10/00 gth : Created. *
  288. *=============================================================================================*/
  289. const Matrix3D & StaticPhysClass::Get_Transform(void) const
  290. {
  291. assert(Model);
  292. return Model->Get_Transform();
  293. }
  294. /***********************************************************************************************
  295. * StaticPhysClass::Set_Transform -- Set the transform for this object *
  296. * *
  297. * INPUT: *
  298. * *
  299. * OUTPUT: *
  300. * *
  301. * WARNINGS: *
  302. * The transform should not be changed in-game! *
  303. * *
  304. * HISTORY: *
  305. * 1/10/00 gth : Created. *
  306. *=============================================================================================*/
  307. void StaticPhysClass::Set_Transform(const Matrix3D & m)
  308. {
  309. // Note: this kind of object never collides with others so we
  310. // can just warp it to the users desired position. However,
  311. // we do need to tell the scene so that it can update us in
  312. // the culling system
  313. // Note #2: In-Game, these objects should never move!!! this
  314. // feature is used in the editor. Moving one of these will
  315. // invalidate some or all of the nice pre-calculated lighting
  316. // and culling data!
  317. assert(Model);
  318. Model->Set_Transform(m);
  319. Update_Cull_Box();
  320. Invalidate_Static_Lighting_Cache();
  321. // if our model is a mesh and its in world space, enable the world-space-mesh optimizations
  322. if ((Model->Class_ID() == RenderObjClass::CLASSID_MESH) && (m == Matrix3D::Identity)) {
  323. Enable_Is_World_Space_Mesh(true);
  324. } else {
  325. Enable_Is_World_Space_Mesh(false);
  326. }
  327. }
  328. /***********************************************************************************************
  329. * StaticPhysClass::Is_Occluder -- Returns whether this static object is an occluder *
  330. * *
  331. * INPUT: *
  332. * *
  333. * OUTPUT: *
  334. * *
  335. * WARNINGS: *
  336. * *
  337. * HISTORY: *
  338. * 1/10/00 gth : Created. *
  339. *=============================================================================================*/
  340. int StaticPhysClass::Is_Occluder(void)
  341. {
  342. StaticPhysDefClass * def = Get_StaticPhysDef();
  343. if ((def != NULL) && (def->IsNonOccluder)) {
  344. return false;
  345. } else if (Model) {
  346. if (Model->Is_Translucent()) {
  347. return false;
  348. }
  349. if (Model->Class_ID() == RenderObjClass::CLASSID_DAZZLE) {
  350. return false;
  351. }
  352. }
  353. return true;
  354. }
  355. /***********************************************************************************************
  356. * StaticPhysClass::Is_Model_Pre_Lit -- determines if the render object is pre-lit *
  357. * *
  358. * INPUT: *
  359. * *
  360. * OUTPUT: *
  361. * *
  362. * WARNINGS: *
  363. * *
  364. * HISTORY: *
  365. * 4/20/2000 gth : Created. *
  366. *=============================================================================================*/
  367. bool StaticPhysClass::Is_Model_Pre_Lit(void)
  368. {
  369. // if the model is a light-mapped mesh, we want to exclude it from the static lights
  370. if (Model->Class_ID() == RenderObjClass::CLASSID_MESH) {
  371. MeshModelClass * mesh_model = ((MeshClass *)Model)->Get_Model();
  372. WWASSERT(mesh_model != NULL);
  373. if (mesh_model) {
  374. bool isprelit = (mesh_model->Get_Flag(MeshModelClass::PRELIT_MASK) != 0);
  375. mesh_model->Release_Ref();
  376. return isprelit;
  377. }
  378. } else if (Model->Class_ID() == RenderObjClass::CLASSID_RENEGADE_TERRAIN) {
  379. //return ((RenegadeTerrainPatchClass *)Model)->Is_Prelit ();
  380. }
  381. return false;
  382. }
  383. bool StaticPhysClass::Is_Model_User_Lit(void)
  384. {
  385. if (Model != NULL) {
  386. return !!(Model->Has_User_Lighting());
  387. }
  388. return false;
  389. }
  390. /***********************************************************************************************
  391. * StaticPhysClass::Is_Vis_Sector -- Is_Vis_Sector *
  392. * *
  393. * Searches the model to determine whether it defines a vis sector. I.e. any of its polys *
  394. * are marked as VIS polys *
  395. * *
  396. * INPUT: *
  397. * model - typically leave the default of NULL, this function will be called recursively *
  398. * on sub-objects *
  399. * *
  400. * OUTPUT: *
  401. * *
  402. * WARNINGS: *
  403. * *
  404. * HISTORY: *
  405. * 6/5/2000 gth : Created. *
  406. *=============================================================================================*/
  407. bool StaticPhysClass::Is_Vis_Sector(RenderObjClass * model) const
  408. {
  409. bool retval = false;
  410. /*
  411. ** If NULL was passed in, start with the render object for this StaticPhysClass.
  412. */
  413. if (model == NULL) {
  414. model = Model;
  415. }
  416. /*
  417. ** If we have a valid model to check; either recurse into its sub objects or
  418. ** check if it is a vis-collideable mesh
  419. */
  420. if (model != NULL) {
  421. /*
  422. ** Check each sub-object
  423. */
  424. int count = model->Get_Num_Sub_Objects ();
  425. for (int index = 0; (index < count) && !retval; index ++) {
  426. RenderObjClass *sub_object = model->Get_Sub_Object (index);
  427. if (sub_object != NULL) {
  428. retval |= Is_Vis_Sector(sub_object);
  429. REF_PTR_RELEASE(sub_object);
  430. }
  431. }
  432. /*
  433. ** Check the model itself
  434. */
  435. if ((model->Class_ID () == RenderObjClass::CLASSID_MESH) &&
  436. (model->Get_Collision_Type () & COLLISION_TYPE_VIS))
  437. {
  438. retval = true;
  439. }
  440. }
  441. return retval;
  442. }
  443. /***********************************************************************************************
  444. * StaticPhysClass::Update_Sun_Status -- determine if this object is in the sun *
  445. * *
  446. * This updates the internal IS_IN_THE_SUN flag. *
  447. * *
  448. * INPUT: *
  449. * *
  450. * OUTPUT: *
  451. * *
  452. * WARNINGS: *
  453. * *
  454. * HISTORY: *
  455. * 9/24/2000 gth : Created. *
  456. *=============================================================================================*/
  457. void StaticPhysClass::Update_Sun_Status(void)
  458. {
  459. /*
  460. ** Cant do sun occlusion very well for static objects...
  461. ** Just let the sun always apply?
  462. */
  463. Set_Flag(IS_IN_THE_SUN,true);
  464. }
  465. /***********************************************************************************************
  466. * StaticPhysClass::Get_Factory -- Returns the persist factory for StaticPhysClass *
  467. * *
  468. * All persistant object types need a persist factory which ties them to a unique chunk ID *
  469. * and links them into the save-load system *
  470. * *
  471. * INPUT: *
  472. * *
  473. * OUTPUT: *
  474. * *
  475. * WARNINGS: *
  476. * *
  477. * HISTORY: *
  478. * 1/10/00 gth : Created. *
  479. *=============================================================================================*/
  480. const PersistFactoryClass & StaticPhysClass::Get_Factory(void) const
  481. {
  482. return _StaticPhysFactory;
  483. }
  484. /***********************************************************************************************
  485. * StaticPhysClass::Save -- Save method, persistant object support *
  486. * *
  487. * INPUT: *
  488. * *
  489. * OUTPUT: *
  490. * *
  491. * WARNINGS: *
  492. * *
  493. * HISTORY: *
  494. * 1/10/00 gth : Created. *
  495. *=============================================================================================*/
  496. bool StaticPhysClass::Save(ChunkSaveClass &csave)
  497. {
  498. csave.Begin_Chunk(STATICPHYS_CHUNK_PHYS);
  499. PhysClass::Save(csave);
  500. csave.End_Chunk();
  501. csave.Begin_Chunk(STATICPHYS_CHUNK_VARIABLES);
  502. WRITE_MICRO_CHUNK(csave,STATICPHYS_VARIABLE_VISOBJECTID,VisObjectID);
  503. WRITE_MICRO_CHUNK(csave,STATICPHYS_VARIABLE_VISSECTORID,VisSectorID);
  504. csave.End_Chunk();
  505. return true;
  506. }
  507. /***********************************************************************************************
  508. * StaticPhysClass::Load -- Load method, persistant object support *
  509. * *
  510. * INPUT: *
  511. * *
  512. * OUTPUT: *
  513. * *
  514. * WARNINGS: *
  515. * *
  516. * HISTORY: *
  517. * 1/10/00 gth : Created. *
  518. *=============================================================================================*/
  519. bool StaticPhysClass::Load(ChunkLoadClass &cload)
  520. {
  521. while (cload.Open_Chunk()) {
  522. switch(cload.Cur_Chunk_ID())
  523. {
  524. case STATICPHYS_CHUNK_PHYS:
  525. PhysClass::Load(cload);
  526. break;
  527. case STATICPHYS_CHUNK_VARIABLES:
  528. while (cload.Open_Micro_Chunk()) {
  529. switch(cload.Cur_Micro_Chunk_ID()) {
  530. READ_MICRO_CHUNK(cload,STATICPHYS_VARIABLE_VISOBJECTID,VisObjectID);
  531. READ_MICRO_CHUNK(cload,STATICPHYS_VARIABLE_VISSECTORID,VisSectorID);
  532. }
  533. cload.Close_Micro_Chunk();
  534. }
  535. break;
  536. default:
  537. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  538. break;
  539. }
  540. cload.Close_Chunk();
  541. }
  542. SaveLoadSystemClass::Register_Post_Load_Callback(this);
  543. return true;
  544. }
  545. /***********************************************************************************************
  546. * StaticPhysClass::On_Post_Load -- Post-Load callback *
  547. * *
  548. * INPUT: *
  549. * *
  550. * OUTPUT: *
  551. * *
  552. * WARNINGS: *
  553. * *
  554. * HISTORY: *
  555. * 1/10/00 gth : Created. *
  556. *=============================================================================================*/
  557. void StaticPhysClass::On_Post_Load(void)
  558. {
  559. PhysClass::On_Post_Load();
  560. WWASSERT(Model);
  561. if (Model) {
  562. // Set our cull box but don't let the culling system re-insert us.
  563. Set_Cull_Box(Model->Get_Bounding_Box(),true);
  564. // If this is a light-mapped mesh, exclude ourselves from the static lights
  565. Update_Cached_Model_Parameters();
  566. // If this is a particle emitter, start it emitting
  567. if (Model->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER) {
  568. ((ParticleEmitterClass *)Model)->Start ();
  569. }
  570. }
  571. }
  572. float StaticPhysClass::Compute_Vis_Mesh_Ram(RenderObjClass * model)
  573. {
  574. float total = 0.0f;
  575. if (model == NULL) {
  576. model = Model;
  577. }
  578. if (model != NULL) {
  579. if (model->Class_ID() == RenderObjClass::CLASSID_MESH) {
  580. if (model->Get_Collision_Type() & COLLISION_TYPE_VIS) {
  581. MeshModelClass * mdl = ((MeshClass *)model)->Get_Model();
  582. if (mdl != NULL) {
  583. total += sizeof(MeshClass) + sizeof(MeshModelClass);
  584. total += sizeof(Vector3) * mdl->Get_Vertex_Count();
  585. total += sizeof(TriIndex) * mdl->Get_Polygon_Count();
  586. total += sizeof(PlaneClass) * mdl->Get_Polygon_Count();
  587. mdl->Release_Ref();
  588. }
  589. }
  590. } else {
  591. for (int i=0; i<model->Get_Num_Sub_Objects(); i++) {
  592. RenderObjClass * sub_obj = model->Get_Sub_Object(i);
  593. if (sub_obj != NULL) {
  594. total += Compute_Vis_Mesh_Ram(sub_obj);
  595. REF_PTR_RELEASE(sub_obj);
  596. }
  597. }
  598. }
  599. }
  600. return total;
  601. }
  602. /**************************************************************************************
  603. **
  604. ** StaticPhysDefClass Implementation
  605. **
  606. **************************************************************************************/
  607. /*
  608. ** Persist factory for StaticPhysDefClass's
  609. */
  610. SimplePersistFactoryClass<StaticPhysDefClass,PHYSICS_CHUNKID_STATICPHYSDEF> _StaticPhysDefFactory;
  611. /*
  612. ** Definition factory for StaticPhysDefClass. This makes it show up in the editor
  613. */
  614. DECLARE_DEFINITION_FACTORY(StaticPhysDefClass, CLASSID_STATICPHYSDEF, "StaticPhys") _StaticPhysDefDefFactory;
  615. /*
  616. ** Chunk ID's used by StaticPhysDefClass
  617. */
  618. enum
  619. {
  620. STATICPHYSDEF_CHUNK_PHYSDEF = 0x01070002, // (parent class)
  621. STATICPHYSDEF_CHUNK_VARIABLES,
  622. STATICPHYSDEF_VARIABLE_ISNONOCCLUDER = 0,
  623. };
  624. StaticPhysDefClass::StaticPhysDefClass(void) :
  625. IsNonOccluder(true)
  626. {
  627. EDITABLE_PARAM(StaticPhysDefClass, ParameterClass::TYPE_BOOL, IsNonOccluder);
  628. }
  629. uint32 StaticPhysDefClass::Get_Class_ID (void) const
  630. {
  631. return CLASSID_STATICPHYSDEF;
  632. }
  633. PersistClass * StaticPhysDefClass::Create(void) const
  634. {
  635. StaticPhysClass * new_obj = NEW_REF(StaticPhysClass,());
  636. new_obj->Init(*this);
  637. return new_obj;
  638. }
  639. const char * StaticPhysDefClass::Get_Type_Name(void)
  640. {
  641. return "StaticPhysDef";
  642. }
  643. bool StaticPhysDefClass::Is_Type(const char * type_name)
  644. {
  645. if (stricmp(type_name,StaticPhysDefClass::Get_Type_Name()) == 0) {
  646. return true;
  647. } else {
  648. return PhysDefClass::Is_Type(type_name);
  649. }
  650. }
  651. const PersistFactoryClass & StaticPhysDefClass::Get_Factory (void) const
  652. {
  653. return _StaticPhysDefFactory;
  654. }
  655. bool StaticPhysDefClass::Save(ChunkSaveClass &csave)
  656. {
  657. csave.Begin_Chunk(STATICPHYSDEF_CHUNK_PHYSDEF);
  658. PhysDefClass::Save(csave);
  659. csave.End_Chunk();
  660. csave.Begin_Chunk(STATICPHYSDEF_CHUNK_VARIABLES);
  661. WRITE_MICRO_CHUNK(csave,STATICPHYSDEF_VARIABLE_ISNONOCCLUDER,IsNonOccluder);
  662. csave.End_Chunk();
  663. return true;
  664. }
  665. bool StaticPhysDefClass::Load(ChunkLoadClass &cload)
  666. {
  667. while (cload.Open_Chunk()) {
  668. switch(cload.Cur_Chunk_ID()) {
  669. case STATICPHYSDEF_CHUNK_PHYSDEF:
  670. PhysDefClass::Load(cload);
  671. break;
  672. case STATICPHYSDEF_CHUNK_VARIABLES:
  673. while (cload.Open_Micro_Chunk()) {
  674. switch(cload.Cur_Micro_Chunk_ID()) {
  675. READ_MICRO_CHUNK(cload,STATICPHYSDEF_VARIABLE_ISNONOCCLUDER,IsNonOccluder);
  676. }
  677. cload.Close_Micro_Chunk();
  678. }
  679. break;
  680. default:
  681. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  682. break;
  683. }
  684. cload.Close_Chunk();
  685. }
  686. return true;
  687. }