pscene.cpp 101 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154
  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.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 3/28/02 6:48p $*
  29. * *
  30. * $Revision:: 218 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * PhysicsSceneClass::PhysicsSceneClass -- Constructor *
  35. * PhysicsSceneClass::~PhysicsSceneClass -- Destructor *
  36. * PhysicsSceneClass::Update -- Simulates the entire scene forward one timestep *
  37. * PhysicsSceneClass::Add_Dynamic_Object -- Adds a dynamic object to the scene *
  38. * PhysicsSceneClass::Internal_Add_Dynamic_Object -- internal function finishes adding a dyn *
  39. * PhysicsSceneClass::Add_Static_Object -- Adds a static object to the scene *
  40. * PhysicsSceneClass::Internal_Add_Static_Object -- internal add static object... *
  41. * PhysicsSceneClass::Add_Static_Light -- Adds a static light to the system *
  42. * PhysicsSceneClass::Internal_Add_Static_Light -- internal add static light... *
  43. * PhysicsSceneClass::Delayed_Remove_Object -- registers an object for removal *
  44. * PhysicsSceneClass::Process_Release_List -- Removes all objects in the ReleaseList *
  45. * PhysicsSceneClass::Remove_Object -- Remove an object from the scene *
  46. * PhysicsSceneClass::Remove_All -- Removes all objects from the scene *
  47. * PhysicsSceneClass::Contains -- Tests if the scene contains the given object *
  48. * PhysicsSceneClass::Get_Dynamic_Object_Iterator -- returns an iterator for the dynamic obj *
  49. * PhysicsSceneClass::Get_Static_Object_Iterator -- return an iterator for the static objs *
  50. * PhysicsSceneClass::Get_Static_Anim_Object_Iterator -- returns an iterator for static anim *
  51. * PhysicsSceneClass::Get_Static_Light_Iterator -- returns an iterator for static lights *
  52. * PhysicsSceneClass::Get_Static_Projector_Iterator -- returns an iterator for static projec *
  53. * PhysicsSceneClass::Get_Dynamic_Projector_Iterator -- returns an iterator for dynamic proj *
  54. * PhysicsSceneClass::Add_To_Dirty_Cull_List -- adds something to the "dirty cull" list *
  55. * PhysicsSceneClass::Remove_From_Dirty_Cull_List -- removes an object from the dirty cull l *
  56. * PhysicsSceneClass::Is_In_Dirty_Cull_List -- tests whether an object is in the dirty cull *
  57. * PhysicsSceneClass::Add_Render_Object -- Adds a render object to the scene *
  58. * PhysicsSceneClass::Remove_Render_Object -- removes a render object from the scene *
  59. * PhysicsSceneClass::Register -- rengisters given render object *
  60. * PhysicsSceneClass::Unregister -- Unregisters the given render object *
  61. * PhysicsSceneClass::Set_Vis_Sample_Point -- Set the current vis sample point *
  62. * PhysicsSceneClass::Pre_Render_Processing -- processing which occurs prior to rendering *
  63. * PhysicsSceneClass::Post_Render_Processing -- processing that occurs after rendering *
  64. * PhysicsSceneClass::Optimize_LODs -- Set the LOD level for each object *
  65. * PhysicsSceneClass::Render -- Render the scene *
  66. * PhysicsSceneClass::Render_Objects -- Render the visible objects *
  67. * PhysicsSceneClass::Render_Object -- Render an individual object *
  68. * PhysicsSceneClass::Render_Backface_Occluders -- Render backfaces of all occluders *
  69. * PhysicsSceneClass::Re_Partition_Static_Objects -- partition the static objects *
  70. * PhysicsSceneClass::Re_Partition_Static_Lights -- partition the static lights *
  71. * PhysicsSceneClass::Re_Partition_Dynamic_Culling_System -- partition the dynamic culling s *
  72. * PhysicsSceneClass::Re_Partition_Static_Projectors -- partition the static projectors *
  73. * PhysicsSceneClass::Update_Culling_System_Bounding_Boxes -- updates the cull systems *
  74. * PhysicsSceneClass::Get_Level_Extents -- returns the bounds of the level *
  75. * PhysicsSceneClass::Set_Polygon_Budgets -- set the budgets for the LOD system *
  76. * PhysicsSceneClass::Get_Polygon_Budgets -- returns the budgets for the LOD system *
  77. * PhysicsSceneClass::Per_Frame_Statistics_Update -- statistics tracking *
  78. * PhysicsSceneClass::Get_Statistics -- returns statistics *
  79. * PhysicsSceneClass::Find_Static_Object -- Find static object with the given ID *
  80. * PhysicsSceneClass::Shatter_Mesh -- Clips a mesh into pieces and scatters them *
  81. * PhysicsSceneClass::Verify_Culling_Systems -- Verify the culling systems *
  82. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  83. #include "pscene.h"
  84. #include "rinfo.h"
  85. #include "light.h"
  86. #include "wwdebug.h"
  87. #include "wwhack.h"
  88. #include "wwprofile.h"
  89. #include "wwmemlog.h"
  90. #include "physgridcull.h"
  91. #include "staticaabtreecull.h"
  92. #include "dynamicaabtreecull.h"
  93. #include "lightcull.h"
  94. #include "camera.h"
  95. #include "wwphystrig.h"
  96. #include "vertmaterial.h"
  97. #include "predlod.h"
  98. #include "widgets.h"
  99. #include "renderobjphys.h"
  100. #include "pathfind.h"
  101. #include "lightexclude.h"
  102. #include "physdecalsys.h"
  103. #include "quat.h"
  104. #include "shader.h"
  105. #include "lookuptable.h"
  106. #include "shattersystem.h"
  107. #include "projectile.h"
  108. #include "staticphys.h"
  109. #include "vistable.h"
  110. #include "meshmdl.h"
  111. #include "camerashakesystem.h"
  112. #include "lightenvironment.h"
  113. #include "dx8wrapper.h"
  114. #include "physresourcemgr.h"
  115. #include "phys3.h"
  116. #include "umbrasupport.h"
  117. #define STATISTICS_FRAMES 20 // number of frames to average statistics across
  118. #define SHATTER_DEBUG 0 // debugging, freeze shattered particles in place for 60sec
  119. /*
  120. ** Static members of PhysicsSceneClass
  121. */
  122. bool PhysicsSceneClass::AllowCollisionFlags[NUM_COLLISION_FLAGS];
  123. PhysicsSceneClass * PhysicsSceneClass::TheScene = NULL;
  124. /*
  125. ** Constants
  126. */
  127. const float MAX_TIMESTEP = 1.0f / 15.0f;
  128. const Vector3 MIN_GRID_CELL_SIZE(15.0f,15.0f,15.0f);
  129. const int MAX_GRID_CELL_COUNT = 8192;
  130. const float MAX_DYNAMIC_OBJ_RADIUS = 5.0f;
  131. const int DEFAULT_DYNAMIC_LOD_BUDGET = 4000;
  132. const int DEFAULT_STATIC_LOD_BUDGET = 4000;
  133. /******************************************************************************************
  134. **
  135. **
  136. ** PhysicsSceneClass Implementation
  137. **
  138. **
  139. ******************************************************************************************/
  140. /***********************************************************************************************
  141. * PhysicsSceneClass::PhysicsSceneClass -- Constructor *
  142. * *
  143. * INPUT: *
  144. * *
  145. * OUTPUT: *
  146. * *
  147. * WARNINGS: *
  148. * *
  149. * HISTORY: *
  150. * 7/7/2000 gth : Created. *
  151. *=============================================================================================*/
  152. PhysicsSceneClass::PhysicsSceneClass(void) :
  153. FrameNum(0),
  154. LastCameraPosition(0,0,0),
  155. LastValidVisId(-1),
  156. DebugDisplayEnabled(false),
  157. ProjectorDebugDisplayEnabled(false),
  158. DirtyCullDebugDisplayEnabled(false),
  159. LightingDebugDisplayEnabled(false),
  160. StaticCullingSystem(NULL),
  161. DynamicCullingSystem(NULL),
  162. StaticLightingSystem(NULL),
  163. StaticProjectorCullingSystem(NULL),
  164. DynamicProjectorCullingSystem(NULL),
  165. DynamicPolyBudget(DEFAULT_DYNAMIC_LOD_BUDGET),
  166. StaticPolyBudget(DEFAULT_STATIC_LOD_BUDGET),
  167. LightingMode(LIGHTING_MODE_CHEAP),
  168. SceneAmbientLight(0.5f,0.5f,0.5f),
  169. UseSun(false),
  170. SunLight(NULL),
  171. VisEnabled(true),
  172. VisInverted(false),
  173. VisQuickAndDirty(false),
  174. VisResetNeeded(false),
  175. VisSectorDisplayEnabled(false),
  176. VisSectorHistoryEnabled(false),
  177. VisGridDisplayMode(VIS_GRID_DISPLAY_NONE),
  178. VisSectorMissing(false),
  179. VisSectorFallbackEnabled(true),
  180. BackfaceDebugEnabled(false),
  181. VisSamplePointLocked(false),
  182. LockedVisSamplePoint(0,0,0),
  183. VisCamera(NULL),
  184. CurrentVisTable(NULL),
  185. StaticProjectorsEnabled(false),
  186. DynamicProjectorsEnabled(false),
  187. ShadowMode(SHADOW_MODE_NONE),
  188. ShadowAttenStart(25.0f),
  189. ShadowAttenEnd(40.0f),
  190. ShadowNormalIntensity(0.45f),
  191. ShadowBlobTexture(NULL),
  192. ShadowCamera(NULL),
  193. ShadowRenderContext(NULL),
  194. ShadowMaterialPass(NULL),
  195. ShadowResWidth(128),
  196. ShadowResHeight(128),
  197. DecalSystem(NULL),
  198. Pathfinder(NULL),
  199. CameraShakeSystem(NULL),
  200. HighlightMaterialPass(NULL),
  201. UpdateOnlyVisibleObjects(false),
  202. CurrentFrameNumber(0)
  203. {
  204. WWASSERT_PRINT(TheScene == NULL,"Only one instance of the PhysicsSceneClass is allowed.\r\n");
  205. WWMEMLOG(MEM_PHYSICSDATA);
  206. TheScene = this;
  207. /*
  208. ** Initialize Umbra
  209. */
  210. #if (UMBRASUPPORT)
  211. UmbraSupport::Init();
  212. #endif
  213. /*
  214. ** Clear the collision flags
  215. */
  216. memset(AllowCollisionFlags,0,NUM_COLLISION_FLAGS);
  217. /*
  218. ** Allocate culling systems
  219. */
  220. StaticCullingSystem = new StaticAABTreeCullClass(this);
  221. DynamicCullingSystem = new PhysGridCullClass(this);
  222. DynamicObjVisSystem = new DynamicAABTreeCullClass(this);
  223. StaticLightingSystem = new StaticLightCullClass;
  224. StaticProjectorCullingSystem = new TypedAABTreeCullSystemClass<TexProjectClass>;
  225. DynamicProjectorCullingSystem = new TypedGridCullSystemClass<TexProjectClass>;
  226. /*
  227. ** Allocate pathfind object
  228. */
  229. Pathfinder = new PathfindClass;
  230. /*
  231. ** Allocate the camera shake system
  232. */
  233. CameraShakeSystem = new CameraShakeSystemClass;
  234. /*
  235. ** Allocate the sun light
  236. */
  237. SunLight = NEW_REF(LightClass,(LightClass::DIRECTIONAL));
  238. Reset_Sun_Light();
  239. /*
  240. ** Initialize the debug code
  241. */
  242. WidgetSystem::Init_Debug_Widgets();
  243. /*
  244. ** Allocate decal resources
  245. */
  246. Allocate_Decal_Resources();
  247. }
  248. /***********************************************************************************************
  249. * PhysicsSceneClass::~PhysicsSceneClass -- Destructor *
  250. * *
  251. * INPUT: *
  252. * *
  253. * OUTPUT: *
  254. * *
  255. * WARNINGS: *
  256. * *
  257. * HISTORY: *
  258. * 7/7/2000 gth : Created. *
  259. *=============================================================================================*/
  260. PhysicsSceneClass::~PhysicsSceneClass(void)
  261. {
  262. Remove_All();
  263. delete StaticCullingSystem;
  264. delete DynamicCullingSystem;
  265. delete DynamicObjVisSystem;
  266. delete StaticLightingSystem;
  267. delete StaticProjectorCullingSystem;
  268. delete DynamicProjectorCullingSystem;
  269. delete Pathfinder;
  270. delete CameraShakeSystem;
  271. REF_PTR_RELEASE(SunLight);
  272. Release_Vis_Resources();
  273. Release_Projector_Resources();
  274. Release_Decal_Resources();
  275. WidgetSystem::Release_Debug_Widgets();
  276. WWASSERT(TheScene == this);
  277. TheScene = NULL;
  278. /*
  279. ** Shutdown UMBRA
  280. */
  281. #if (UMBRASUPPORT)
  282. UmbraSupport::Shutdown();
  283. #endif
  284. }
  285. /***********************************************************************************************
  286. * PhysicsSceneClass::Update -- Simulates the entire scene forward one timestep *
  287. * *
  288. * INPUT: *
  289. * *
  290. * OUTPUT: *
  291. * *
  292. * WARNINGS: *
  293. * *
  294. * HISTORY: *
  295. * 7/7/2000 gth : Created. *
  296. *=============================================================================================*/
  297. void PhysicsSceneClass::Update(float dt,int frameid)
  298. {
  299. WWPROFILE("PhysicsScene::Update");
  300. Generate_Static_Shadow_Projectors();
  301. FrameNum = frameid;
  302. if (dt == 0.0f) {
  303. return;
  304. }
  305. /*
  306. ** Timestep all of the physics objects
  307. */
  308. {
  309. WWPROFILE("Timestep");
  310. float remaining = dt;
  311. while (remaining > 0) {
  312. float step = min(remaining,MAX_TIMESTEP);
  313. /*
  314. ** Loop through each object telling each to time-step itself.
  315. */
  316. RefPhysListIterator it(&TimestepList);
  317. for (it.First(); !it.Is_Done(); it.Next()) {
  318. PhysClass* phys_obj=it.Peek_Obj();
  319. // Little optimization hack - only update vehicles that are visible (for now update all other physics
  320. // objects regardless of the visibility to avoid problems, vehicles are the most expensive anyway).
  321. // This same thing is done to Post Timestep couple lines lower.
  322. if (phys_obj->Is_Object_Simulating()) {
  323. if (!UpdateOnlyVisibleObjects ||
  324. phys_obj->Get_Last_Visible_Frame()==CurrentFrameNumber ||
  325. !phys_obj->As_VehiclePhysClass()) {
  326. phys_obj->Timestep(step);
  327. }
  328. }
  329. }
  330. remaining -= step;
  331. }
  332. }
  333. {
  334. WWPROFILE("Post Timestep");
  335. RefPhysListIterator it(&TimestepList);
  336. for (it.First(); !it.Is_Done(); it.Next()) {
  337. // if (it.Peek_Obj()->Is_Object_Simulating()) {
  338. // if (!UpdateOnlyVisibleObjects || it.Peek_Obj()->Get_Last_Visible_Frame()==CurrentFrameNumber) {
  339. PhysClass* phys_obj=it.Peek_Obj();
  340. if (phys_obj->Is_Object_Simulating()) {
  341. if (!UpdateOnlyVisibleObjects ||
  342. phys_obj->Get_Last_Visible_Frame()==CurrentFrameNumber ||
  343. !phys_obj->As_VehiclePhysClass()) {
  344. phys_obj->Post_Timestep_Process();
  345. }
  346. }
  347. }
  348. }
  349. /*
  350. ** Timestep the camera shakers
  351. */
  352. {
  353. WWPROFILE("CameraShakeSystem");
  354. CameraShakeSystem->Timestep(dt);
  355. }
  356. /*
  357. ** Timestep the material effects
  358. */
  359. {
  360. WWPROFILE("MaterialEffects");
  361. MaterialEffectClass::Timestep_All_Effects(dt);
  362. }
  363. /*
  364. ** Process pending release requests
  365. ** Put here prior to rendering to insure items won't draw too many times.
  366. */
  367. Process_Release_List();
  368. CurrentFrameNumber++;
  369. }
  370. /***********************************************************************************************
  371. * PhysicsSceneClass::Add_Dynamic_Object -- Adds a dynamic object to the scene *
  372. * *
  373. * INPUT: *
  374. * *
  375. * OUTPUT: *
  376. * *
  377. * WARNINGS: *
  378. * *
  379. * HISTORY: *
  380. * 7/7/2000 gth : Created. *
  381. *=============================================================================================*/
  382. void PhysicsSceneClass::Add_Dynamic_Object(PhysClass * newobj)
  383. {
  384. WWASSERT(newobj != NULL);
  385. WWASSERT(newobj->Peek_Model() != NULL);
  386. WWASSERT(newobj->Get_Culling_System() == NULL);
  387. // Add the object to the dynamic culling system
  388. DynamicCullingSystem->Add_Object(newobj);
  389. // Add the object to the lists in the physics scene
  390. Internal_Add_Dynamic_Object(newobj);
  391. // Clean up any cached visibility data that may have been in the object
  392. DynamicPhysClass * dynobj = newobj->As_DynamicPhysClass();
  393. WWASSERT(dynobj != NULL);
  394. if (dynobj != NULL) {
  395. dynobj->Update_Visibility_Status();
  396. }
  397. }
  398. /***********************************************************************************************
  399. * PhysicsSceneClass::Internal_Add_Dynamic_Object -- internal function finishes adding a dynam *
  400. * *
  401. * This function is called both by the loading code and the Add_Dynamic_Object function. *
  402. * *
  403. * INPUT: *
  404. * *
  405. * OUTPUT: *
  406. * *
  407. * WARNINGS: *
  408. * *
  409. * HISTORY: *
  410. * 7/7/2000 gth : Created. *
  411. *=============================================================================================*/
  412. void PhysicsSceneClass::Internal_Add_Dynamic_Object(PhysClass * newobj)
  413. {
  414. // Add the object to the appropriate lists
  415. ObjList.Add(newobj);
  416. SceneClass::Add_Render_Object(newobj->Peek_Model());
  417. if (newobj->Needs_Timestep()) {
  418. TimestepList.Add(newobj);
  419. }
  420. }
  421. /***********************************************************************************************
  422. * PhysicsSceneClass::Add_Static_Object -- Adds a static object to the scene *
  423. * *
  424. * INPUT: *
  425. * *
  426. * OUTPUT: *
  427. * *
  428. * WARNINGS: *
  429. * *
  430. * HISTORY: *
  431. * 7/7/2000 gth : Created. *
  432. *=============================================================================================*/
  433. void PhysicsSceneClass::Add_Static_Object(StaticPhysClass * newtile,int cull_node_id/*=-1*/)
  434. {
  435. WWASSERT(newtile != NULL);
  436. WWASSERT(newtile->Peek_Model() != NULL);
  437. WWASSERT(newtile->Get_Culling_System() == NULL);
  438. // Add the object to the static culling system
  439. StaticCullingSystem->Add_Object(newtile,cull_node_id);
  440. // Add the object to the lists in the physics scene
  441. Internal_Add_Static_Object(newtile);
  442. }
  443. /***********************************************************************************************
  444. * PhysicsSceneClass::Internal_Add_Static_Object -- internal add static object... *
  445. * *
  446. * This function is called by both the loading code and the Add_Static_Object function *
  447. * *
  448. * INPUT: *
  449. * *
  450. * OUTPUT: *
  451. * *
  452. * WARNINGS: *
  453. * *
  454. * HISTORY: *
  455. * 7/7/2000 gth : Created. *
  456. *=============================================================================================*/
  457. void PhysicsSceneClass::Internal_Add_Static_Object(StaticPhysClass * newtile)
  458. {
  459. // Add the object to the appropriate lists
  460. StaticObjList.Add(newtile);
  461. SceneClass::Add_Render_Object(newtile->Peek_Model());
  462. if (newtile->Needs_Timestep()) {
  463. TimestepList.Add(newtile);
  464. }
  465. if (newtile->As_StaticAnimPhysClass() != NULL) {
  466. StaticAnimList.Add(newtile);
  467. }
  468. }
  469. /***********************************************************************************************
  470. * PhysicsSceneClass::Add_Static_Light -- Adds a static light to the system *
  471. * *
  472. * INPUT: *
  473. * *
  474. * OUTPUT: *
  475. * *
  476. * WARNINGS: *
  477. * *
  478. * HISTORY: *
  479. * 7/7/2000 gth : Created. *
  480. *=============================================================================================*/
  481. void PhysicsSceneClass::Add_Static_Light(LightPhysClass * newlight,int cull_node_id/*=-1*/)
  482. {
  483. WWASSERT(newlight != NULL);
  484. WWASSERT(newlight->Peek_Model() != NULL);
  485. WWASSERT(newlight->Get_Culling_System() == NULL);
  486. // Add the light to the static light culling system
  487. StaticLightingSystem->Add_Object(newlight);
  488. // Add the light to all of the appropriate lists
  489. Internal_Add_Static_Light(newlight);
  490. }
  491. /***********************************************************************************************
  492. * PhysicsSceneClass::Internal_Add_Static_Light -- internal add static light... *
  493. * *
  494. * This function is called by both the loading code and the Add_Static_Light function *
  495. * *
  496. * *
  497. * INPUT: *
  498. * *
  499. * OUTPUT: *
  500. * *
  501. * WARNINGS: *
  502. * *
  503. * HISTORY: *
  504. * 7/7/2000 gth : Created. *
  505. *=============================================================================================*/
  506. void PhysicsSceneClass::Internal_Add_Static_Light(LightPhysClass * newlight)
  507. {
  508. // Add the object to the appropriate lists
  509. StaticLightList.Add(newlight);
  510. //(gth) hack, I don't want static lights to get registered as vertex processors.
  511. //so don't let the scene class know about them ;-) I should probably come up with
  512. //a better mechanism for this...
  513. //SceneClass::Add_Render_Object(newlight->Peek_Model());
  514. if (newlight->Needs_Timestep()) {
  515. TimestepList.Add(newlight);
  516. }
  517. }
  518. /***********************************************************************************************
  519. * PhysicsSceneClass::Delayed_Remove_Object -- registers an object for removal *
  520. * *
  521. * The object will be released by the scene at the end of the next frame. *
  522. * *
  523. * INPUT: *
  524. * *
  525. * OUTPUT: *
  526. * *
  527. * WARNINGS: *
  528. * *
  529. * HISTORY: *
  530. * 7/7/2000 gth : Created. *
  531. *=============================================================================================*/
  532. void PhysicsSceneClass::Delayed_Remove_Object(PhysClass * obj)
  533. {
  534. if (!ReleaseList.Contains(obj)) {
  535. ReleaseList.Add(obj);
  536. }
  537. }
  538. /***********************************************************************************************
  539. * PhysicsSceneClass::Process_Release_List -- Removes all objects in the ReleaseList *
  540. * *
  541. * INPUT: *
  542. * *
  543. * OUTPUT: *
  544. * *
  545. * WARNINGS: *
  546. * *
  547. * HISTORY: *
  548. * 7/7/2000 gth : Created. *
  549. *=============================================================================================*/
  550. void PhysicsSceneClass::Process_Release_List(void)
  551. {
  552. while(!ReleaseList.Is_Empty()) {
  553. PhysClass * obj = ReleaseList.Remove_Head();
  554. Remove_Object(obj);
  555. obj->Release_Ref();
  556. }
  557. }
  558. /***********************************************************************************************
  559. * PhysicsSceneClass::Remove_Object -- Remove an object from the scene *
  560. * *
  561. * INPUT: *
  562. * *
  563. * OUTPUT: *
  564. * *
  565. * WARNINGS: *
  566. * *
  567. * HISTORY: *
  568. * 7/7/2000 gth : Created. *
  569. *=============================================================================================*/
  570. void PhysicsSceneClass::Remove_Object(PhysClass * obj)
  571. {
  572. // NOTE: sometimes the game tries to 'remove' objects that havent been added...
  573. if (!Contains(obj)) return;
  574. // Assert that the object is valid
  575. WWASSERT(obj != NULL);
  576. WWASSERT(obj->Peek_Model() != NULL);
  577. // Notify the model that it is being removed from the scene
  578. SceneClass::Remove_Render_Object(obj->Peek_Model());
  579. // Notify the observer (if it has one)
  580. if (obj->Get_Observer() != NULL) {
  581. obj->Get_Observer()->Object_Removed_From_Scene(obj);
  582. }
  583. // Pull the object out of any of the "extra-processing" lists
  584. Remove_From_Dirty_Cull_List(obj);
  585. TimestepList.Remove(obj);
  586. StaticAnimList.Remove(obj);
  587. // Pull the physics object out of whatever system it is in
  588. CullSystemClass * cullsys = obj->Get_Culling_System();
  589. if (cullsys == DynamicCullingSystem) {
  590. DynamicCullingSystem->Remove_Object(obj);
  591. ObjList.Remove(obj);
  592. } else if (cullsys == StaticCullingSystem) {
  593. WWASSERT(obj->As_StaticPhysClass() != NULL);
  594. StaticCullingSystem->Remove_Object(obj->As_StaticPhysClass());
  595. StaticObjList.Remove(obj);
  596. } else if (cullsys == StaticLightingSystem) {
  597. WWASSERT(obj->As_LightPhysClass() != NULL);
  598. StaticLightingSystem->Remove_Object(obj->As_LightPhysClass());
  599. StaticLightList.Remove(obj);
  600. } else {
  601. WWASSERT(0); // should never happen!
  602. }
  603. }
  604. /***********************************************************************************************
  605. * PhysicsSceneClass::Remove_All -- Removes all objects from the scene *
  606. * *
  607. * INPUT: *
  608. * *
  609. * OUTPUT: *
  610. * *
  611. * WARNINGS: *
  612. * *
  613. * HISTORY: *
  614. * 7/7/2000 gth : Created. *
  615. *=============================================================================================*/
  616. void PhysicsSceneClass::Remove_All(void)
  617. {
  618. PhysClass * obj = ObjList.Peek_Head();
  619. while (obj) {
  620. Remove_Object(obj);
  621. obj = ObjList.Peek_Head();
  622. }
  623. StaticPhysClass * tile = (StaticPhysClass *)StaticObjList.Peek_Head();
  624. while (tile) {
  625. Remove_Object(tile);
  626. tile = (StaticPhysClass *)StaticObjList.Peek_Head();
  627. }
  628. LightPhysClass * light = (LightPhysClass *)StaticLightList.Peek_Head();
  629. while(light) {
  630. Remove_Object(light);
  631. light = (LightPhysClass *)StaticLightList.Peek_Head();
  632. }
  633. TexProjectClass * static_proj = StaticProjectorList.Peek_Head();
  634. while(static_proj) {
  635. Remove_Static_Texture_Projector(static_proj);
  636. static_proj = StaticProjectorList.Peek_Head();
  637. }
  638. TexProjectClass * dynamic_proj = DynamicProjectorList.Peek_Head();
  639. while(dynamic_proj) {
  640. Remove_Dynamic_Texture_Projector(dynamic_proj);
  641. dynamic_proj = DynamicProjectorList.Peek_Head();
  642. }
  643. Pathfinder->Reset_Sectors ();
  644. }
  645. /***********************************************************************************************
  646. * PhysicsSceneClass::Contains -- Tests if the scene contains the given object *
  647. * *
  648. * INPUT: *
  649. * *
  650. * OUTPUT: *
  651. * *
  652. * WARNINGS: *
  653. * *
  654. * HISTORY: *
  655. * 7/7/2000 gth : Created. *
  656. *=============================================================================================*/
  657. bool PhysicsSceneClass::Contains(PhysClass * obj)
  658. {
  659. if (ObjList.Is_In_List(obj)) return true;
  660. if (StaticObjList.Is_In_List(obj)) return true;
  661. if (StaticLightList.Is_In_List(obj)) return true;
  662. return false;
  663. }
  664. /***********************************************************************************************
  665. * PhysicsSceneClass::Get_Dynamic_Object_Iterator -- returns an iterator for the dynamic objec *
  666. * *
  667. * INPUT: *
  668. * *
  669. * OUTPUT: *
  670. * *
  671. * WARNINGS: *
  672. * *
  673. * HISTORY: *
  674. * 11/29/2000 gth : Created. *
  675. *=============================================================================================*/
  676. RefPhysListIterator PhysicsSceneClass::Get_Dynamic_Object_Iterator(void)
  677. {
  678. return RefPhysListIterator(&ObjList);
  679. }
  680. /***********************************************************************************************
  681. * PhysicsSceneClass::Get_Static_Object_Iterator -- return an iterator for the static objs *
  682. * *
  683. * INPUT: *
  684. * *
  685. * OUTPUT: *
  686. * *
  687. * WARNINGS: *
  688. * *
  689. * HISTORY: *
  690. * 11/29/2000 gth : Created. *
  691. *=============================================================================================*/
  692. RefPhysListIterator PhysicsSceneClass::Get_Static_Object_Iterator(void)
  693. {
  694. return RefPhysListIterator(&StaticObjList);
  695. }
  696. /***********************************************************************************************
  697. * PhysicsSceneClass::Get_Static_Anim_Object_Iterator -- returns an iterator for static anim o *
  698. * *
  699. * INPUT: *
  700. * *
  701. * OUTPUT: *
  702. * *
  703. * WARNINGS: *
  704. * *
  705. * HISTORY: *
  706. * 11/29/2000 gth : Created. *
  707. *=============================================================================================*/
  708. RefPhysListIterator PhysicsSceneClass::Get_Static_Anim_Object_Iterator(void)
  709. {
  710. return RefPhysListIterator(&StaticAnimList);
  711. }
  712. /***********************************************************************************************
  713. * PhysicsSceneClass::Get_Static_Light_Iterator -- returns an iterator for static lights *
  714. * *
  715. * INPUT: *
  716. * *
  717. * OUTPUT: *
  718. * *
  719. * WARNINGS: *
  720. * *
  721. * HISTORY: *
  722. * 11/29/2000 gth : Created. *
  723. *=============================================================================================*/
  724. RefPhysListIterator PhysicsSceneClass::Get_Static_Light_Iterator(void)
  725. {
  726. return RefPhysListIterator(&StaticLightList);
  727. }
  728. /***********************************************************************************************
  729. * PhysicsSceneClass::Get_Static_Projector_Iterator -- returns an iterator for static projecto *
  730. * *
  731. * INPUT: *
  732. * *
  733. * OUTPUT: *
  734. * *
  735. * WARNINGS: *
  736. * *
  737. * HISTORY: *
  738. * 11/29/2000 gth : Created. *
  739. *=============================================================================================*/
  740. TexProjListIterator PhysicsSceneClass::Get_Static_Projector_Iterator(void)
  741. {
  742. return TexProjListIterator(&StaticProjectorList);
  743. }
  744. /***********************************************************************************************
  745. * PhysicsSceneClass::Get_Dynamic_Projector_Iterator -- returns an iterator for dynamic projec *
  746. * *
  747. * INPUT: *
  748. * *
  749. * OUTPUT: *
  750. * *
  751. * WARNINGS: *
  752. * *
  753. * HISTORY: *
  754. * 11/29/2000 gth : Created. *
  755. *=============================================================================================*/
  756. TexProjListIterator PhysicsSceneClass::Get_Dynamic_Projector_Iterator(void)
  757. {
  758. return TexProjListIterator(&DynamicProjectorList);
  759. }
  760. /***********************************************************************************************
  761. * PhysicsSceneClass::Add_To_Dirty_Cull_List -- adds something to the "dirty cull" list *
  762. * *
  763. * objects in the dirty cull list have their visiblity and cull box re-computed each *
  764. * frame. We should try to keep things like this to a minimum. Particle buffers are *
  765. * an example of something that would end up in the "dirty cull" list *
  766. * *
  767. * INPUT: *
  768. * *
  769. * OUTPUT: *
  770. * *
  771. * WARNINGS: *
  772. * *
  773. * HISTORY: *
  774. * 11/29/2000 gth : Created. *
  775. *=============================================================================================*/
  776. void PhysicsSceneClass::Add_To_Dirty_Cull_List(PhysClass *obj)
  777. {
  778. DirtyCullList.Add (obj);
  779. }
  780. /***********************************************************************************************
  781. * PhysicsSceneClass::Remove_From_Dirty_Cull_List -- removes an object from the dirty cull lis *
  782. * *
  783. * INPUT: *
  784. * *
  785. * OUTPUT: *
  786. * *
  787. * WARNINGS: *
  788. * *
  789. * HISTORY: *
  790. * 11/29/2000 gth : Created. *
  791. *=============================================================================================*/
  792. void PhysicsSceneClass::Remove_From_Dirty_Cull_List(PhysClass *obj)
  793. {
  794. DirtyCullList.Remove (obj);
  795. }
  796. /***********************************************************************************************
  797. * PhysicsSceneClass::Is_In_Dirty_Cull_List -- tests whether an object is in the dirty cull li *
  798. * *
  799. * INPUT: *
  800. * *
  801. * OUTPUT: *
  802. * *
  803. * WARNINGS: *
  804. * *
  805. * HISTORY: *
  806. * 11/29/2000 gth : Created. *
  807. *=============================================================================================*/
  808. bool PhysicsSceneClass::Is_In_Dirty_Cull_List(PhysClass *obj)
  809. {
  810. return DirtyCullList.Contains (obj);
  811. }
  812. /***********************************************************************************************
  813. * PhysicsSceneClass::Add_Render_Object -- Adds a render object to the scene *
  814. * *
  815. * INPUT: *
  816. * *
  817. * OUTPUT: *
  818. * *
  819. * WARNINGS: *
  820. * This interface is less efficient than wrapping your render objects in some kind of physics *
  821. * object. *
  822. * *
  823. * HISTORY: *
  824. * 7/7/2000 gth : Created. *
  825. *=============================================================================================*/
  826. void PhysicsSceneClass::Add_Render_Object(RenderObjClass * obj)
  827. {
  828. WWMEMLOG(MEM_PHYSICSDATA); // Right category?
  829. // NOTE: The *ONLY* way this code should get activated is when the user
  830. // or some deep dark w3d code is directly adding and removing render objects
  831. // in the physics scene. In this case, I wrap the render objects with
  832. // RenderObjPhysClass's and set the UserData pointer to point back to this
  833. // wrapper.
  834. WWASSERT(obj != NULL);
  835. RenderObjPhysClass * cullnode = NEW_REF(RenderObjPhysClass,());
  836. cullnode->Set_Model(obj);
  837. Add_Dynamic_Object(cullnode);
  838. Add_To_Dirty_Cull_List(cullnode);
  839. //
  840. // Make sure we don't save particle buffers or lines
  841. //
  842. if ((obj->Class_ID () == RenderObjClass::CLASSID_PARTICLEBUFFER) ||
  843. (obj->Class_ID () == RenderObjClass::CLASSID_SEGLINE))
  844. {
  845. cullnode->Enable_Dont_Save(true);
  846. }
  847. cullnode->Release_Ref();
  848. SceneClass::Add_Render_Object(obj);
  849. }
  850. /***********************************************************************************************
  851. * PhysicsSceneClass::Remove_Render_Object -- removes a render object from the scene *
  852. * *
  853. * INPUT: *
  854. * *
  855. * OUTPUT: *
  856. * *
  857. * WARNINGS: *
  858. * *
  859. * HISTORY: *
  860. * 7/7/2000 gth : Created. *
  861. *=============================================================================================*/
  862. void PhysicsSceneClass::Remove_Render_Object(RenderObjClass * obj)
  863. {
  864. // NOTE: The *ONLY* way this code should get activated is when the user
  865. // or some deep dark w3d code is directly adding and removing render objects
  866. // in the physics scene. In this case, I wrap the render objects with
  867. // RenderObjPhysClass's and set the UserData pointer to point back to this
  868. // wrapper.
  869. SceneClass::Remove_Render_Object(obj);
  870. WWASSERT(obj != NULL);
  871. PhysClass * cullnode = (PhysClass *)obj->Get_User_Data();
  872. WWASSERT(cullnode != NULL);
  873. WWASSERT(cullnode->As_RenderObjPhysClass() != NULL);
  874. Remove_Object(cullnode);
  875. }
  876. /***********************************************************************************************
  877. * PhysicsSceneClass::Register -- rengisters given render object *
  878. * *
  879. * Render objects can be registered for On_Frame_Update calls, added to the vertex *
  880. * processor list, or added to the release list. *
  881. * *
  882. * INPUT: *
  883. * *
  884. * OUTPUT: *
  885. * *
  886. * WARNINGS: *
  887. * *
  888. * HISTORY: *
  889. * 7/7/2000 gth : Created. *
  890. *=============================================================================================*/
  891. void PhysicsSceneClass::Register(RenderObjClass * obj,RegType for_what)
  892. {
  893. WWASSERT(obj != NULL);
  894. switch (for_what)
  895. {
  896. case ON_FRAME_UPDATE:
  897. UpdateList.Add(obj);
  898. break;
  899. case LIGHT:
  900. VertexProcList.Add(obj);
  901. break;
  902. case RELEASE:
  903. {
  904. if (obj->Get_Container() != NULL) {
  905. obj->Get_Container()->Remove_Sub_Object(obj);
  906. } else {
  907. PhysClass * wrapper = (PhysClass *)obj->Get_User_Data();
  908. /*
  909. ** If there is no wrapper, the object isn't actually in the scene so do nothing
  910. */
  911. if (wrapper != NULL) {
  912. Delayed_Remove_Object(wrapper);
  913. }
  914. }
  915. }
  916. break;
  917. }
  918. }
  919. /***********************************************************************************************
  920. * PhysicsSceneClass::Unregister -- Unregisters the given render object *
  921. * *
  922. * INPUT: *
  923. * *
  924. * OUTPUT: *
  925. * *
  926. * WARNINGS: *
  927. * *
  928. * HISTORY: *
  929. * 7/7/2000 gth : Created. *
  930. *=============================================================================================*/
  931. void PhysicsSceneClass::Unregister(RenderObjClass * obj,RegType for_what)
  932. {
  933. WWASSERT(obj != NULL);
  934. switch (for_what)
  935. {
  936. case ON_FRAME_UPDATE:
  937. UpdateList.Remove(obj);
  938. break;
  939. case LIGHT:
  940. VertexProcList.Remove(obj);
  941. break;
  942. case RELEASE:
  943. WWASSERT_PRINT(0,("Error! Object %s tried to un-register from the release list\r\n",obj->Get_Name()));
  944. break;
  945. }
  946. }
  947. /***********************************************************************************************
  948. * PhysicsSceneClass::Pre_Render_Processing -- processing which occurs prior to rendering *
  949. * *
  950. * INPUT: *
  951. * *
  952. * OUTPUT: *
  953. * *
  954. * WARNINGS: *
  955. * *
  956. * HISTORY: *
  957. * 7/7/2000 gth : Created. *
  958. *=============================================================================================*/
  959. void PhysicsSceneClass::Pre_Render_Processing(CameraClass & camera)
  960. {
  961. WWPROFILE("Pre_Render_Processing");
  962. LastCameraPosition = camera.Get_Position();
  963. DecalSystem->Update_Decal_Fade_Distances(camera);
  964. // Do the needed 'On_Frame_Update's
  965. RefRenderObjListIterator rit(&UpdateList);
  966. for (rit.First(); !rit.Is_Done(); rit.Next()) {
  967. rit.Peek_Obj()->On_Frame_Update();
  968. }
  969. // Update culling info for all of the objects in the "dirty cull" list (these are
  970. // objects which were added to the scene as pure render objects so I don't assume
  971. // that the I have control over when their transform or bounding box is changed...)
  972. RefPhysListIterator it(&DirtyCullList);
  973. for (it.First(); !it.Is_Done(); it.Next()) {
  974. PhysClass * obj = it.Peek_Obj();
  975. obj->Update_Cull_Box();
  976. if (obj->As_DynamicPhysClass()) {
  977. obj->As_DynamicPhysClass()->Update_Visibility_Status();
  978. }
  979. if (DirtyCullDebugDisplayEnabled) {
  980. const AABoxClass & box = obj->Get_Cull_Box();
  981. if (box.Extent.Length2() > 0.0f) {
  982. DEBUG_RENDER_AABOX(obj->Get_Cull_Box(),Vector3(1,1,1),0.25f);
  983. }
  984. }
  985. }
  986. // Get the pvs
  987. VisTableClass * pvs = Get_Vis_Table_For_Rendering(camera);
  988. // Collect the visible objects
  989. bool use_umbra = false;
  990. #if (UMBRASUPPORT)
  991. use_umbra = UmbraSupport::Is_Umbra_Enabled();
  992. #endif
  993. if (!use_umbra) {
  994. // Get the lists of visible objects
  995. {
  996. WWPROFILE( "Collect Static Objs" );
  997. StaticCullingSystem->Collect_Visible_Objects(camera.Get_Frustum(),pvs,VisibleStaticObjectList,VisibleWSMeshList);
  998. }
  999. // Collect list of the visible dynamic objects
  1000. {
  1001. WWPROFILE( "Collect Dynamic Objs" );
  1002. DynamicCullingSystem->Collect_Visible_Objects(camera.Get_Frustum(),pvs,VisibleDynamicObjectList);
  1003. }
  1004. // LOD processing
  1005. Optimize_LODs(camera,&VisibleDynamicObjectList,&VisibleStaticObjectList,&VisibleWSMeshList);
  1006. // Texture projectors
  1007. Apply_Projectors(camera);
  1008. } else {
  1009. #if (UMBRASUPPORT)
  1010. RefPhysListClass vis_obj_list;
  1011. {
  1012. WWPROFILE("Umbra!");
  1013. UmbraSupport::Collect_Visible_Objects(camera,VisibleDynamicObjectList);
  1014. }
  1015. #endif
  1016. }
  1017. // release the visibility table
  1018. REF_PTR_RELEASE(pvs);
  1019. }
  1020. /***********************************************************************************************
  1021. * PhysicsSceneClass::Post_Render_Processing -- processing that occurs after rendering *
  1022. * *
  1023. * INPUT: *
  1024. * *
  1025. * OUTPUT: *
  1026. * *
  1027. * WARNINGS: *
  1028. * *
  1029. * HISTORY: *
  1030. * 7/7/2000 gth : Created. *
  1031. *=============================================================================================*/
  1032. void PhysicsSceneClass::Post_Render_Processing(void)
  1033. {
  1034. WWPROFILE("Post_Render_Processing");
  1035. // Release the visible object lists, release the shadow textures
  1036. VisibleDynamicObjectList.Reset_List();
  1037. VisibleStaticObjectList.Reset_List();
  1038. VisibleWSMeshList.Reset_List();
  1039. // Update statistics
  1040. Per_Frame_Statistics_Update();
  1041. }
  1042. /***********************************************************************************************
  1043. * PhysicsSceneClass::Optimize_LODs -- Set the LOD level for each object *
  1044. * *
  1045. * INPUT: *
  1046. * *
  1047. * OUTPUT: *
  1048. * *
  1049. * WARNINGS: *
  1050. * *
  1051. * HISTORY: *
  1052. * 7/7/2000 gth : Created. *
  1053. *=============================================================================================*/
  1054. void PhysicsSceneClass::Optimize_LODs
  1055. (
  1056. CameraClass & camera,
  1057. RefPhysListClass * dyn_objs,
  1058. RefPhysListClass * static_objs,
  1059. RefPhysListClass * static_ws_meshes
  1060. )
  1061. {
  1062. WWPROFILE("Optimize_LODs");
  1063. // process the dynamic objects
  1064. PredictiveLODOptimizerClass::Clear();
  1065. RefPhysListIterator it(dyn_objs);
  1066. for (it.First(); !it.Is_Done(); it.Next()) {
  1067. it.Peek_Obj()->Peek_Model()->Prepare_LOD(camera);
  1068. it.Peek_Obj()->Set_Last_Visible_Frame(CurrentFrameNumber);
  1069. }
  1070. PredictiveLODOptimizerClass::Optimize_LODs(DynamicPolyBudget);
  1071. // process the static objects
  1072. PredictiveLODOptimizerClass::Clear();
  1073. for (it.First(static_objs); !it.Is_Done(); it.Next()) {
  1074. it.Peek_Obj()->Peek_Model()->Prepare_LOD(camera);
  1075. it.Peek_Obj()->Set_Last_Visible_Frame(CurrentFrameNumber);
  1076. }
  1077. for (it.First(static_ws_meshes); !it.Is_Done(); it.Next()) {
  1078. it.Peek_Obj()->Peek_Model()->Prepare_LOD(camera);
  1079. it.Peek_Obj()->Set_Last_Visible_Frame(CurrentFrameNumber);
  1080. }
  1081. PredictiveLODOptimizerClass::Optimize_LODs(StaticPolyBudget);
  1082. }
  1083. /***********************************************************************************************
  1084. * PhysicsSceneClass::Render -- Render the scene *
  1085. * *
  1086. * INPUT: *
  1087. * *
  1088. * OUTPUT: *
  1089. * *
  1090. * WARNINGS: *
  1091. * *
  1092. * HISTORY: *
  1093. * 7/7/2000 gth : Created. *
  1094. *=============================================================================================*/
  1095. void PhysicsSceneClass::Customized_Render(RenderInfoClass & rinfo)
  1096. {
  1097. WWPROFILE("PhysicsSceneClass::Render");
  1098. /*
  1099. ** Render the normal models
  1100. */
  1101. Render_Objects(rinfo,&VisibleWSMeshList,&VisibleStaticObjectList,&VisibleDynamicObjectList);
  1102. /*
  1103. ** Backface Debug rendering
  1104. */
  1105. #ifdef WWDEBUG
  1106. Render_Backface_Occluders(rinfo,&VisibleWSMeshList,&VisibleStaticObjectList);
  1107. #endif
  1108. /*
  1109. ** Debug widget rendering
  1110. */
  1111. {
  1112. static LightEnvironmentClass _defaultlightenvironment;
  1113. _defaultlightenvironment.Reset(Vector3(0,0,0),Get_Ambient_Light());
  1114. _defaultlightenvironment.Add_Light(*SunLight);
  1115. rinfo.light_environment = &_defaultlightenvironment;
  1116. Render_Debug_Widgets(rinfo);
  1117. Reset_Debug_Widget_List();
  1118. rinfo.light_environment = NULL;
  1119. }
  1120. if (Pathfinder != NULL) {
  1121. Pathfinder->Render_Debug_Widgets(rinfo);
  1122. }
  1123. /*
  1124. ** Vis Sector Debugging
  1125. */
  1126. if (VisSectorDisplayEnabled || VisSectorHistoryEnabled) {
  1127. // list of previous vis sectors so we can render them
  1128. static StaticPhysClass * old_vis_sectors[3] = { NULL, NULL, NULL };
  1129. static int old_vis_index = 0;
  1130. Vector3 vis_sample_point;
  1131. Compute_Vis_Sample_Point(rinfo.Camera,&vis_sample_point);
  1132. StaticPhysClass * vis_sector = StaticCullingSystem->Find_Vis_Tile(vis_sample_point);
  1133. if (vis_sector != NULL) {
  1134. MaterialPassClass * matpass = PhysResourceMgrClass::Get_Highlight_Material_Pass();
  1135. if (matpass) {
  1136. // flush all rendering, set wireframe render mode
  1137. WW3D::Flush(rinfo);
  1138. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
  1139. // set wireframe mode and draw the vis sector
  1140. rinfo.Push_Material_Pass(matpass);
  1141. rinfo.Push_Override_Flags(RenderInfoClass::RINFO_OVERRIDE_ADDITIONAL_PASSES_ONLY);
  1142. if (VisSectorHistoryEnabled) {
  1143. // render the previous vis sectors
  1144. for (int i=0; i<3; i++) {
  1145. if (old_vis_sectors[i] != NULL) {
  1146. old_vis_sectors[i]->Render_Vis_Meshes(rinfo);
  1147. }
  1148. }
  1149. // add this one to the history if it is new
  1150. int prev_index = (old_vis_index + 2) % 3;
  1151. if (old_vis_sectors[prev_index] != vis_sector) {
  1152. old_vis_sectors[old_vis_index] = vis_sector;
  1153. old_vis_index = (old_vis_index + 1) % 3;
  1154. }
  1155. } else {
  1156. // Just draw the current vis sector
  1157. vis_sector->Render_Vis_Meshes(rinfo);
  1158. }
  1159. WW3D::Flush(rinfo);
  1160. rinfo.Pop_Material_Pass();
  1161. rinfo.Pop_Override_Flags();
  1162. // restore previous render mode
  1163. switch(Get_Polygon_Mode()) {
  1164. case POINT:
  1165. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_POINT);
  1166. break;
  1167. case LINE:
  1168. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
  1169. break;
  1170. case FILL:
  1171. DX8Wrapper::Set_DX8_Render_State(D3DRS_FILLMODE,D3DFILL_SOLID);
  1172. break;
  1173. }
  1174. // release resources
  1175. REF_PTR_RELEASE(matpass);
  1176. }
  1177. }
  1178. }
  1179. /*
  1180. ** Dynamic Vis, Virtual Occludee Debugging
  1181. */
  1182. if (VisGridDisplayMode == VIS_GRID_DISPLAY_ACTUAL_BOXES) {
  1183. VisTableClass * pvs = Get_Vis_Table_For_Rendering(rinfo.Camera);
  1184. if ((pvs != NULL) && (DynamicObjVisSystem != NULL)) {
  1185. DynamicObjVisSystem->Render_Visible_Cells(rinfo,pvs,DynamicAABTreeCullClass::DISPLAY_ACTUAL_BOXES);
  1186. }
  1187. REF_PTR_RELEASE(pvs);
  1188. }
  1189. /*
  1190. ** Light Source Debugging, render debug widgets at each light transform
  1191. */
  1192. static bool ACTIVE_ONLY = true;
  1193. if (LightingDebugDisplayEnabled) {
  1194. StaticLightingSystem->Reset_Collection();
  1195. StaticLightingSystem->Collect_Objects(rinfo.Camera.Get_Frustum());
  1196. LightPhysClass * light = StaticLightingSystem->Peek_First_Collected_Object();
  1197. while (light != NULL) {
  1198. if ((!light->Is_Disabled()) || (!ACTIVE_ONLY)) {
  1199. DEBUG_RENDER_AXES(light->Get_Transform(),Vector3(1.0f,1.0f,1.0f));
  1200. }
  1201. light = StaticLightingSystem->Peek_Next_Collected_Object(light);
  1202. }
  1203. }
  1204. }
  1205. /***********************************************************************************************
  1206. * PhysicsSceneClass::Render_Objects -- Render the visible objects *
  1207. * *
  1208. * INPUT: *
  1209. * *
  1210. * OUTPUT: *
  1211. * *
  1212. * WARNINGS: *
  1213. * *
  1214. * HISTORY: *
  1215. * 4/24/2001 gth : Created. *
  1216. *=============================================================================================*/
  1217. void PhysicsSceneClass::Render_Objects(
  1218. RenderInfoClass& rinfo,
  1219. RefPhysListClass * static_ws_list,
  1220. RefPhysListClass * static_list,
  1221. RefPhysListClass * dyn_list)
  1222. {
  1223. WWPROFILE("Render_Meshes");
  1224. RefPhysListIterator it(static_ws_list);
  1225. if (WW3D::Get_Mesh_Draw_Mode()!=WW3D::MESH_DRAW_MODE_NONE) {
  1226. if (Is_Backface_Occluder_Debug_Enabled()) {
  1227. // render the static world-space meshes
  1228. {
  1229. WWPROFILE("world-space meshes");
  1230. for (it.First(static_ws_list); !it.Is_Done(); it.Next()) {
  1231. // Only render occluders when backface debug is on
  1232. if (it.Peek_Obj()->As_StaticPhysClass()->Is_Occluder() != 0) {
  1233. Render_Object(rinfo,it.Peek_Obj());
  1234. }
  1235. }
  1236. }
  1237. // render the other static objects
  1238. {
  1239. WWPROFILE("static objects");
  1240. for (it.First(static_list); !it.Is_Done(); it.Next()) {
  1241. // Only render occluders when backface debug is on
  1242. if (it.Peek_Obj()->As_StaticPhysClass()->Is_Occluder() != 0) {
  1243. Render_Object(rinfo,it.Peek_Obj());
  1244. }
  1245. }
  1246. }
  1247. } else {
  1248. // render the static world-space meshes
  1249. {
  1250. WWPROFILE("world-space meshes");
  1251. for (it.First(static_ws_list); !it.Is_Done(); it.Next()) {
  1252. Render_Object(rinfo,it.Peek_Obj());
  1253. }
  1254. }
  1255. // render the other static objects
  1256. {
  1257. WWPROFILE("static objects");
  1258. for (it.First(static_list); !it.Is_Done(); it.Next()) {
  1259. Render_Object(rinfo,it.Peek_Obj());
  1260. }
  1261. }
  1262. }
  1263. }
  1264. // render the dynamic objects
  1265. // render dynamic objects even if the render type is "NONE"
  1266. {
  1267. WWPROFILE("dynamic objects");
  1268. for (it.First(dyn_list); !it.Is_Done(); it.Next()) {
  1269. Render_Object(rinfo,it.Peek_Obj());
  1270. }
  1271. }
  1272. }
  1273. /***********************************************************************************************
  1274. * PhysicsSceneClass::Render_Object -- Render an individual object *
  1275. * *
  1276. * This function installs the lighting environment and renders the object. *
  1277. * *
  1278. * INPUT: *
  1279. * *
  1280. * OUTPUT: *
  1281. * *
  1282. * WARNINGS: *
  1283. * *
  1284. * HISTORY: *
  1285. * 4/24/2001 gth : Created. *
  1286. *=============================================================================================*/
  1287. void PhysicsSceneClass::Render_Object(RenderInfoClass & context,PhysClass * obj)
  1288. {
  1289. if ((obj->Peek_Model() == NULL) || (obj->Is_Rendering_Disabled())) {
  1290. return;
  1291. }
  1292. /*
  1293. ** Set up the lighting environment for this object
  1294. */
  1295. bool do_lighting = ( (obj->Is_Pre_Lit() == false) &&
  1296. (obj->Peek_Model()->Is_Not_Hidden_At_All()) );
  1297. if (do_lighting) {
  1298. WWPROFILE("setup lights");
  1299. LightEnvironmentClass & light_env = *(obj->Get_Static_Lighting_Environment());
  1300. light_env.Pre_Render_Update(context.Camera.Get_Transform());
  1301. /*
  1302. ** If lighting debugging is enabled, display a vector to each light source
  1303. */
  1304. #if WWDEBUG
  1305. Vector3 pos = obj->Peek_Model()->Get_Bounding_Box().Center;
  1306. if (LightingDebugDisplayEnabled) {
  1307. if ((pos - context.Camera.Get_Position()).Length2() < 30.0f * 30.0f) {
  1308. for (int i=0; i<light_env.Get_Light_Count(); i++) {
  1309. DEBUG_RENDER_VECTOR(pos,light_env.Get_Light_Direction(i),light_env.Get_Light_Diffuse(i));
  1310. }
  1311. }
  1312. }
  1313. #endif
  1314. context.light_environment = &light_env;
  1315. } else {
  1316. static LightEnvironmentClass _emptylightenvironment;
  1317. _emptylightenvironment.Reset(Vector3(0,0,0),Vector3(1,1,1));
  1318. context.light_environment = &_emptylightenvironment;
  1319. }
  1320. /*
  1321. ** Render the object
  1322. */
  1323. {
  1324. WWPROFILE("render");
  1325. obj->Render(context);
  1326. }
  1327. /*
  1328. ** Remove the lighting environment
  1329. */
  1330. if (do_lighting) {
  1331. context.light_environment = NULL;
  1332. }
  1333. }
  1334. /***********************************************************************************************
  1335. * PhysicsSceneClass::Render_Backface_Occluders -- Render backfaces of all occluders *
  1336. * *
  1337. * INPUT: *
  1338. * *
  1339. * OUTPUT: *
  1340. * *
  1341. * WARNINGS: *
  1342. * *
  1343. * HISTORY: *
  1344. * 4/24/2001 gth : Created. *
  1345. *=============================================================================================*/
  1346. void PhysicsSceneClass::Render_Backface_Occluders
  1347. (
  1348. RenderInfoClass & context,
  1349. RefPhysListClass * static_ws_list,
  1350. RefPhysListClass * static_list
  1351. )
  1352. {
  1353. static LightEnvironmentClass lenv;
  1354. if (BackfaceDebugEnabled) {
  1355. MaterialPassClass * matpass = PhysResourceMgrClass::Get_Highlight_Material_Pass();
  1356. if (matpass != NULL) {
  1357. /*
  1358. ** Flush the system and invert the backface culling check
  1359. */
  1360. WW3D::Flush(context);
  1361. ShaderClass::Invert_Backface_Culling(true);
  1362. /*
  1363. ** Set up the render context to render everything bright green
  1364. */
  1365. ShaderClass shader = matpass->Peek_Shader();
  1366. shader.Set_Depth_Compare(ShaderClass::PASS_LESS);
  1367. matpass->Set_Shader(shader);
  1368. context.Push_Material_Pass(matpass);
  1369. context.Push_Override_Flags(RenderInfoClass::RINFO_OVERRIDE_ADDITIONAL_PASSES_ONLY);
  1370. lenv.Reset(Vector3(0,0,0),Vector3(1,1,1));
  1371. context.light_environment = &lenv;
  1372. /*
  1373. ** Render the world-space mesh that are occluders
  1374. */
  1375. RefPhysListIterator it(static_ws_list);
  1376. while (!it.Is_Done()) {
  1377. StaticPhysClass * sphys = it.Peek_Obj()->As_StaticPhysClass();
  1378. if (sphys && sphys->Is_Occluder()) {
  1379. sphys->Render(context);
  1380. }
  1381. it.Next();
  1382. }
  1383. /*
  1384. ** Render the static objects that are occluders
  1385. */
  1386. it.First(static_list);
  1387. while (!it.Is_Done()) {
  1388. StaticPhysClass * sphys = it.Peek_Obj()->As_StaticPhysClass();
  1389. if (sphys && sphys->Is_Occluder()) {
  1390. sphys->Render(context);
  1391. }
  1392. it.Next();
  1393. }
  1394. /*
  1395. ** Flush all rendering and restore the normal backface culling state
  1396. */
  1397. WW3D::Flush(context);
  1398. ShaderClass::Invert_Backface_Culling(false);
  1399. context.Pop_Material_Pass();
  1400. context.Pop_Override_Flags();
  1401. REF_PTR_RELEASE(matpass);
  1402. }
  1403. }
  1404. }
  1405. /***********************************************************************************************
  1406. * PhysicsSceneClass::Re_Partition_Static_Objects -- partition the static objects *
  1407. * *
  1408. * INPUT: *
  1409. * *
  1410. * OUTPUT: *
  1411. * *
  1412. * WARNINGS: *
  1413. * This should be done in the editor. VIS data is invalidated when you do this... *
  1414. * *
  1415. * HISTORY: *
  1416. * 7/7/2000 gth : Created. *
  1417. *=============================================================================================*/
  1418. void PhysicsSceneClass::Re_Partition_Static_Objects(void)
  1419. {
  1420. StaticCullingSystem->Re_Partition();
  1421. }
  1422. /***********************************************************************************************
  1423. * PhysicsSceneClass::Re_Partition_Static_Lights -- partition the static lights *
  1424. * *
  1425. * INPUT: *
  1426. * *
  1427. * OUTPUT: *
  1428. * *
  1429. * WARNINGS: *
  1430. * This should be done in the editor. VIS data is invalidated when you do this... *
  1431. * *
  1432. * HISTORY: *
  1433. * 7/7/2000 gth : Created. *
  1434. *=============================================================================================*/
  1435. void PhysicsSceneClass::Re_Partition_Static_Lights(void)
  1436. {
  1437. StaticLightingSystem->Re_Partition();
  1438. }
  1439. /***********************************************************************************************
  1440. * PhysicsSceneClass::Re_Partition_Dynamic_Culling_System -- partition the dynamic culling sys *
  1441. * *
  1442. * INPUT: *
  1443. * *
  1444. * OUTPUT: *
  1445. * *
  1446. * WARNINGS: *
  1447. * This should be done in the editor. VIS data is invalidated when you do this... *
  1448. * *
  1449. * HISTORY: *
  1450. * 7/7/2000 gth : Created. *
  1451. *=============================================================================================*/
  1452. void PhysicsSceneClass::Re_Partition_Dynamic_Culling_System(void)
  1453. {
  1454. Vector3 wmin,wmax;
  1455. Get_Level_Extents(wmin,wmax);
  1456. DynamicCullingSystem->Re_Partition( wmin,wmax,
  1457. MAX_DYNAMIC_OBJ_RADIUS );
  1458. DynamicObjVisSystem->Re_Partition( NULL,
  1459. wmin,wmax,
  1460. MIN_GRID_CELL_SIZE,
  1461. MAX_GRID_CELL_COUNT,
  1462. MAX_DYNAMIC_OBJ_RADIUS );
  1463. Reset_Vis();
  1464. }
  1465. /***********************************************************************************************
  1466. * PhysicsSceneClass::Re_Partition_Dynamic_Culling_System -- partition the dynamic culling sys *
  1467. * *
  1468. * INPUT: *
  1469. * *
  1470. * OUTPUT: *
  1471. * *
  1472. * WARNINGS: *
  1473. * This should be done in the editor. VIS data is invalidated when you do this... *
  1474. * *
  1475. * HISTORY: *
  1476. * 7/7/2000 gth : Created. *
  1477. *=============================================================================================*/
  1478. void PhysicsSceneClass::Re_Partition_Dynamic_Culling_System(DynamicVectorClass<AABoxClass> & virtual_occludees)
  1479. {
  1480. Vector3 wmin,wmax;
  1481. Get_Level_Extents(wmin,wmax);
  1482. DynamicCullingSystem->Re_Partition( wmin,wmax,
  1483. MAX_DYNAMIC_OBJ_RADIUS );
  1484. AABoxClass bounds(virtual_occludees[0]);
  1485. for (int i=0; i<virtual_occludees.Count(); i++) {
  1486. bounds.Add_Box(virtual_occludees[i]);
  1487. }
  1488. DynamicObjVisSystem->Re_Partition( &virtual_occludees,
  1489. bounds.Center - bounds.Extent,
  1490. bounds.Center + bounds.Extent,
  1491. MIN_GRID_CELL_SIZE,
  1492. MAX_GRID_CELL_COUNT,
  1493. MAX_DYNAMIC_OBJ_RADIUS );
  1494. Reset_Vis();
  1495. }
  1496. /***********************************************************************************************
  1497. * PhysicsSceneClass::Re_Partition_Static_Projectors -- partition the static projectors *
  1498. * *
  1499. * INPUT: *
  1500. * *
  1501. * OUTPUT: *
  1502. * *
  1503. * WARNINGS: *
  1504. * *
  1505. * HISTORY: *
  1506. * 7/7/2000 gth : Created. *
  1507. *=============================================================================================*/
  1508. void PhysicsSceneClass::Re_Partition_Static_Projectors(void)
  1509. {
  1510. StaticProjectorCullingSystem->Re_Partition();
  1511. }
  1512. /***********************************************************************************************
  1513. * PhysicsSceneClass::Update_Culling_System_Bounding_Boxes -- updates the cull systems *
  1514. * *
  1515. * This should be performed by the level editor when geometry may have changed but we do not *
  1516. * want to do a re-partition due to the loss of hierarchical VIS data. Basically, the editor *
  1517. * will call this every time it loads an LVL in case the user has changed the geometry. It *
  1518. * causes all bounding boxes in the static culling systems to be validated. *
  1519. * *
  1520. * INPUT: *
  1521. * *
  1522. * OUTPUT: *
  1523. * *
  1524. * WARNINGS: *
  1525. * *
  1526. * HISTORY: *
  1527. * 9/3/2000 gth : Created. *
  1528. *=============================================================================================*/
  1529. void PhysicsSceneClass::Update_Culling_System_Bounding_Boxes(void)
  1530. {
  1531. StaticCullingSystem->Update_Bounding_Boxes();
  1532. StaticLightingSystem->Update_Bounding_Boxes();
  1533. }
  1534. /***********************************************************************************************
  1535. * PhysicsSceneClass::Verify_Culling_Systems -- Verify the culling systems *
  1536. * *
  1537. * This function asks the culling systems to verify that all of thier bounding boxes *
  1538. * are properly constructed. I.e. they contain the objects they claim to contain, etc. *
  1539. * *
  1540. * INPUT: *
  1541. * error_report - will be filled in with a description of any errors encountered *
  1542. * *
  1543. * OUTPUT: *
  1544. * *
  1545. * WARNINGS: *
  1546. * *
  1547. * HISTORY: *
  1548. * 9/28/2000 gth : Created. *
  1549. *=============================================================================================*/
  1550. bool PhysicsSceneClass::Verify_Culling_Systems(StringClass & set_error_report)
  1551. {
  1552. return StaticCullingSystem->Verify(set_error_report);
  1553. }
  1554. /***********************************************************************************************
  1555. * PhysicsSceneClass::Get_Level_Extents -- returns the bounds of the level *
  1556. * *
  1557. * INPUT: *
  1558. * *
  1559. * OUTPUT: *
  1560. * *
  1561. * WARNINGS: *
  1562. * *
  1563. * HISTORY: *
  1564. * 7/7/2000 gth : Created. *
  1565. *=============================================================================================*/
  1566. void PhysicsSceneClass::Get_Level_Extents(Vector3 &min, Vector3 &max)
  1567. {
  1568. const AABoxClass & level_bounds = StaticCullingSystem->Get_Bounding_Box();
  1569. min = level_bounds.Center - level_bounds.Extent;
  1570. max = level_bounds.Center + level_bounds.Extent;
  1571. }
  1572. /***********************************************************************************************
  1573. * PhysicsSceneClass::Set_Polygon_Budgets -- set the budgets for the LOD system *
  1574. * *
  1575. * INPUT: *
  1576. * *
  1577. * OUTPUT: *
  1578. * *
  1579. * WARNINGS: *
  1580. * *
  1581. * HISTORY: *
  1582. * 7/7/2000 gth : Created. *
  1583. *=============================================================================================*/
  1584. void PhysicsSceneClass::Set_Polygon_Budgets(int static_count,int dynamic_count)
  1585. {
  1586. StaticPolyBudget = static_count;
  1587. DynamicPolyBudget = dynamic_count;
  1588. }
  1589. /***********************************************************************************************
  1590. * PhysicsSceneClass::Get_Polygon_Budgets -- returns the budgets for the LOD system *
  1591. * *
  1592. * INPUT: *
  1593. * *
  1594. * OUTPUT: *
  1595. * *
  1596. * WARNINGS: *
  1597. * *
  1598. * HISTORY: *
  1599. * 7/7/2000 gth : Created. *
  1600. *=============================================================================================*/
  1601. void PhysicsSceneClass::Get_Polygon_Budgets(int * static_count,int * dynamic_count)
  1602. {
  1603. *static_count = StaticPolyBudget;
  1604. *dynamic_count = DynamicPolyBudget;
  1605. }
  1606. /***********************************************************************************************
  1607. * PhysicsSceneClass::Per_Frame_Statistics_Update -- statistics tracking *
  1608. * *
  1609. * INPUT: *
  1610. * *
  1611. * OUTPUT: *
  1612. * *
  1613. * WARNINGS: *
  1614. * *
  1615. * HISTORY: *
  1616. * 7/7/2000 gth : Created. *
  1617. *=============================================================================================*/
  1618. void PhysicsSceneClass::Per_Frame_Statistics_Update(void)
  1619. {
  1620. CurrentStats.FrameCount ++;
  1621. if (CurrentStats.FrameCount >= STATISTICS_FRAMES) {
  1622. /*
  1623. ** Collect the culling system stats
  1624. */
  1625. const GridCullSystemClass::StatsStruct & dyn_stats = DynamicCullingSystem->Get_Statistics();
  1626. const AABTreeCullSystemClass::StatsStruct & static_stats = StaticCullingSystem->Get_Statistics();
  1627. const AABTreeCullSystemClass::StatsStruct & light_stats = StaticLightingSystem->Get_Statistics();
  1628. CurrentStats.CullNodeCount = dyn_stats.NodeCount + static_stats.NodeCount + light_stats.NodeCount;
  1629. CurrentStats.CullNodesAccepted = dyn_stats.NodesAccepted + static_stats.NodesAccepted + light_stats.NodesAccepted;
  1630. CurrentStats.CullNodesTriviallyAccepted = dyn_stats.NodesTriviallyAccepted + static_stats.NodesTriviallyAccepted + light_stats.NodesTriviallyAccepted;
  1631. CurrentStats.CullNodesRejected = dyn_stats.NodesRejected + static_stats.NodesRejected + light_stats.NodesRejected;
  1632. DynamicCullingSystem->Reset_Statistics();
  1633. StaticCullingSystem->Reset_Statistics();
  1634. StaticLightingSystem->Reset_Statistics();
  1635. /*
  1636. ** Copy over LastValidStats, reset
  1637. */
  1638. LastValidStats = CurrentStats;
  1639. CurrentStats.Reset();
  1640. }
  1641. }
  1642. /***********************************************************************************************
  1643. * PhysicsSceneClass::Get_Statistics -- returns statistics *
  1644. * *
  1645. * INPUT: *
  1646. * *
  1647. * OUTPUT: *
  1648. * *
  1649. * WARNINGS: *
  1650. * *
  1651. * HISTORY: *
  1652. * 7/7/2000 gth : Created. *
  1653. *=============================================================================================*/
  1654. const PhysicsSceneClass::StatsStruct & PhysicsSceneClass::Get_Statistics(void)
  1655. {
  1656. return LastValidStats;
  1657. }
  1658. /***********************************************************************************************
  1659. * PhysicsSceneClass::Find_Static_Object -- Find static object with the given ID *
  1660. * *
  1661. * INPUT: *
  1662. * *
  1663. * OUTPUT: *
  1664. * *
  1665. * WARNINGS: *
  1666. * *
  1667. * HISTORY: *
  1668. * 7/7/2000 gth : Created. *
  1669. *=============================================================================================*/
  1670. StaticPhysClass * PhysicsSceneClass::Find_Static_Object( int instance_id )
  1671. {
  1672. RefPhysListIterator it(&StaticObjList);
  1673. for (it.First(); !it.Is_Done(); it.Next()) {
  1674. if ( (int)(it.Peek_Obj()->Get_ID()) == instance_id ) {
  1675. return (StaticPhysClass*)it.Peek_Obj();
  1676. }
  1677. }
  1678. return NULL;
  1679. }
  1680. /***********************************************************************************************
  1681. * PhysicsSceneClass::Shatter_Mesh -- Clips a mesh into pieces and scatters them *
  1682. * *
  1683. * INPUT: *
  1684. * *
  1685. * OUTPUT: *
  1686. * *
  1687. * WARNINGS: *
  1688. * *
  1689. * HISTORY: *
  1690. * 7/7/2000 gth : Created. *
  1691. *=============================================================================================*/
  1692. void PhysicsSceneClass::Shatter_Mesh
  1693. (
  1694. MeshClass * mesh,
  1695. const Vector3 & impact_point,
  1696. const Vector3 & impact_normal,
  1697. const Vector3 & impact_velocity
  1698. )
  1699. {
  1700. LookupTableClass * vel_table = LookupTableMgrClass::Get_Table("ShatterVel.tbl");
  1701. LookupTableClass * avel_table = LookupTableMgrClass::Get_Table("ShatterAVel.tbl");
  1702. /*
  1703. ** Clip the mesh into fragments
  1704. */
  1705. ShatterSystem::Shatter_Mesh(mesh,impact_point,impact_normal);
  1706. /*
  1707. ** Wake up any dynamic objects in the area
  1708. */
  1709. if (mesh->Get_Collision_Type() & COLLISION_TYPE_PHYSICAL) {
  1710. AABoxClass bounds = mesh->Get_Bounding_Box();
  1711. bounds.Extent *= 1.05f;
  1712. Force_Dynamic_Objects_Awake(bounds);
  1713. }
  1714. /*
  1715. ** Disable the original mesh so that it doesn't shatter repeatedly
  1716. */
  1717. mesh->Set_Hidden(true);
  1718. mesh->Set_Collision_Type(0);
  1719. /*
  1720. ** Now create new auto-destructing projectiles for each fragment
  1721. */
  1722. for (int i=0; i<ShatterSystem::Get_Fragment_Count(); i++) {
  1723. ProjectileClass * frag = NEW_REF(ProjectileClass,());
  1724. RenderObjClass * frag_model = ShatterSystem::Peek_Fragment(i);
  1725. Matrix3D frag_tm = frag_model->Get_Transform();
  1726. frag->Set_Model(frag_model);
  1727. frag->Set_Transform(frag_tm);
  1728. frag->Set_Orientation_Mode_Tumbling();
  1729. frag->Set_Lifetime(3.0f);
  1730. frag->Set_Gravity_Multiplier(2.0f);
  1731. frag->Set_Bounce_Count(1);
  1732. /*
  1733. ** Vector from the impact to the center of the fragment is
  1734. ** used in generating the initial velocity and rotation of the fragment
  1735. */
  1736. Vector3 dc = frag_tm.Get_Translation() - impact_point;
  1737. float dclen = dc.Length();
  1738. dc /= dclen;
  1739. /*
  1740. ** Generate a suitable velocity for the fragment
  1741. */
  1742. Vector3 frag_vel = impact_velocity;
  1743. frag_vel.Normalize();
  1744. if (rand() & 0x00000100) {
  1745. frag_vel *= -1.0f;
  1746. }
  1747. frag_vel += 0.2f*dc;
  1748. frag_vel *= vel_table->Get_Value(dclen);
  1749. frag->Set_Velocity(frag_vel);
  1750. /*
  1751. ** Generate a rotation for the fragment. The axis it rotates about
  1752. ** will be in the plane of the impact, perpendicular to a vector from
  1753. ** the impact to the CM
  1754. */
  1755. Vector3 axis;
  1756. Vector3::Cross_Product(impact_velocity,dc,&axis);
  1757. frag->Set_Orientation_Mode_Tumbling(axis,avel_table->Get_Value(dclen));
  1758. /*
  1759. ** We cannot allow these object to get saved since their model was
  1760. ** procedurally generated and it will not get loaded...
  1761. */
  1762. frag->Enable_Dont_Save(true);
  1763. /*
  1764. ** Debugging, Stop the velocity, set life to infinite, move along initial velocity to offset pieces
  1765. */
  1766. #if (SHATTER_DEBUG)
  1767. Matrix3D tm = frag->Get_Transform();
  1768. Vector3 pos,vel;
  1769. tm.Get_Translation(&pos);
  1770. frag->Get_Velocity(&vel);
  1771. tm.Set_Translation(pos+vel*0.1f);
  1772. frag->Set_Transform(tm);
  1773. frag->Set_Velocity(Vector3(0,0,0));
  1774. frag->Set_Lifetime(60.0f);
  1775. frag->Set_Gravity_Multiplier(0.0f);
  1776. frag->Set_Bounce_Count(100);
  1777. frag->Set_Orientation_Mode_Fixed();
  1778. #endif
  1779. /*
  1780. ** Add the fragment to the scene
  1781. */
  1782. Add_Dynamic_Object(frag);
  1783. REF_PTR_RELEASE(frag);
  1784. }
  1785. /*
  1786. ** Done, have the shatter system release the fragments
  1787. */
  1788. ShatterSystem::Release_Fragments();
  1789. vel_table->Release_Ref();
  1790. avel_table->Release_Ref();
  1791. }
  1792. void PhysicsSceneClass::Add_Camera_Shake
  1793. (
  1794. const Vector3 & position,
  1795. float radius,
  1796. float duration,
  1797. float power
  1798. )
  1799. {
  1800. WWASSERT(CameraShakeSystem != NULL);
  1801. CameraShakeSystem->Add_Camera_Shake(position,radius,duration,power);
  1802. }
  1803. void PhysicsSceneClass::Apply_Camera_Shakes(CameraClass & camera)
  1804. {
  1805. CameraShakeSystem->Update_Camera(camera);
  1806. }
  1807. float PhysicsSceneClass::Compute_Vis_Mesh_Ram(void)
  1808. {
  1809. float total = 0.0f;
  1810. RefPhysListIterator it(&StaticObjList);
  1811. for (it.First(); !it.Is_Done(); it.Next()) {
  1812. total += ((StaticPhysClass *)it.Peek_Obj())->Compute_Vis_Mesh_Ram();
  1813. }
  1814. return total;
  1815. }
  1816. void PhysicsSceneClass::Force_Dynamic_Objects_Awake(const AABoxClass & box)
  1817. {
  1818. /*
  1819. ** Collect the objects that touch this box and wake them up.
  1820. */
  1821. NonRefPhysListClass list;
  1822. Collect_Objects(box,false,true,&list);
  1823. NonRefPhysListIterator it(&list);
  1824. while (!it.Is_Done()) {
  1825. PhysClass * obj = it.Peek_Obj();
  1826. obj->Force_Awake();
  1827. if (obj->As_Phys3Class() != NULL) {
  1828. obj->As_Phys3Class()->Invalidate_Ground_State();
  1829. }
  1830. it.Next();
  1831. }
  1832. }
  1833. /******************************************************************************************
  1834. **
  1835. **
  1836. ** PhysicsSceneClass::StatsStruct Implementation
  1837. **
  1838. **
  1839. ******************************************************************************************/
  1840. PhysicsSceneClass::StatsStruct::StatsStruct(void)
  1841. {
  1842. Reset();
  1843. }
  1844. void PhysicsSceneClass::StatsStruct::Reset(void)
  1845. {
  1846. FrameCount = 0;
  1847. CullNodeCount = 0;
  1848. CullNodesAccepted = 0;
  1849. CullNodesTriviallyAccepted = 0;
  1850. CullNodesRejected = 0;
  1851. }
  1852. /*
  1853. ** Force-Link relevant modules from WWPhys
  1854. */
  1855. void Force_Link_Modules(void)
  1856. {
  1857. FORCE_LINK(decophys);
  1858. FORCE_LINK(humanphys);
  1859. FORCE_LINK(lightphys);
  1860. FORCE_LINK(motorcycle);
  1861. FORCE_LINK(movephys);
  1862. FORCE_LINK(phys3);
  1863. FORCE_LINK(rbody);
  1864. FORCE_LINK(staticphys);
  1865. FORCE_LINK(staticanimphys);
  1866. FORCE_LINK(wheelvehicle);
  1867. FORCE_LINK(projectile);
  1868. FORCE_LINK(timeddecophys);
  1869. FORCE_LINK(trackedvehicle);
  1870. FORCE_LINK(vtolvehicle);
  1871. FORCE_LINK(waypath);
  1872. FORCE_LINK(waypoint);
  1873. FORCE_LINK(dynamicanimphys);
  1874. FORCE_LINK(shakeablestaticphys);
  1875. FORCE_LINK(RenegadeTerrainPatch);
  1876. }