animcollisionmanager.cpp 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545
  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/animcollisionmanager.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Greg_h $*
  29. * *
  30. * $Modtime:: 11/14/01 1:34p $*
  31. * *
  32. * $Revision:: 33 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass -- Constructor *
  37. * AnimCollisionManagerClass::CollideableObjClass::~CollideableObjClass -- Destructor *
  38. * AnimCollisionManagerClass::CollideableObjClass::operator = -- assignment operator *
  39. * AnimCollisionManagerClass::CollideableObjClass::Set_Collision_Object -- set collision mes *
  40. * AnimCollisionManagerClass::CollideableObjClass::Intersect_Scene -- intersection test *
  41. * AnimCollisionManagerClass::CollideableObjClass::Clear_Collision_Bits -- disables collisio *
  42. * AnimCollisionManagerClass::CollideableObjClass::Restore_Collision_Bits -- set collision b *
  43. * AnimCollisionManagerClass::AnimCollisionManagerClass -- Constructor *
  44. * AnimCollisionManagerClass::~AnimCollisionManagerClass -- Destructor *
  45. * AnimCollisionManagerClass::Set_Animation_Mode -- set the current anim mode *
  46. * AnimCollisionManagerClass::Get_Animation_Mode -- Get the current anim mode *
  47. * AnimCollisionManagerClass::Set_Animation -- Set the current animation *
  48. * AnimCollisionManagerClass::Peek_Animation -- Get the current animation *
  49. * AnimCollisionManagerClass::Set_Target_Frame -- Set the target animation frame *
  50. * AnimCollisionManagerClass::Get_Target_Frame -- Get the target animation frame *
  51. * AnimCollisionManagerClass::Set_Target_Frame_End -- Set the target frame to the end of the *
  52. * AnimCollisionManagerClass::Is_At_Target -- returns true if in TARGET mode and done animat *
  53. * AnimCollisionManagerClass::Set_Loop_Start -- Sets frame0 for an anim loop *
  54. * AnimCollisionManagerClass::Set_Loop_End -- Sets frame1 for an anim loop *
  55. * AnimCollisionManagerClass::Get_Loop_Start -- returns frame0 for an anim loop *
  56. * AnimCollisionManagerClass::Get_Loop_End -- returns frame1 for an anim loop *
  57. * AnimCollisionManagerClass::Set_Current_Frame -- Set the current frame *
  58. * AnimCollisionManagerClass::Get_Current_Frame -- Get the current frame *
  59. * AnimCollisionManagerClass::Set_Collision_Mode -- Set the current collision mode *
  60. * AnimCollisionManagerClass::Get_Collision_Mode -- Get the current collision mode *
  61. * AnimCollisionManagerClass::Init -- Init this collision manager *
  62. * AnimCollisionManagerClass::Update_Cached_Model_Parameters -- find all of the collideable *
  63. * AnimCollisionManagerClass::Is_Collision_Model -- classify a sub-object as collideable or *
  64. * AnimCollisionManagerClass::Recursive_Count_Collision_Models -- count the collideable mesh *
  65. * AnimCollisionManagerClass::Recursive_Collect_Collision_Models -- collect collideable mesh *
  66. * AnimCollisionManagerClass::Timestep -- Update the state of this object *
  67. * AnimCollisionManagerClass::Check_Collision -- Check the given collision object *
  68. * AnimCollisionManagerClass::Is_Intersecting -- intersection test *
  69. * AnimCollisionManagerClass::Push_Collided_Object -- push an object we collided with *
  70. * AnimCollisionManagerClass::Save -- save! *
  71. * AnimCollisionManagerClass::Load -- Load! *
  72. * AnimCollisionManagerClass::Revert_Animation_State -- revert to previous anim frame *
  73. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  74. #include "animcollisionmanager.h"
  75. #include "colmathaabox.h"
  76. #include "pscene.h"
  77. #include "physinttest.h"
  78. #include "movephys.h"
  79. #include "bitstream.h"
  80. #include "assetmgr.h"
  81. #include "hanim.h"
  82. #include "boxrobj.h"
  83. #include "chunkio.h"
  84. #include "wwdebug.h"
  85. #include "wwprofile.h"
  86. /*
  87. ** Set this if you want verbose logging. It will be un-set if debugging is not enabled...
  88. */
  89. #define VERBOSE_LOGGING 0
  90. #if VERBOSE_LOGGING
  91. #define VERBOSE_LOG(x) /*if (strstr(Parent.Peek_Model()->Get_Name(),"HND_ELEV03"))*/ WWDEBUG_SAY(x)
  92. #else
  93. #define VERBOSE_LOG(x)
  94. #endif
  95. /**
  96. ** PushRecordClass
  97. ** This object is used to record each object's initial state before an animated collision
  98. ** moves them. At the end of an update, if the animated object has to revert to its initial state,
  99. ** all of the objects in the "PushList" will be reverted to there original states as well.
  100. */
  101. class PushRecordClass : public AutoPoolClass<PushRecordClass,32>
  102. {
  103. public:
  104. PushRecordClass(PhysClass * obj) : Object(NULL), Next(NULL) { REF_PTR_SET(Object,obj); WWASSERT(obj); Transform = obj->Get_Transform(); }
  105. ~PushRecordClass(void) { REF_PTR_RELEASE(Object); };
  106. void Revert(void) { Object->Set_Transform(Transform); }
  107. PushRecordClass * Get_Next(void) const { return Next; }
  108. void Set_Next(PushRecordClass * next) { Next = next; }
  109. static void Add_To_List(PushRecordClass ** head, PhysClass * obj)
  110. {
  111. PushRecordClass * new_rec = new PushRecordClass(obj);
  112. new_rec->Set_Next(*head);
  113. *head = new_rec;
  114. }
  115. static void Revert_List(PushRecordClass * head)
  116. {
  117. while (head) {
  118. head->Revert();
  119. head = head->Get_Next();
  120. }
  121. }
  122. static void Delete_List(PushRecordClass * head)
  123. {
  124. while (head) {
  125. PushRecordClass * next = head->Get_Next();
  126. delete head;
  127. head = next;
  128. }
  129. }
  130. protected:
  131. PhysClass * Object;
  132. Matrix3D Transform;
  133. PushRecordClass * Next;
  134. };
  135. DEFINE_AUTO_POOL(PushRecordClass,32);
  136. /*
  137. ** Chunk ID's used by AnimCollisionManagerClass
  138. */
  139. enum
  140. {
  141. ANIMCOLLISIONMANAGER_CHUNK_VARIABLES = 0525000421,
  142. ANIMCOLLISIONMANAGER_VARIABLE_COLLISIONMODE = 0x00,
  143. ANIMCOLLISIONMANAGER_VARIABLE_ANIMATIONMODE,
  144. ANIMCOLLISIONMANAGER_VARIABLE_TARGETFRAME,
  145. ANIMCOLLISIONMANAGER_VARIABLE_CURFRAME,
  146. ANIMCOLLISIONMANAGER_VARIABLE_ANIMATIONNAME,
  147. ANIMCOLLISIONMANAGER_VARIABLE_LOOPSTART,
  148. ANIMCOLLISIONMANAGER_VARIABLE_LOOPEND,
  149. ANIMCOLLISIONMANAGER_VARIABLE_PREVFRAME,
  150. ANIMCOLLISIONMANAGER_VARIABLE_PREVANIMATIONNAME,
  151. };
  152. /********************************************************************************************
  153. **
  154. ** AnimCollisionManagerClass::CollideableObjClass Implementation
  155. **
  156. ********************************************************************************************/
  157. /***********************************************************************************************
  158. * AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass -- Constructor *
  159. * *
  160. * INPUT: *
  161. * *
  162. * OUTPUT: *
  163. * *
  164. * WARNINGS: *
  165. * *
  166. * HISTORY: *
  167. *=============================================================================================*/
  168. AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass(void) :
  169. CollisionMesh(NULL),
  170. StartTransform(1),
  171. EndTransform(1)
  172. {
  173. }
  174. /***********************************************************************************************
  175. * AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass -- Constructor *
  176. * *
  177. * INPUT: *
  178. * *
  179. * OUTPUT: *
  180. * *
  181. * WARNINGS: *
  182. * *
  183. * HISTORY: *
  184. *=============================================================================================*/
  185. AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass
  186. (
  187. RenderObjClass * collisionmesh
  188. ) :
  189. CollisionMesh(NULL),
  190. StartTransform(1),
  191. EndTransform(1)
  192. {
  193. Set_Collision_Object(collisionmesh);
  194. }
  195. /***********************************************************************************************
  196. * AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass -- Constructor *
  197. * *
  198. * INPUT: *
  199. * *
  200. * OUTPUT: *
  201. * *
  202. * WARNINGS: *
  203. * *
  204. * HISTORY: *
  205. *=============================================================================================*/
  206. AnimCollisionManagerClass::CollideableObjClass::CollideableObjClass
  207. (
  208. const CollideableObjClass & that
  209. ) :
  210. CollisionMesh(NULL),
  211. StartTransform(1),
  212. EndTransform(1)
  213. {
  214. *this = that;
  215. }
  216. /***********************************************************************************************
  217. * AnimCollisionManagerClass::CollideableObjClass::~CollideableObjClass -- Destructor *
  218. * *
  219. * INPUT: *
  220. * *
  221. * OUTPUT: *
  222. * *
  223. * WARNINGS: *
  224. * *
  225. * HISTORY: *
  226. * 8/9/2000 gth : Created. *
  227. *=============================================================================================*/
  228. AnimCollisionManagerClass::CollideableObjClass::~CollideableObjClass(void)
  229. {
  230. REF_PTR_RELEASE(CollisionMesh);
  231. }
  232. /***********************************************************************************************
  233. * AnimCollisionManagerClass::CollideableObjClass::operator = -- assignment operator *
  234. * *
  235. * INPUT: *
  236. * *
  237. * OUTPUT: *
  238. * *
  239. * WARNINGS: *
  240. * *
  241. * HISTORY: *
  242. * 8/9/2000 gth : Created. *
  243. *=============================================================================================*/
  244. AnimCollisionManagerClass::CollideableObjClass &
  245. AnimCollisionManagerClass::CollideableObjClass::operator = (const CollideableObjClass & that)
  246. {
  247. if (this != &that) {
  248. REF_PTR_SET(CollisionMesh,that.CollisionMesh);
  249. StartTransform = that.StartTransform;
  250. EndTransform = that.EndTransform;
  251. }
  252. return *this;
  253. }
  254. /***********************************************************************************************
  255. * AnimCollisionManagerClass::CollideableObjClass::Set_Collision_Object -- set collision mesh *
  256. * *
  257. * Sets the render object being tracked by this CollideableObjClass *
  258. * *
  259. * INPUT: *
  260. * *
  261. * OUTPUT: *
  262. * *
  263. * WARNINGS: *
  264. * *
  265. * HISTORY: *
  266. * 8/9/2000 gth : Created. *
  267. *=============================================================================================*/
  268. void
  269. AnimCollisionManagerClass::CollideableObjClass::Set_Collision_Object(RenderObjClass * mesh)
  270. {
  271. REF_PTR_SET(CollisionMesh,mesh);
  272. StartTransform = EndTransform = CollisionMesh->Get_Transform();
  273. }
  274. /***********************************************************************************************
  275. * AnimCollisionManagerClass::CollideableObjClass::Intersect_Scene -- intersection test *
  276. * *
  277. * INPUT: *
  278. * *
  279. * OUTPUT: *
  280. * *
  281. * WARNINGS: *
  282. * *
  283. * HISTORY: *
  284. * 8/9/2000 gth : Created. *
  285. *=============================================================================================*/
  286. void
  287. AnimCollisionManagerClass::CollideableObjClass::Intersect_Scene
  288. (
  289. int colgroup,
  290. NonRefPhysListClass * intersect_list
  291. )
  292. {
  293. if (CollisionMesh == NULL) return;
  294. PhysicsSceneClass * scene = PhysicsSceneClass::Get_Instance();
  295. #if VERBOSE_LOGGING
  296. Vector3 pos = CollisionMesh->Get_Transform().Get_Translation();
  297. WWDEBUG_SAY(("Checking obj: %s position: %10.2f, %10.2f, %10.2f\r\n",CollisionMesh->Get_Name(),pos.X,pos.Y,pos.Z));
  298. #endif
  299. switch (CollisionMesh->Class_ID()) {
  300. case RenderObjClass::CLASSID_MESH:
  301. {
  302. MeshClass * mesh = (MeshClass *)CollisionMesh;
  303. PhysMeshIntersectionTestClass test(mesh,colgroup,COLLISION_TYPE_PHYSICAL,intersect_list);
  304. test.CheckStaticObjs = false;
  305. scene->Intersection_Test(test);
  306. VERBOSE_LOG(("Mesh intersection: %d\r\n",!intersect_list->Is_Empty()));
  307. }
  308. break;
  309. case RenderObjClass::CLASSID_OBBOX:
  310. {
  311. OBBoxRenderObjClass * boxrobj = (OBBoxRenderObjClass *)CollisionMesh;
  312. PhysOBBoxIntersectionTestClass test(boxrobj->Get_Box(),colgroup,COLLISION_TYPE_PHYSICAL,intersect_list);
  313. test.CheckStaticObjs = false;
  314. scene->Intersection_Test(test);
  315. VERBOSE_LOG(("OBBox intersection: %d\r\n",!intersect_list->Is_Empty()));
  316. }
  317. break;
  318. case RenderObjClass::CLASSID_AABOX:
  319. {
  320. AABoxRenderObjClass * boxrobj = (AABoxRenderObjClass *)CollisionMesh;
  321. PhysAABoxIntersectionTestClass test(boxrobj->Get_Box(),colgroup,COLLISION_TYPE_PHYSICAL,intersect_list);
  322. test.CheckStaticObjs = false;
  323. scene->Intersection_Test(test);
  324. VERBOSE_LOG(("AABox intersection: %d\r\n",!intersect_list->Is_Empty()));
  325. }
  326. break;
  327. };
  328. }
  329. /***********************************************************************************************
  330. * AnimCollisionManagerClass::CollideableObjClass::Clear_Collision_Bits -- disables collision *
  331. * *
  332. * Disables all collision on the render object that this CollideableObjClass is managing *
  333. * *
  334. * INPUT: *
  335. * *
  336. * OUTPUT: *
  337. * *
  338. * WARNINGS: *
  339. * *
  340. * HISTORY: *
  341. * 8/9/2000 gth : Created. *
  342. *=============================================================================================*/
  343. int AnimCollisionManagerClass::CollideableObjClass::Clear_Collision_Bits(void)
  344. {
  345. int oldbits = CollisionMesh->Get_Collision_Type();
  346. CollisionMesh->Set_Collision_Type(0);
  347. return oldbits;
  348. }
  349. /***********************************************************************************************
  350. * AnimCollisionManagerClass::CollideableObjClass::Restore_Collision_Bits -- set collision bit *
  351. * *
  352. * restores the collision bits on the render object that this CollideableObjClass is managing *
  353. * *
  354. * INPUT: *
  355. * *
  356. * OUTPUT: *
  357. * *
  358. * WARNINGS: *
  359. * *
  360. * HISTORY: *
  361. * 8/9/2000 gth : Created. *
  362. *=============================================================================================*/
  363. void AnimCollisionManagerClass::CollideableObjClass::Restore_Collision_Bits(int oldbits)
  364. {
  365. CollisionMesh->Set_Collision_Type(oldbits);
  366. }
  367. /********************************************************************************************
  368. **
  369. ** AnimCollisionManagerClass Implementation
  370. **
  371. ********************************************************************************************/
  372. /***********************************************************************************************
  373. * AnimCollisionManagerClass::AnimCollisionManagerClass -- Constructor *
  374. * *
  375. * INPUT: *
  376. * *
  377. * OUTPUT: *
  378. * *
  379. * WARNINGS: *
  380. * *
  381. * HISTORY: *
  382. *=============================================================================================*/
  383. AnimCollisionManagerClass::AnimCollisionManagerClass(PhysClass & parent) :
  384. Parent(parent),
  385. AnimationMode(ANIMATE_LOOP),
  386. TargetFrame(0.0f),
  387. LoopStart(0.0f),
  388. LoopEnd(0.0f),
  389. CurAnimation(NULL),
  390. CurFrame(0.0f),
  391. PrevAnimation(NULL),
  392. PrevFrame(0.0f),
  393. CollisionMode(COLLIDE_NONE),
  394. PushList(NULL)
  395. {
  396. }
  397. /***********************************************************************************************
  398. * AnimCollisionManagerClass::~AnimCollisionManagerClass -- Destructor *
  399. * *
  400. * INPUT: *
  401. * *
  402. * OUTPUT: *
  403. * *
  404. * WARNINGS: *
  405. * *
  406. * HISTORY: *
  407. * 8/9/2000 gth : Created. *
  408. *=============================================================================================*/
  409. AnimCollisionManagerClass::~AnimCollisionManagerClass(void)
  410. {
  411. WWASSERT(PushList == NULL);
  412. REF_PTR_RELEASE(CurAnimation);
  413. REF_PTR_RELEASE(PrevAnimation);
  414. }
  415. /***********************************************************************************************
  416. * AnimCollisionManagerClass::Set_Animation_Mode -- set the current anim mode *
  417. * *
  418. * INPUT: *
  419. * *
  420. * OUTPUT: *
  421. * *
  422. * WARNINGS: *
  423. * *
  424. * HISTORY: *
  425. * 8/9/2000 gth : Created. *
  426. *=============================================================================================*/
  427. void AnimCollisionManagerClass::Set_Animation_Mode(AnimModeType mode)
  428. {
  429. AnimationMode = mode;
  430. }
  431. /***********************************************************************************************
  432. * AnimCollisionManagerClass::Get_Animation_Mode -- Get the current anim mode *
  433. * *
  434. * INPUT: *
  435. * *
  436. * OUTPUT: *
  437. * *
  438. * WARNINGS: *
  439. * *
  440. * HISTORY: *
  441. * 8/9/2000 gth : Created. *
  442. *=============================================================================================*/
  443. AnimCollisionManagerClass::AnimModeType
  444. AnimCollisionManagerClass::Get_Animation_Mode(void)
  445. {
  446. return AnimationMode;
  447. }
  448. /***********************************************************************************************
  449. * AnimCollisionManagerClass::Set_Animation -- Set the current animation *
  450. * *
  451. * INPUT: *
  452. * *
  453. * OUTPUT: *
  454. * *
  455. * WARNINGS: *
  456. * *
  457. * HISTORY: *
  458. * 8/9/2000 gth : Created. *
  459. *=============================================================================================*/
  460. void AnimCollisionManagerClass::Set_Animation(const char * anim_name)
  461. {
  462. Internal_Set_Animation(anim_name);
  463. /*
  464. ** Automatically loop this animation by default
  465. */
  466. LoopStart = 0;
  467. if (CurAnimation != NULL) {
  468. LoopEnd = TargetFrame = CurAnimation->Get_Num_Frames() - 1;
  469. } else {
  470. LoopEnd = TargetFrame = 0;
  471. }
  472. }
  473. /***********************************************************************************************
  474. * AnimCollisionManagerClass::Internal_Set_Animation -- Set the current animation pointer *
  475. * *
  476. * This function doesn't change the animation mode, target frame, or current frame *
  477. * *
  478. * INPUT: *
  479. * *
  480. * OUTPUT: *
  481. * *
  482. * WARNINGS: *
  483. * *
  484. * HISTORY: *
  485. * 7/13/2000 gth : Created. *
  486. *=============================================================================================*/
  487. void AnimCollisionManagerClass::Internal_Set_Animation(const char * anim_name)
  488. {
  489. HAnimClass * anim = WW3DAssetManager::Get_Instance()->Get_HAnim(anim_name);
  490. if ( anim == NULL && anim_name != NULL ) {
  491. WWDEBUG_SAY(( "FAILED TO FIND ANIM IN AnimCollisionManagerClass::Internal_Set_Animation(\"%s\")\n", anim_name ));
  492. }
  493. REF_PTR_SET(CurAnimation,anim);
  494. REF_PTR_RELEASE(anim);
  495. if (Parent.Peek_Model() != NULL) {
  496. Parent.Peek_Model()->Set_Animation(CurAnimation,CurFrame);
  497. }
  498. }
  499. /***********************************************************************************************
  500. * AnimCollisionManagerClass::Peek_Animation -- Get the current animation *
  501. * *
  502. * INPUT: *
  503. * *
  504. * OUTPUT: *
  505. * *
  506. * WARNINGS: *
  507. * *
  508. * HISTORY: *
  509. * 8/9/2000 gth : Created. *
  510. *=============================================================================================*/
  511. HAnimClass * AnimCollisionManagerClass::Peek_Animation(void)
  512. {
  513. return CurAnimation;
  514. }
  515. /***********************************************************************************************
  516. * AnimCollisionManagerClass::Set_Target_Frame -- Set the target animation frame *
  517. * *
  518. * INPUT: *
  519. * *
  520. * OUTPUT: *
  521. * *
  522. * WARNINGS: *
  523. * *
  524. * HISTORY: *
  525. * 8/9/2000 gth : Created. *
  526. *=============================================================================================*/
  527. void AnimCollisionManagerClass::Set_Target_Frame(float frame)
  528. {
  529. TargetFrame = frame;
  530. Parent.Enable_Is_State_Dirty(true);
  531. }
  532. /***********************************************************************************************
  533. * AnimCollisionManagerClass::Set_Target_Frame_End -- Set the target frame to the end of the c *
  534. * *
  535. * Sets the target frame to the end of the current anim *
  536. * *
  537. * INPUT: *
  538. * *
  539. * OUTPUT: *
  540. * *
  541. * WARNINGS: *
  542. * *
  543. * HISTORY: *
  544. * 9/13/2000 gth : Created. *
  545. *=============================================================================================*/
  546. void AnimCollisionManagerClass::Set_Target_Frame_End(void)
  547. {
  548. if (CurAnimation != NULL) {
  549. Set_Target_Frame(CurAnimation->Get_Num_Frames() - 1);
  550. }
  551. }
  552. /***********************************************************************************************
  553. * AnimCollisionManagerClass::Get_Target_Frame -- Get the target animation frame *
  554. * *
  555. * INPUT: *
  556. * *
  557. * OUTPUT: *
  558. * *
  559. * WARNINGS: *
  560. * *
  561. * HISTORY: *
  562. * 8/9/2000 gth : Created. *
  563. *=============================================================================================*/
  564. float AnimCollisionManagerClass::Get_Target_Frame(void)
  565. {
  566. return TargetFrame;
  567. }
  568. /***********************************************************************************************
  569. * AnimCollisionManagerClass::Is_At_Target -- returns true if in TARGET mode and done animatin *
  570. * *
  571. * INPUT: *
  572. * *
  573. * OUTPUT: *
  574. * *
  575. * WARNINGS: *
  576. * *
  577. * HISTORY: *
  578. * 9/14/2000 gth : Created. *
  579. *=============================================================================================*/
  580. bool AnimCollisionManagerClass::Is_At_Target(void)
  581. {
  582. return ((TargetFrame == CurFrame) && (AnimationMode == ANIMATE_TARGET));
  583. }
  584. /***********************************************************************************************
  585. * AnimCollisionManagerClass::Set_Loop_Start -- Sets frame0 for an anim loop *
  586. * *
  587. * INPUT: *
  588. * *
  589. * OUTPUT: *
  590. * *
  591. * WARNINGS: *
  592. * This setting is only used if you are in AnimationMode==ANIMATE_LOOP *
  593. * *
  594. * HISTORY: *
  595. * 8/29/2000 gth : Created. *
  596. *=============================================================================================*/
  597. void AnimCollisionManagerClass::Set_Loop_Start(float frame0)
  598. {
  599. LoopStart = frame0;
  600. Parent.Enable_Is_State_Dirty(true);
  601. }
  602. /***********************************************************************************************
  603. * AnimCollisionManagerClass::Set_Loop_End -- Sets frame1 for an anim loop *
  604. * *
  605. * INPUT: *
  606. * *
  607. * OUTPUT: *
  608. * *
  609. * WARNINGS: *
  610. * This setting is only used if you are in AnimationMode==ANIMATE_LOOP *
  611. * *
  612. * HISTORY: *
  613. * 8/29/2000 gth : Created. *
  614. *=============================================================================================*/
  615. void AnimCollisionManagerClass::Set_Loop_End(float frame1)
  616. {
  617. LoopEnd = frame1;
  618. Parent.Enable_Is_State_Dirty(true);
  619. }
  620. /***********************************************************************************************
  621. * AnimCollisionManagerClass::Get_Loop_Start -- returns frame0 for an anim loop *
  622. * *
  623. * INPUT: *
  624. * *
  625. * OUTPUT: *
  626. * *
  627. * WARNINGS: *
  628. * *
  629. * HISTORY: *
  630. * 8/29/2000 gth : Created. *
  631. *=============================================================================================*/
  632. float AnimCollisionManagerClass::Get_Loop_Start(void)
  633. {
  634. return LoopStart;
  635. }
  636. /***********************************************************************************************
  637. * AnimCollisionManagerClass::Get_Loop_End -- returns frame1 for an anim loop *
  638. * *
  639. * INPUT: *
  640. * *
  641. * OUTPUT: *
  642. * *
  643. * WARNINGS: *
  644. * *
  645. * HISTORY: *
  646. * 8/29/2000 gth : Created. *
  647. *=============================================================================================*/
  648. float AnimCollisionManagerClass::Get_Loop_End(void)
  649. {
  650. return LoopEnd;
  651. }
  652. /***********************************************************************************************
  653. * AnimCollisionManagerClass::Set_Current_Frame -- Set the current frame *
  654. * *
  655. * INPUT: *
  656. * *
  657. * OUTPUT: *
  658. * *
  659. * WARNINGS: *
  660. * *
  661. * HISTORY: *
  662. * 8/9/2000 gth : Created. *
  663. *=============================================================================================*/
  664. void AnimCollisionManagerClass::Set_Current_Frame(float frame)
  665. {
  666. CurFrame = frame;
  667. Parent.Enable_Is_State_Dirty(true);
  668. #if VERBOSE_LOGGING
  669. WWASSERT(!Is_Intersecting());
  670. #endif
  671. }
  672. /***********************************************************************************************
  673. * AnimCollisionManagerClass::Get_Current_Frame -- Get the current frame *
  674. * *
  675. * INPUT: *
  676. * *
  677. * OUTPUT: *
  678. * *
  679. * WARNINGS: *
  680. * *
  681. * HISTORY: *
  682. * 8/9/2000 gth : Created. *
  683. *=============================================================================================*/
  684. float AnimCollisionManagerClass::Get_Current_Frame(void)
  685. {
  686. return CurFrame;
  687. }
  688. /***********************************************************************************************
  689. * AnimCollisionManagerClass::Set_Collision_Mode -- Set the current collision mode *
  690. * *
  691. * INPUT: *
  692. * *
  693. * OUTPUT: *
  694. * *
  695. * WARNINGS: *
  696. * *
  697. * HISTORY: *
  698. * 8/9/2000 gth : Created. *
  699. *=============================================================================================*/
  700. void AnimCollisionManagerClass::Set_Collision_Mode(CollisionModeType mode)
  701. {
  702. CollisionMode = mode;
  703. }
  704. /***********************************************************************************************
  705. * AnimCollisionManagerClass::Get_Collision_Mode -- Get the current collision mode *
  706. * *
  707. * INPUT: *
  708. * *
  709. * OUTPUT: *
  710. * *
  711. * WARNINGS: *
  712. * *
  713. * HISTORY: *
  714. * 8/9/2000 gth : Created. *
  715. *=============================================================================================*/
  716. AnimCollisionManagerClass::CollisionModeType AnimCollisionManagerClass::Get_Collision_Mode(void)
  717. {
  718. return CollisionMode;
  719. }
  720. /***********************************************************************************************
  721. * AnimCollisionManagerClass::Init -- Init this collision manager *
  722. * *
  723. * INPUT: *
  724. * *
  725. * OUTPUT: *
  726. * *
  727. * WARNINGS: *
  728. * *
  729. * HISTORY: *
  730. * 8/9/2000 gth : Created. *
  731. *=============================================================================================*/
  732. void AnimCollisionManagerClass::Init(const AnimCollisionManagerDefClass & def)
  733. {
  734. /*
  735. ** Set the collision and animation mode
  736. */
  737. CollisionMode = (CollisionModeType)def.CollisionMode;
  738. AnimationMode = (AnimModeType)def.AnimationMode;
  739. /*
  740. ** Plug in the animation
  741. */
  742. if (Parent.Peek_Model()) {
  743. Set_Current_Frame(0.0f);
  744. /*
  745. ** Get the name of the animation from the definition
  746. */
  747. StringClass anim_name = def.AnimationName;
  748. /*
  749. ** If the user didn't specify an animation name, then
  750. ** build an animation name from the model name.
  751. */
  752. if (anim_name.Is_Empty ()) {
  753. StringClass model_name(Parent.Peek_Model()->Get_Name(),true);
  754. anim_name = model_name;
  755. anim_name+=".";
  756. anim_name+=model_name;
  757. }
  758. Set_Animation(anim_name);
  759. }
  760. }
  761. /***********************************************************************************************
  762. * AnimCollisionManagerClass::Update_Cached_Model_Parameters -- find all of the collideable me *
  763. * *
  764. * This function mainly finds all of the animating collideable meshes. *
  765. * *
  766. * INPUT: *
  767. * *
  768. * OUTPUT: *
  769. * *
  770. * WARNINGS: *
  771. * *
  772. * HISTORY: *
  773. * 8/9/2000 gth : Created. *
  774. *=============================================================================================*/
  775. void AnimCollisionManagerClass::Update_Cached_Model_Parameters(void)
  776. {
  777. /*
  778. ** Build the array of collideable animated meshes
  779. */
  780. int count = Recursive_Count_Collision_Models(Parent.Peek_Model());
  781. CollisionMeshes.Delete_All();
  782. CollisionMeshes.Resize(count);
  783. Recursive_Collect_Collision_Models(Parent.Peek_Model());
  784. }
  785. /***********************************************************************************************
  786. * AnimCollisionManagerClass::Is_Collision_Model -- classify a sub-object as collideable or no *
  787. * *
  788. * A sub object needs a collision object if it is attached to a bone other than the root *
  789. * and it is collideable. *
  790. * *
  791. * INPUT: *
  792. * *
  793. * OUTPUT: *
  794. * *
  795. * WARNINGS: *
  796. * *
  797. * HISTORY: *
  798. * 8/9/2000 gth : Created. *
  799. *=============================================================================================*/
  800. bool AnimCollisionManagerClass::Is_Collision_Model(RenderObjClass * subobj)
  801. {
  802. /*
  803. ** If this sub-object is collideable and it is not attached to the RootTransform (0)
  804. ** then it is considered an animated collideable mesh.
  805. */
  806. return ( (subobj->Get_Collision_Type() & COLLISION_TYPE_PHYSICAL) &&
  807. (subobj->Get_Container() != NULL) &&
  808. (subobj->Get_Container()->Get_Sub_Object_Bone_Index(subobj) != 0) );
  809. }
  810. /***********************************************************************************************
  811. * AnimCollisionManagerClass::Recursive_Count_Collision_Models -- count the collideable meshes *
  812. * *
  813. * INPUT: *
  814. * *
  815. * OUTPUT: *
  816. * *
  817. * WARNINGS: *
  818. * *
  819. * HISTORY: *
  820. * 8/9/2000 gth : Created. *
  821. *=============================================================================================*/
  822. int AnimCollisionManagerClass::Recursive_Count_Collision_Models(RenderObjClass * model)
  823. {
  824. int count = 0;
  825. if (model == NULL) {
  826. return 0;
  827. }
  828. for (int i=0; i<model->Get_Num_Sub_Objects(); i++) {
  829. RenderObjClass * subobj = model->Get_Sub_Object(i);
  830. if (subobj->Get_Num_Sub_Objects() > 0) {
  831. count += Recursive_Count_Collision_Models(subobj); // recurse
  832. } else {
  833. if (Is_Collision_Model(model)) {
  834. count++;
  835. }
  836. }
  837. subobj->Release_Ref();
  838. }
  839. return count;
  840. }
  841. /***********************************************************************************************
  842. * AnimCollisionManagerClass::Recursive_Collect_Collision_Models -- collect collideable meshes *
  843. * *
  844. * INPUT: *
  845. * *
  846. * OUTPUT: *
  847. * *
  848. * WARNINGS: *
  849. * *
  850. * HISTORY: *
  851. * 8/9/2000 gth : Created. *
  852. *=============================================================================================*/
  853. void AnimCollisionManagerClass::Recursive_Collect_Collision_Models(RenderObjClass * model)
  854. {
  855. if (model == NULL) {
  856. return;
  857. }
  858. for (int i=0; i<model->Get_Num_Sub_Objects(); i++) {
  859. RenderObjClass * subobj = model->Get_Sub_Object(i);
  860. if (subobj->Get_Num_Sub_Objects() > 0) {
  861. Recursive_Collect_Collision_Models(subobj); // recurse
  862. } else {
  863. /*
  864. ** If this sub-object is collideable and it is not attached to the RootTransform (0)
  865. ** then it is a candidate for being a collideable object
  866. */
  867. if (Is_Collision_Model(subobj)) {
  868. /*
  869. ** Add this collideable mesh to our array of collision meshes
  870. */
  871. CollideableObjClass colmesh(subobj);
  872. CollisionMeshes.Add(colmesh);
  873. }
  874. }
  875. subobj->Release_Ref();
  876. }
  877. }
  878. /***********************************************************************************************
  879. * AnimCollisionManagerClass::Timestep -- Update the state of this object *
  880. * *
  881. * INPUT: *
  882. * *
  883. * OUTPUT: *
  884. * *
  885. * WARNINGS: *
  886. * *
  887. * HISTORY: *
  888. * 8/9/2000 gth : Created. *
  889. *=============================================================================================*/
  890. bool AnimCollisionManagerClass::Timestep(float dt)
  891. {
  892. WWPROFILE("AnimColMgr::Timestep");
  893. VERBOSE_LOG(("\r\nTimestep for %s - begin\r\n",Parent.Peek_Model()->Get_Name()));
  894. bool object_animated = false;
  895. /*
  896. ** In the case where we're not going to do anything bail out immediately!
  897. */
  898. if ((CurFrame == PrevFrame) && (CurAnimation == PrevAnimation)) {
  899. if (AnimationMode == ANIMATE_MANUAL) {
  900. return false;
  901. }
  902. if ((AnimationMode == ANIMATE_TARGET) && (CurFrame == TargetFrame)) {
  903. return false;
  904. }
  905. }
  906. /*
  907. ** Store the collision transform prior to updating the animation
  908. */
  909. if (CollisionMode != COLLIDE_NONE) {
  910. for (int i=0; i<CollisionMeshes.Count(); i++) {
  911. CollisionMeshes[i].Cache_Start_Transform();
  912. }
  913. }
  914. #if VERBOSE_LOGGING
  915. bool started_intersecting = false;
  916. if (CollisionMode != COLLIDE_NONE) {
  917. started_intersecting = Is_Intersecting();
  918. WWDEBUG_SAY(("Checking started_intersecting: %d\r\n",started_intersecting));
  919. }
  920. #endif
  921. /*
  922. ** move animation forward
  923. */
  924. if (CurAnimation != NULL) {
  925. switch (AnimationMode) {
  926. case ANIMATE_LOOP:
  927. CurFrame += CurAnimation->Get_Frame_Rate() * dt;
  928. if (CurFrame >= LoopEnd) {
  929. CurFrame -= (LoopEnd - LoopStart);
  930. }
  931. break;
  932. case ANIMATE_TARGET:
  933. if (CurFrame < TargetFrame) {
  934. CurFrame += CurAnimation->Get_Frame_Rate() * dt;
  935. // if we overshoot targetframe, snap to targetframe
  936. if (CurFrame >= TargetFrame) {
  937. CurFrame = TargetFrame;
  938. }
  939. } else if (CurFrame > TargetFrame) {
  940. CurFrame -= CurAnimation->Get_Frame_Rate() * dt;
  941. // if we overshoot targetframe, snap to targetframe
  942. if (CurFrame <= TargetFrame) {
  943. CurFrame = TargetFrame;
  944. }
  945. }
  946. break;
  947. case ANIMATE_MANUAL:
  948. break;
  949. default:
  950. WWASSERT_PRINT(0,("Invalid Animation Mode!\n"));
  951. }
  952. VERBOSE_LOG(("Cur-Frame: %f Target-Frame: %f\r\n",CurFrame,TargetFrame));
  953. Parent.Peek_Model()->Set_Animation(CurAnimation,CurFrame);
  954. }
  955. /*
  956. ** Check for collisions.
  957. ** - cache a copy of the ending transform for each collideable object
  958. ** - revert all collideable objects back to their start transform
  959. ** - for each object:
  960. ** - install its ending transform and check for collision.
  961. ** - if collided, compute the movement vector and push objects.
  962. ** - if unable to push objects out of the way, set the revert flag and exit
  963. */
  964. if ((CurAnimation != PrevAnimation) || (CurFrame != PrevFrame)) {
  965. /*
  966. ** Add our riders to our push list
  967. */
  968. object_animated = true;
  969. bool intersecting = false;
  970. if (CollisionMode != COLLIDE_NONE) {
  971. int ci;
  972. /*
  973. ** Save the transform as the "ending transform"
  974. ** and roll back to the starting transform
  975. */
  976. for (ci=0; ci<CollisionMeshes.Count(); ci++) {
  977. CollisionMeshes[ci].Cache_End_Transform();
  978. CollisionMeshes[ci].Install_Start_Transform();
  979. }
  980. /*
  981. ** Move this mesh forward to the End Transform
  982. ** and see if it collides with anything
  983. */
  984. for (ci=0; (ci<CollisionMeshes.Count()) && (!intersecting); ci++) {
  985. CollisionMeshes[ci].Install_End_Transform();
  986. intersecting |= Check_Collision(CollisionMeshes[ci]);
  987. }
  988. /*
  989. ** If we ended up intersecting, then we have to revert
  990. */
  991. if (intersecting) {
  992. Revert_Animation_State();
  993. object_animated = false;
  994. }
  995. #if VERBOSE_LOGGING
  996. WWDEBUG_SAY(("checking is_now_intersecting\r\n"));
  997. bool is_now_intersecting = Is_Intersecting();
  998. if ( (started_intersecting == false) && (is_now_intersecting == true)) {
  999. WWDEBUG_SAY(("Reverting did not fix intersections!\r\n"));
  1000. }
  1001. #endif
  1002. }
  1003. }
  1004. /*
  1005. ** Release the push records
  1006. */
  1007. PushRecordClass::Delete_List(PushList);
  1008. PushList = NULL;
  1009. /*
  1010. ** Ratchet our animation state forward for the next frame
  1011. */
  1012. REF_PTR_RELEASE(PrevAnimation);
  1013. REF_PTR_SET(PrevAnimation,CurAnimation);
  1014. PrevFrame = CurFrame;
  1015. VERBOSE_LOG(("Timestep - done\r\n"));
  1016. return object_animated;
  1017. }
  1018. /***********************************************************************************************
  1019. * AnimCollisionManagerClass::Revert_Animation_State -- revert to previous anim frame *
  1020. * *
  1021. * INPUT: *
  1022. * *
  1023. * OUTPUT: *
  1024. * *
  1025. * WARNINGS: *
  1026. * *
  1027. * HISTORY: *
  1028. * 8/9/2000 gth : Created. *
  1029. *=============================================================================================*/
  1030. void AnimCollisionManagerClass::Revert_Animation_State(void)
  1031. {
  1032. REF_PTR_SET(CurAnimation,PrevAnimation);
  1033. CurFrame = PrevFrame;
  1034. Parent.Peek_Model()->Set_Animation(CurAnimation,CurFrame);
  1035. VERBOSE_LOG(("Reverted to frame: %f\r\n",CurFrame));
  1036. /*
  1037. ** Force the transforms of the collideable meshes to update
  1038. */
  1039. for (int ci=0; ci<CollisionMeshes.Count(); ci++) {
  1040. CollisionMeshes[ci].Cache_End_Transform();
  1041. CollisionMeshes[ci].Install_End_Transform();
  1042. }
  1043. /*
  1044. ** Put everyone that we pushed back into their original state
  1045. */
  1046. PushRecordClass::Revert_List(PushList);
  1047. }
  1048. /***********************************************************************************************
  1049. * AnimCollisionManagerClass::Check_Collision -- Check the given collision object *
  1050. * *
  1051. * This returns true if the object collided with something and could not move it out of the *
  1052. * way. (You must revert or kill the object in this case) *
  1053. * *
  1054. * INPUT: *
  1055. * *
  1056. * OUTPUT: *
  1057. * *
  1058. * WARNINGS: *
  1059. * *
  1060. * HISTORY: *
  1061. * 8/9/2000 gth : Created. *
  1062. *=============================================================================================*/
  1063. bool AnimCollisionManagerClass::Check_Collision(CollideableObjClass & collisionobj)
  1064. {
  1065. /*
  1066. ** Algorithm:
  1067. ** - Determine how each attached object should move due to our motion.
  1068. ** - Ask all of our attached objects to apply the same delta.
  1069. ** - Ask physics scene to do an intersection test between our mesh and all nearby dynamic objects
  1070. ** - If (CollisionMode == STOP) REVERT animation and return
  1071. ** - Else For each object intersecting the collision mesh:
  1072. ** - If it is one of our attached objects, SQUISH and REVERT
  1073. ** - Else
  1074. ** - Determine how the collided object should move and try to move it
  1075. ** - If still colliding, SQUISH and REVERT
  1076. ** - Else OK
  1077. ** - If no object caused a revert, ACCEPT new animation state and return.
  1078. ** - Else REVERT and return
  1079. */
  1080. /*
  1081. ** Compute the change in the transform of the collision mesh. Note that this
  1082. ** is currently only "supposed" to work with pure translational motion...
  1083. */
  1084. Matrix3D delta_transform;
  1085. Matrix3D pinv;
  1086. collisionobj.Get_Start_Transform().Get_Orthogonal_Inverse(pinv);
  1087. Matrix3D::Multiply(collisionobj.Get_End_Transform(),pinv,&delta_transform);
  1088. /*
  1089. ** Make all attached objects move with us (people stick on elevators, etc)
  1090. ** Adding a push record for each rider in case it gets moved...
  1091. */
  1092. int collision_bits = collisionobj.Clear_Collision_Bits();
  1093. NonRefPhysListIterator rider_iterator(RiderManager.Get_Rider_List());
  1094. VERBOSE_LOG((" rider_list: "));
  1095. while (!rider_iterator.Is_Done()) {
  1096. VERBOSE_LOG(("%s, ",rider_iterator.Peek_Obj()->Peek_Model()->Get_Name()));
  1097. PushRecordClass::Add_To_List(&PushList,rider_iterator.Peek_Obj());
  1098. rider_iterator.Next();
  1099. }
  1100. VERBOSE_LOG(("\r\n"));
  1101. RiderManager.Move_Riders(delta_transform,collisionobj.Peek_Collision_Object());
  1102. collisionobj.Restore_Collision_Bits(collision_bits);
  1103. /*
  1104. ** Perform intersection detection
  1105. */
  1106. VERBOSE_LOG(("Check Collision: %s\r\n",collisionobj.Peek_Collision_Object()->Get_Name()));
  1107. NonRefPhysListClass intersection_list;
  1108. collisionobj.Intersect_Scene(Parent.Get_Collision_Group(),&intersection_list);
  1109. /*
  1110. ** If nothing is intersecting us, return.
  1111. */
  1112. if (intersection_list.Is_Empty()) {
  1113. return false;
  1114. }
  1115. /*
  1116. ** CollisionMode == COLLIDE_STOP
  1117. ** If something is intersecting us and we just revert when that happens, revert and return
  1118. */
  1119. if (CollisionMode == COLLIDE_STOP) {
  1120. return true;
  1121. }
  1122. /*
  1123. ** CollisionMode == COLLIDE_KILL
  1124. ** If something is intersecting us and we are in KILL mode, then we kill them!
  1125. */
  1126. if (CollisionMode == COLLIDE_KILL) {
  1127. NonRefPhysListIterator it(&intersection_list);
  1128. for (it.First(); !it.Is_Done(); it.Next()) {
  1129. it.Peek_Obj()->Expire();
  1130. }
  1131. }
  1132. /*
  1133. ** CollisionMode == COLLIDE_PUSH
  1134. ** Handle collisions by pushing the objects out of our way
  1135. */
  1136. bool revert = false;
  1137. NonRefPhysListIterator it(&intersection_list);
  1138. for (it.First();!it.Is_Done();it.Next()) {
  1139. PhysClass * obj = it.Peek_Obj();
  1140. VERBOSE_LOG(("intersecting object: %s\r\n",obj->Peek_Model()->Get_Name()));
  1141. if (RiderManager.Contains(obj) && (obj->Peek_Carrier_Sub_Object() == collisionobj.Peek_Collision_Object())) {
  1142. /*
  1143. ** If an object that we hit is attached to us already, squish and revert
  1144. */
  1145. //obj->Notify_Squished(this);
  1146. revert = true;
  1147. #pragma message ("(gth) commenting out rider squishing code for critical review!")
  1148. VERBOSE_LOG(("Squishing a rider!\r\n"));
  1149. } else {
  1150. /*
  1151. ** Otherwise, try to push the object out of our way.
  1152. */
  1153. int collision_bits = collisionobj.Clear_Collision_Bits();
  1154. if (Push_Collided_Object(obj,delta_transform) == false) {
  1155. VERBOSE_LOG(("SAPO %s Failed to push a rider\r\n",Parent.Peek_Model()->Get_Name()));
  1156. revert = true;
  1157. }
  1158. collisionobj.Restore_Collision_Bits(collision_bits);
  1159. }
  1160. }
  1161. return revert;
  1162. }
  1163. /***********************************************************************************************
  1164. * AnimCollisionManagerClass::Is_Intersecting -- intersection test *
  1165. * *
  1166. * INPUT: *
  1167. * *
  1168. * OUTPUT: *
  1169. * *
  1170. * WARNINGS: *
  1171. * *
  1172. * HISTORY: *
  1173. * 8/9/2000 gth : Created. *
  1174. *=============================================================================================*/
  1175. bool AnimCollisionManagerClass::Is_Intersecting(void)
  1176. {
  1177. NonRefPhysListClass intersection_list;
  1178. for (int ci=0; ci<CollisionMeshes.Count() && intersection_list.Is_Empty(); ci++) {
  1179. CollisionMeshes[ci].Intersect_Scene(Parent.Get_Collision_Group(),&intersection_list);
  1180. }
  1181. return !intersection_list.Is_Empty();
  1182. }
  1183. /***********************************************************************************************
  1184. * AnimCollisionManagerClass::Push_Collided_Object -- push an object we collided with *
  1185. * *
  1186. * INPUT: *
  1187. * *
  1188. * OUTPUT: *
  1189. * *
  1190. * WARNINGS: *
  1191. * *
  1192. * HISTORY: *
  1193. * 8/9/2000 gth : Created. *
  1194. *=============================================================================================*/
  1195. bool AnimCollisionManagerClass::Push_Collided_Object(PhysClass * obj,const Matrix3D & delta_transform)
  1196. {
  1197. bool result = false;
  1198. MoveablePhysClass * move_obj = obj->As_MoveablePhysClass();
  1199. if (move_obj != NULL) {
  1200. VERBOSE_LOG(("Pushing object: %s, vector: (%f, %f, %f)\r\n",move_obj->Peek_Model()->Get_Name(),
  1201. delta_transform.Get_Translation().X,
  1202. delta_transform.Get_Translation().Y,
  1203. delta_transform.Get_Translation().Z ));
  1204. PushRecordClass::Add_To_List(&PushList,obj);
  1205. result = move_obj->Push(delta_transform.Get_Translation());
  1206. }
  1207. return result;
  1208. }
  1209. /***********************************************************************************************
  1210. * AnimCollisionManagerClass::Save -- save! *
  1211. * *
  1212. * INPUT: *
  1213. * *
  1214. * OUTPUT: *
  1215. * *
  1216. * WARNINGS: *
  1217. * *
  1218. * HISTORY: *
  1219. * 8/9/2000 gth : Created. *
  1220. *=============================================================================================*/
  1221. bool AnimCollisionManagerClass::Save(ChunkSaveClass &csave)
  1222. {
  1223. csave.Begin_Chunk(ANIMCOLLISIONMANAGER_CHUNK_VARIABLES);
  1224. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_COLLISIONMODE,CollisionMode);
  1225. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_ANIMATIONMODE,AnimationMode);
  1226. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_TARGETFRAME,TargetFrame);
  1227. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_CURFRAME,CurFrame);
  1228. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_PREVFRAME,PrevFrame);
  1229. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_LOOPSTART,LoopStart);
  1230. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGER_VARIABLE_LOOPEND,LoopEnd);
  1231. if (CurAnimation != NULL) {
  1232. WRITE_MICRO_CHUNK_STRING(csave,ANIMCOLLISIONMANAGER_VARIABLE_ANIMATIONNAME,CurAnimation->Get_Name());
  1233. }
  1234. if (PrevAnimation != NULL) {
  1235. WRITE_MICRO_CHUNK_STRING(csave,ANIMCOLLISIONMANAGER_VARIABLE_PREVANIMATIONNAME,PrevAnimation->Get_Name());
  1236. }
  1237. csave.End_Chunk();
  1238. return true;
  1239. }
  1240. /***********************************************************************************************
  1241. * AnimCollisionManagerClass::Load -- Load! *
  1242. * *
  1243. * INPUT: *
  1244. * *
  1245. * OUTPUT: *
  1246. * *
  1247. * WARNINGS: *
  1248. * *
  1249. * HISTORY: *
  1250. * 8/9/2000 gth : Created. *
  1251. *=============================================================================================*/
  1252. bool AnimCollisionManagerClass::Load(ChunkLoadClass &cload)
  1253. {
  1254. StringClass anim_name;
  1255. StringClass prev_anim_name;
  1256. /*
  1257. ** Read in the chunks from the file
  1258. */
  1259. while (cload.Open_Chunk()) {
  1260. switch(cload.Cur_Chunk_ID())
  1261. {
  1262. case ANIMCOLLISIONMANAGER_CHUNK_VARIABLES:
  1263. while (cload.Open_Micro_Chunk()) {
  1264. switch(cload.Cur_Micro_Chunk_ID()) {
  1265. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_COLLISIONMODE,CollisionMode);
  1266. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_ANIMATIONMODE,AnimationMode);
  1267. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_TARGETFRAME,TargetFrame);
  1268. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_CURFRAME,CurFrame);
  1269. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_PREVFRAME,PrevFrame);
  1270. READ_MICRO_CHUNK_WWSTRING(cload,ANIMCOLLISIONMANAGER_VARIABLE_ANIMATIONNAME,anim_name);
  1271. READ_MICRO_CHUNK_WWSTRING(cload,ANIMCOLLISIONMANAGER_VARIABLE_PREVANIMATIONNAME,prev_anim_name);
  1272. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_LOOPSTART,LoopStart);
  1273. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGER_VARIABLE_LOOPEND,LoopEnd);
  1274. }
  1275. cload.Close_Micro_Chunk();
  1276. }
  1277. break;
  1278. default:
  1279. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  1280. break;
  1281. };
  1282. cload.Close_Chunk();
  1283. }
  1284. if (!anim_name.Is_Empty()) {
  1285. Internal_Set_Animation(anim_name);
  1286. }
  1287. if (!prev_anim_name.Is_Empty()) {
  1288. HAnimClass * anim = WW3DAssetManager::Get_Instance()->Get_HAnim(prev_anim_name);
  1289. if ( anim == NULL ) {
  1290. WWDEBUG_SAY(( "FAILED TO FIND PREV ANIM IN AnimCollisionManagerClass::Internal_Set_Animation(\"%s\")\n", prev_anim_name ));
  1291. }
  1292. REF_PTR_SET(PrevAnimation,anim);
  1293. }
  1294. return true;
  1295. }
  1296. /********************************************************************************************
  1297. **
  1298. ** AnimCollisionManagerDefClass Implementation
  1299. ** Note, AnimCollisionManagerDef is not a full-fleged definition class. It is meant to be
  1300. ** embedded inside another real definition. (e.g. StaticAnimPhys)
  1301. **
  1302. ********************************************************************************************/
  1303. enum
  1304. {
  1305. ANIMCOLLISIONMANAGERDEF_CHUNK_VARIABLES = 525000306,
  1306. ANIMCOLLISIONMANAGERDEF_VARIABLE_COLLISIONMODE = 0x00,
  1307. ANIMCOLLISIONMANAGERDEF_VARIABLE_ANIMATIONMODE,
  1308. ANIMCOLLISIONMANAGERDEF_VARIABLE_ANIMATIONNAME,
  1309. };
  1310. AnimCollisionManagerDefClass::AnimCollisionManagerDefClass(void) :
  1311. CollisionMode(AnimCollisionManagerClass::COLLIDE_PUSH),
  1312. AnimationMode(AnimCollisionManagerClass::ANIMATE_LOOP)
  1313. {
  1314. }
  1315. AnimCollisionManagerDefClass::~AnimCollisionManagerDefClass(void)
  1316. {
  1317. }
  1318. void AnimCollisionManagerDefClass::Validate_Parameters(void)
  1319. {
  1320. if (CollisionMode < 0) CollisionMode = 0;
  1321. if (CollisionMode > AnimCollisionManagerClass::ANIMATE_MANUAL) CollisionMode = AnimCollisionManagerClass::ANIMATE_MANUAL;
  1322. }
  1323. bool AnimCollisionManagerDefClass::Save(ChunkSaveClass &csave)
  1324. {
  1325. Validate_Parameters();
  1326. csave.Begin_Chunk(ANIMCOLLISIONMANAGERDEF_CHUNK_VARIABLES);
  1327. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGERDEF_VARIABLE_COLLISIONMODE,CollisionMode);
  1328. WRITE_MICRO_CHUNK(csave,ANIMCOLLISIONMANAGERDEF_VARIABLE_ANIMATIONMODE,AnimationMode);
  1329. WRITE_MICRO_CHUNK_WWSTRING(csave,ANIMCOLLISIONMANAGERDEF_VARIABLE_ANIMATIONNAME,AnimationName);
  1330. csave.End_Chunk();
  1331. return true;
  1332. }
  1333. bool AnimCollisionManagerDefClass::Load(ChunkLoadClass &cload)
  1334. {
  1335. while (cload.Open_Chunk()) {
  1336. switch(cload.Cur_Chunk_ID()) {
  1337. case ANIMCOLLISIONMANAGERDEF_CHUNK_VARIABLES:
  1338. while (cload.Open_Micro_Chunk()) {
  1339. switch(cload.Cur_Micro_Chunk_ID()) {
  1340. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGERDEF_VARIABLE_COLLISIONMODE,CollisionMode);
  1341. READ_MICRO_CHUNK(cload,ANIMCOLLISIONMANAGERDEF_VARIABLE_ANIMATIONMODE,AnimationMode);
  1342. READ_MICRO_CHUNK_WWSTRING(cload,ANIMCOLLISIONMANAGERDEF_VARIABLE_ANIMATIONNAME,AnimationName);
  1343. }
  1344. cload.Close_Micro_Chunk();
  1345. }
  1346. break;
  1347. default:
  1348. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  1349. break;
  1350. }
  1351. cload.Close_Chunk();
  1352. }
  1353. return true;
  1354. }