VActorPhysicsController.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278
  1. //-----------------------------------------------------------------------------
  2. // Verve
  3. // Copyright (C) 2014 - Violent Tulip
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //-----------------------------------------------------------------------------
  23. #include "VActorPhysicsController.h"
  24. #include "VActor.h"
  25. #include "VActorData.h"
  26. #include "VActorPhysicsStates.h"
  27. #include "Verve/VPath/VPath.h"
  28. #include "collision/clippedPolyList.h"
  29. #include "collision/earlyOutPolyList.h"
  30. #include "collision/extrudedPolyList.h"
  31. #include "core/stream/bitStream.h"
  32. #include "environment/waterObject.h"
  33. //-----------------------------------------------------------------------------
  34. static const U32 sGroundCollisionMask = ( StaticObjectType | StaticShapeObjectType | TerrainObjectType );
  35. static const U32 sMoveCollisionMask = ( PlayerObjectType | VehicleObjectType );
  36. static const U32 sCollisionMask = ( sGroundCollisionMask | sMoveCollisionMask );
  37. //-----------------------------------------------------------------------------
  38. VActorPhysicsController::VActorPhysicsController( void ) :
  39. mObject( NULL ),
  40. mMountedPath( NULL ),
  41. mPhysicsState( 0 ),
  42. mControlState( k_NullControlState ),
  43. mMoveState( k_NullMove ),
  44. mVelocity( VectorF::Zero ),
  45. mGravity( 0.f, 0.f, -9.8f ),
  46. mOnGround(false)
  47. {
  48. // Void.
  49. }
  50. VActorPhysicsController::~VActorPhysicsController( void )
  51. {
  52. // Clear Object.
  53. clearObject();
  54. }
  55. //-----------------------------------------------------------------------------
  56. //
  57. // Initialisation Methods.
  58. //
  59. //-----------------------------------------------------------------------------
  60. //-----------------------------------------------------------------------------
  61. //
  62. // VActorPhysicsController::initPhysicsController();
  63. //
  64. // Initialise the physics table and setup the interface between the Controller
  65. // and the reference object.
  66. //
  67. //-----------------------------------------------------------------------------
  68. bool VActorPhysicsController::initPhysicsController( VActor *pObject )
  69. {
  70. // Valid Object?
  71. if ( !pObject )
  72. {
  73. // Assert & Quit.
  74. AssertFatal( false, "VActorPhysicsController::initPhysicsController() - Invalid Object Specified." );
  75. return false;
  76. }
  77. // Set Object.
  78. mObject = pObject;
  79. // Register for Actor Events.
  80. mObject->getEventSignal().notify( this, &VActorPhysicsController::onActorEvent );
  81. // Set Table's Reference.
  82. mPhysicsStateTable.setObject( pObject );
  83. // Init the Convex Box.
  84. mConvex.init( pObject );
  85. // Reset Interp.
  86. mInterpController.resetDelta( pObject->getTransform() );
  87. // Validate.
  88. return initPhysicsTable();
  89. }
  90. //-----------------------------------------------------------------------------
  91. //
  92. // VActorPhysicsController::initPhysicsTable();
  93. //
  94. // Register the available physics states which this controller may utilize.
  95. //
  96. //-----------------------------------------------------------------------------
  97. bool VActorPhysicsController::initPhysicsTable( void )
  98. {
  99. // Valid Object?
  100. if ( !isValidObject() )
  101. {
  102. // No, Quit Now.
  103. return false;
  104. }
  105. // Clear the Table.
  106. mPhysicsStateTable.clear();
  107. // Fetch Sequence List.
  108. VActorData::tPhysicsStateVector *stateList = getObjectDataBlock()->getPhysicsStateList();
  109. // Initialise the Physics States.
  110. for ( VActorData::tPhysicsStateVector::iterator itr = stateList->begin();
  111. itr != stateList->end();
  112. itr++ )
  113. {
  114. // Fetch Sequence Definition.
  115. const VActorData::sPhysicsState &physState = ( *itr );
  116. // Valid State?
  117. if ( physState.State )
  118. {
  119. // Register State.
  120. mPhysicsStateTable.registerState( physState.State, physState.Priority );
  121. }
  122. }
  123. // Sort the Table.
  124. mPhysicsStateTable.sort();
  125. // Valid.
  126. return true;
  127. }
  128. //-----------------------------------------------------------------------------
  129. //
  130. // Accessor Methods
  131. //
  132. //-----------------------------------------------------------------------------
  133. //-----------------------------------------------------------------------------
  134. //
  135. // VActorPhysicsController::isValidObject();
  136. //
  137. // Do we have a valid reference object?
  138. //
  139. //-----------------------------------------------------------------------------
  140. bool VActorPhysicsController::isValidObject( void )
  141. {
  142. return ( mObject && mObject->getDataBlock() );
  143. }
  144. //-----------------------------------------------------------------------------
  145. //
  146. // VActorPhysicsController::getObject();
  147. //
  148. // Return the reference object.
  149. //
  150. //-----------------------------------------------------------------------------
  151. VActor *VActorPhysicsController::getObject( void )
  152. {
  153. return mObject;
  154. }
  155. //-----------------------------------------------------------------------------
  156. //
  157. // VActorPhysicsController::getObjectDataBlock();
  158. //
  159. // Get the Actor Data for the reference object.
  160. //
  161. //-----------------------------------------------------------------------------
  162. VActorData *VActorPhysicsController::getObjectDataBlock( void )
  163. {
  164. // Valid Object?
  165. if ( !mObject )
  166. {
  167. // No.
  168. return NULL;
  169. }
  170. // Return DataBlock.
  171. return mObject->getDataBlock();
  172. }
  173. //-----------------------------------------------------------------------------
  174. //
  175. // VActorPhysicsController::clearObject();
  176. //
  177. // Clear the reference object. Note that this should *never* be called outside
  178. // of the controller's destructor!
  179. //
  180. //-----------------------------------------------------------------------------
  181. void VActorPhysicsController::clearObject( void )
  182. {
  183. // Valid Object?
  184. if ( !mObject )
  185. {
  186. // No.
  187. return;
  188. }
  189. // Clear Notify.
  190. mObject->getEventSignal().remove( this, &VActorPhysicsController::onActorEvent );
  191. // Clear Object.
  192. mObject = NULL;
  193. // Clear Table.
  194. mPhysicsStateTable.setObject( NULL );
  195. mPhysicsStateTable.clear();
  196. }
  197. //-----------------------------------------------------------------------------
  198. //
  199. // VActorPhysicsController::getControlState();
  200. //
  201. // Get the current Control State.
  202. //
  203. //-----------------------------------------------------------------------------
  204. const U32 VActorPhysicsController::getControlState( void )
  205. {
  206. return mControlState;
  207. }
  208. //-----------------------------------------------------------------------------
  209. //
  210. // VActorPhysicsController::clearControlState( pControlState );
  211. //
  212. // Clear the Control State of a particular mask.
  213. //
  214. //-----------------------------------------------------------------------------
  215. void VActorPhysicsController::clearControlState( const U32 &pControlState )
  216. {
  217. mControlState &= ( ~pControlState );
  218. }
  219. //-----------------------------------------------------------------------------
  220. //
  221. // VActorPhysicsController::setControlState( pControlState );
  222. //
  223. // Set the Control State.
  224. //
  225. //-----------------------------------------------------------------------------
  226. void VActorPhysicsController::setControlState( const U32 &pControlState )
  227. {
  228. mControlState = pControlState;
  229. }
  230. //-----------------------------------------------------------------------------
  231. //
  232. // VActorPhysicsController::isMoving();
  233. //
  234. // Is the Actor currently Moving?
  235. //
  236. //-----------------------------------------------------------------------------
  237. const bool VActorPhysicsController::isMoving( void )
  238. {
  239. return ( !mIsZero( getVelocity().lenSquared() ) );
  240. }
  241. //-----------------------------------------------------------------------------
  242. //
  243. // VActorPhysicsController::isMoving( pMoveState );
  244. //
  245. // Is the Actor currently moving with the desired state?
  246. //
  247. //-----------------------------------------------------------------------------
  248. const bool VActorPhysicsController::isMoving( const U32 &pMoveState )
  249. {
  250. // Moving?
  251. return ( ( getMoveState() & pMoveState ) && isMoving() );
  252. }
  253. //-----------------------------------------------------------------------------
  254. //
  255. // VActorPhysicsController::getMoveState();
  256. //
  257. // Get the current Move State.
  258. //
  259. //-----------------------------------------------------------------------------
  260. const U32 VActorPhysicsController::getMoveState( void )
  261. {
  262. // Return Move State.
  263. return mMoveState;
  264. }
  265. //-----------------------------------------------------------------------------
  266. //
  267. // VActorPhysicsController::clearMoveState( pMoveState );
  268. //
  269. // Clear the Move State of a particular mask.
  270. //
  271. //-----------------------------------------------------------------------------
  272. void VActorPhysicsController::clearMoveState( const U32 &pMoveState )
  273. {
  274. // Set Move State.
  275. mMoveState &= ( ~pMoveState );
  276. }
  277. //-----------------------------------------------------------------------------
  278. //
  279. // VActorPhysicsController::setMoveState( pMoveState );
  280. //
  281. // Set the Move State.
  282. //
  283. //-----------------------------------------------------------------------------
  284. void VActorPhysicsController::setMoveState( const U32 &pMoveState )
  285. {
  286. // Set Move State.
  287. mMoveState = pMoveState;
  288. }
  289. //-----------------------------------------------------------------------------
  290. //
  291. // VActorPhysicsController::isPathing();
  292. //
  293. // Is the Actor Pathing?
  294. //
  295. //-----------------------------------------------------------------------------
  296. const bool VActorPhysicsController::isPathing( void )
  297. {
  298. // Valid Object?
  299. if ( !isValidObject() )
  300. {
  301. // No.
  302. return false;
  303. }
  304. return ( mMountedPath != NULL );
  305. }
  306. //-----------------------------------------------------------------------------
  307. //
  308. // VActorPhysicsController::getPathObject();
  309. //
  310. // Get the Path Object the Actor is mounted to.
  311. //
  312. //-----------------------------------------------------------------------------
  313. VPath *VActorPhysicsController::getPathObject( void )
  314. {
  315. // Valid Object?
  316. if ( !isValidObject() )
  317. {
  318. // No.
  319. return NULL;
  320. }
  321. return mMountedPath;
  322. }
  323. //-----------------------------------------------------------------------------
  324. //
  325. // VActorPhysicsController::isOnGround();
  326. //
  327. // Is the Actor On the Ground?
  328. //
  329. //-----------------------------------------------------------------------------
  330. const bool VActorPhysicsController::isOnGround( void )
  331. {
  332. // Valid Objects?
  333. if ( !isValidObject() )
  334. {
  335. // No.
  336. return false;
  337. }
  338. // On Ground?
  339. return ( mOnGround && mGroundObject && !isInWater() );
  340. }
  341. //-----------------------------------------------------------------------------
  342. //
  343. // VActorPhysicsController::isInAir();
  344. //
  345. // Is the Actor in the Air?
  346. //
  347. //-----------------------------------------------------------------------------
  348. const bool VActorPhysicsController::isInAir( void )
  349. {
  350. // Valid Objects?
  351. if ( !isValidObject() )
  352. {
  353. // No.
  354. return false;
  355. }
  356. // In Air?
  357. return ( !isOnGround() && !isInWater() );
  358. }
  359. //-----------------------------------------------------------------------------
  360. //
  361. // VActorPhysicsController::isInWater();
  362. //
  363. // Is the Actor in the Water?
  364. //
  365. //-----------------------------------------------------------------------------
  366. const bool VActorPhysicsController::isInWater( void )
  367. {
  368. // Valid Objects?
  369. if ( !isValidObject() || !getWaterObject() )
  370. {
  371. // No.
  372. return false;
  373. }
  374. // Submerged?
  375. return ( ( mObject->getWaterCoverage() + POINT_EPSILON ) >= mObject->getDataBlock()->getSumbergeCoverage() );
  376. }
  377. //-----------------------------------------------------------------------------
  378. //
  379. // VActorPhysicsController::getWaterObject();
  380. //
  381. // Get the current Water Object the Actor is in.
  382. //
  383. //-----------------------------------------------------------------------------
  384. WaterObject *VActorPhysicsController::getWaterObject( void )
  385. {
  386. // Valid Object?
  387. if ( !isValidObject() )
  388. {
  389. // No.
  390. return NULL;
  391. }
  392. return mObject->getCurrentWaterObject();
  393. }
  394. //-----------------------------------------------------------------------------
  395. //
  396. // VActorPhysicsController::getTransform();
  397. //
  398. // Get the Actor's Transform.
  399. //
  400. //-----------------------------------------------------------------------------
  401. MatrixF VActorPhysicsController::getTransform( void )
  402. {
  403. // Valid Object?
  404. if ( !isValidObject() )
  405. {
  406. // No.
  407. return MatrixF::Identity;
  408. }
  409. // Return Transform.
  410. return mObject->getTransform();
  411. }
  412. //-----------------------------------------------------------------------------
  413. //
  414. // VActorPhysicsController::setTransform( pTransform );
  415. //
  416. // Set the Actor's Transform.
  417. //
  418. //-----------------------------------------------------------------------------
  419. void VActorPhysicsController::setTransform( const MatrixF &pTransform )
  420. {
  421. // Valid Object?
  422. if ( !isValidObject() )
  423. {
  424. // No.
  425. return;
  426. }
  427. // Apply Transform.
  428. mObject->setTransform( pTransform );
  429. }
  430. //-----------------------------------------------------------------------------
  431. //
  432. // VActorPhysicsController::getPosition();
  433. //
  434. // Get the Actor's Position.
  435. //
  436. //-----------------------------------------------------------------------------
  437. Point3F VActorPhysicsController::getPosition( void )
  438. {
  439. // Valid Object?
  440. if ( !isValidObject() )
  441. {
  442. // No.
  443. return Point3F::Zero;
  444. }
  445. // Return Position.
  446. return mObject->getPosition();
  447. }
  448. //-----------------------------------------------------------------------------
  449. //
  450. // VActorPhysicsController::setPosition( pPosition );
  451. //
  452. // Set the Actor's Position.
  453. //
  454. //-----------------------------------------------------------------------------
  455. void VActorPhysicsController::setPosition( const Point3F &pPosition )
  456. {
  457. // Valid Object?
  458. if ( !isValidObject() )
  459. {
  460. // No.
  461. return;
  462. }
  463. // Apply Position.
  464. mObject->setPosition( pPosition );
  465. }
  466. //-----------------------------------------------------------------------------
  467. //
  468. // VActorPhysicsController::applyGravity( pElapsedTime );
  469. //
  470. // Apply gravity for the elapsed period.
  471. //
  472. //-----------------------------------------------------------------------------
  473. void VActorPhysicsController::applyGravity( const F32 &pElapsedTime )
  474. {
  475. // Get Velocity.
  476. VectorF velocity = getVelocity();
  477. // Add Tick Gravity.
  478. velocity += getGravity() * pElapsedTime;
  479. // Apply.
  480. setVelocity( velocity );
  481. }
  482. //-----------------------------------------------------------------------------
  483. //
  484. // VActorPhysicsController::getVelocity();
  485. //
  486. // Get the Actor's Velocity.
  487. //
  488. //-----------------------------------------------------------------------------
  489. VectorF VActorPhysicsController::getVelocity( void )
  490. {
  491. // Valid Object?
  492. if ( !isValidObject() )
  493. {
  494. // No.
  495. return VectorF::Zero;
  496. }
  497. // Return Velocity.
  498. return mVelocity;
  499. }
  500. //-----------------------------------------------------------------------------
  501. //
  502. // VActorPhysicsController::setVelocity( pVelocity );
  503. //
  504. // Set the Actor's Velocity.
  505. //
  506. //-----------------------------------------------------------------------------
  507. void VActorPhysicsController::setVelocity( const VectorF &pVelocity )
  508. {
  509. // Set Velocity.
  510. mVelocity = pVelocity;
  511. }
  512. //-----------------------------------------------------------------------------
  513. //
  514. // Physics Methods
  515. //
  516. //-----------------------------------------------------------------------------
  517. //-----------------------------------------------------------------------------
  518. //
  519. // VActorPhysicsController::update( pDelta, pMove );
  520. //
  521. // ...
  522. //
  523. //-----------------------------------------------------------------------------
  524. void VActorPhysicsController::update( const F32 &pDelta, const Move *pMove )
  525. {
  526. // Valid Objects?
  527. if ( !isValidObject() )
  528. {
  529. // No, Quit Now.
  530. return;
  531. }
  532. // Pre-tick Update.
  533. preTickUpdate( pDelta );
  534. // Integrate Tick Update.
  535. integrateTickUpdate( pDelta, pMove );
  536. // Post-tick Update.
  537. postTickUpdate( pDelta );
  538. }
  539. //-----------------------------------------------------------------------------
  540. //
  541. // VActorPhysicsController::preTickUpdate( pDelta );
  542. //
  543. // ...
  544. //
  545. //-----------------------------------------------------------------------------
  546. void VActorPhysicsController::preTickUpdate( const F32 &pDelta )
  547. {
  548. // Pop Delta.
  549. mInterpController.popDelta();
  550. switch( mControlState )
  551. {
  552. case k_PathControlState :
  553. {
  554. AssertFatal( isPathing(), "VActorPhysicsController::preTickUpdate() - Invalid Path State." );
  555. // Fetch Mount Velocity.
  556. const VectorF &mountVelocity = mMountedPath->getMountVelocity( mObject->getMountNode() );
  557. // Use X & Y Velocity.
  558. VectorF velocity = getVelocity();
  559. velocity.x = mountVelocity.x;
  560. velocity.y = mountVelocity.y;
  561. // Apply Updates.
  562. setVelocity( velocity );
  563. } break;
  564. }
  565. // Update Move State.
  566. updateMoveState();
  567. }
  568. //-----------------------------------------------------------------------------
  569. //
  570. // VActorPhysicsController::integrateTickUpdate( pDelta, pMove );
  571. //
  572. // ...
  573. //
  574. //-----------------------------------------------------------------------------
  575. void VActorPhysicsController::integrateTickUpdate( const F32 &pDelta, const Move *pMove )
  576. {
  577. // Update Collision Set.
  578. updateWorkingCollisionSet();
  579. // Ground Ground Status.
  580. updateGroundStatus();
  581. // Execute Physics Table.
  582. VActorPhysicsState *physState = dynamic_cast<VActorPhysicsState*>( mPhysicsStateTable.execute() );
  583. // Assert.
  584. AssertFatal( physState, "VActorPhysicsController::update() - Invalid Physics State in the Table." );
  585. // Process the State.
  586. physState->processTick( mObject, pDelta, pMove );
  587. // Process Collisions.
  588. processCollisions();
  589. }
  590. //-----------------------------------------------------------------------------
  591. //
  592. // VActorPhysicsController::postTickUpdate( pDelta );
  593. //
  594. // ...
  595. //
  596. //-----------------------------------------------------------------------------
  597. void VActorPhysicsController::postTickUpdate( const F32 &pDelta )
  598. {
  599. switch( mControlState )
  600. {
  601. case k_PathControlState :
  602. {
  603. AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." );
  604. // Fetch Mount Transform.
  605. MatrixF transform;
  606. mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform );
  607. // Fetch Mount Position.
  608. const Point3F &mountPosition = transform.getPosition();
  609. // Update X & Y Position.
  610. Point3F position = getPosition();
  611. position.x = mountPosition.x;
  612. position.y = mountPosition.y;
  613. // In Water?
  614. bool underWater = false;
  615. if ( isInWater() )
  616. {
  617. // Fetch Body of Water.
  618. WaterObject *waterBody = getWaterObject();
  619. // Fetch Surface Position.
  620. const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) );
  621. // Fetch Submersion Position.
  622. const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() );
  623. // Choose a Z Value.
  624. // Note: This is done so that the Actor will either path under the
  625. // water, or it will swim along the water's surface.
  626. position.z = getMin( mountPosition.z, sumbersionPosition );
  627. // Under Water?
  628. underWater = ( position.z < sumbersionPosition );
  629. }
  630. // Under Water?
  631. if ( !underWater )
  632. {
  633. // Fetch Y Column.
  634. VectorF forwardVector;
  635. transform.getColumn( 1, &forwardVector );
  636. // Determine Angle.
  637. const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y );
  638. // Reset Transform.
  639. transform.set( EulerF( 0.f, 0.f, angle ) );
  640. // In the air?
  641. if ( !isOnGround() )
  642. {
  643. // Apply z-axis force.
  644. position.z += ( getVelocity().z * pDelta );
  645. }
  646. }
  647. // Update Transform.
  648. transform.setPosition( position );
  649. // Apply Update.
  650. setTransform( transform );
  651. } break;
  652. default :
  653. {
  654. // Fetch Transform.
  655. MatrixF transform = getTransform();
  656. // Determine the Post-Tick Position.
  657. Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta );
  658. // Set the Post Tick Position.
  659. transform.setPosition( postTickPosition );
  660. // Apply the Transform.
  661. setTransform( transform );
  662. } break;
  663. }
  664. // Push Delta.
  665. mInterpController.pushDelta( getTransform() );
  666. }
  667. //-----------------------------------------------------------------------------
  668. //
  669. // VActorPhysicsController::interpolateTick( pDelta );
  670. //
  671. // ...
  672. //
  673. //-----------------------------------------------------------------------------
  674. void VActorPhysicsController::interpolateTick( const F32 &pDelta )
  675. {
  676. // Fetch Interpolated Transform.
  677. const MatrixF transform = mInterpController.getTransform( pDelta );
  678. // Apply Render Transform.
  679. mObject->setRenderTransform( transform );
  680. }
  681. //-----------------------------------------------------------------------------
  682. //
  683. // VActorPhysicsController::updateWorkingCollisionSet();
  684. //
  685. // ...
  686. //
  687. //-----------------------------------------------------------------------------
  688. void VActorPhysicsController::updateWorkingCollisionSet()
  689. {
  690. // Contstruct Bounding Box.
  691. const Box3F boundingBox = mConvex.getBoundingBox( getTransform(), mObject->getScale() );
  692. // Determine Sweep Vector.
  693. const VectorF sweepVector = ( getVelocity() * TickSec );
  694. // Construct Swept Box.
  695. Box3F sweptBox = boundingBox;
  696. sweptBox.minExtents.setMin( boundingBox.minExtents + sweepVector );
  697. sweptBox.maxExtents.setMax( boundingBox.maxExtents + sweepVector );
  698. // Update Collision List.
  699. mObject->disableCollision();
  700. mConvex.updateWorkingList( sweptBox, sCollisionMask );
  701. mObject->enableCollision();
  702. }
  703. //-----------------------------------------------------------------------------
  704. //
  705. // VActorPhysicsController::updateMoveState();
  706. //
  707. // ...
  708. //
  709. //-----------------------------------------------------------------------------
  710. void VActorPhysicsController::updateMoveState( void )
  711. {
  712. switch( mControlState )
  713. {
  714. case k_PathControlState :
  715. {
  716. AssertFatal( isPathing(), "VActorPhysicsController::updateMoveState() - Invalid Path State." );
  717. // Update Move State.
  718. VPathObject *pathObject = mMountedPath->getPathObject( mObject );
  719. if ( !pathObject->isActive() )
  720. {
  721. // Idle.
  722. setMoveState( k_NullMove );
  723. }
  724. else
  725. {
  726. // Set Movement Direction.
  727. setMoveState( ( pathObject->isForward() ) ? k_ForwardMove : k_BackwardMove );
  728. }
  729. } break;
  730. default :
  731. {
  732. // Set Idle.
  733. setMoveState( k_NullMove );
  734. } break;
  735. }
  736. }
  737. //-----------------------------------------------------------------------------
  738. //
  739. // VActorPhysicsController::clearGroundStatus();
  740. //
  741. // ...
  742. //
  743. //-----------------------------------------------------------------------------
  744. void VActorPhysicsController::clearGroundStatus( void )
  745. {
  746. // Clear Grounding.
  747. mOnGround = false;
  748. mGroundObject = NULL;
  749. mGroundNormal.zero();
  750. }
  751. //-----------------------------------------------------------------------------
  752. //
  753. // VActorPhysicsController::updateGroundStatus();
  754. //
  755. // ...
  756. //
  757. //-----------------------------------------------------------------------------
  758. void VActorPhysicsController::updateGroundStatus( void )
  759. {
  760. // Submerged?
  761. if ( isInWater() )
  762. {
  763. // Clear Ground Status.
  764. clearGroundStatus();
  765. return;
  766. }
  767. // Check for Grounding.
  768. SceneObject *groundObject;
  769. Point3F groundPoint;
  770. VectorF groundNormal;
  771. if ( !findGroundContact( groundObject, groundPoint, groundNormal ) )
  772. {
  773. // Clear Ground Status.
  774. clearGroundStatus();
  775. return;
  776. }
  777. // Tidy up the Contact Position.
  778. // Note: This basically "clamps" the Actor to the surface of the ground
  779. // object.
  780. const Point3F objPosition = getPosition();
  781. setPosition( objPosition - Point3F( 0.f, 0.f, ( objPosition.z - groundPoint.z ) ) );
  782. // Clear Z-Axis Velocity.
  783. mVelocity.z = 0.f;
  784. // Store Details.
  785. mOnGround = true;
  786. mGroundObject = groundObject;
  787. mGroundNormal = groundNormal;
  788. }
  789. //-----------------------------------------------------------------------------
  790. //
  791. // VActorPhysicsController::findGroundContact( pContactObject, pContactPoint, pContactNormal );
  792. //
  793. // ...
  794. //
  795. //-----------------------------------------------------------------------------
  796. bool VActorPhysicsController::findGroundContact( SceneObject *&pContactObject, Point3F &pContactPoint, VectorF &pContactNormal )
  797. {
  798. // Setup Collision List.
  799. static CollisionList sCollisionList;
  800. sCollisionList.clear();
  801. static Polyhedron sBoxPolyhedron;
  802. static ExtrudedPolyList sExtrudedPolyList;
  803. // Fetch Max Step Height.
  804. const F32 stepHeight = mObject->getDataBlock()->getMaxStepHeight();
  805. // Determine Positions.
  806. const Point3F preTickPosition = getPosition() + Point3F( 0.f, 0.f, stepHeight );
  807. const VectorF preTickVelocity = getVelocity() + mGravity - VectorF( 0.f, 0.f, stepHeight / TickSec );
  808. const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec );
  809. const VectorF postTickVector = postTickPosition - preTickPosition;
  810. // Construct Scaled Box.
  811. Box3F scaledBox = mObject->getObjBox();
  812. scaledBox.minExtents.convolve( mObject->getScale() );
  813. scaledBox.maxExtents.convolve( mObject->getScale() );
  814. // Setup Polyherdron.
  815. MatrixF collisionMatrix( true );
  816. collisionMatrix.setPosition( preTickPosition );
  817. sBoxPolyhedron.buildBox( collisionMatrix, scaledBox );
  818. // Setup Extruded Poly List.
  819. sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector );
  820. sExtrudedPolyList.setVelocity( preTickVelocity );
  821. sExtrudedPolyList.setCollisionList( &sCollisionList );
  822. // Construct World Convex Box & Adjust for Sweep.
  823. Box3F convexBox = scaledBox;
  824. getTransform().mul( convexBox );
  825. convexBox.minExtents += postTickVector;
  826. convexBox.maxExtents += postTickVector;
  827. // Build List of Contacts.
  828. CollisionWorkingList &rList = mConvex.getWorkingList();
  829. for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext )
  830. {
  831. Convex *convexShape = pList->mConvex;
  832. // Ground Object?
  833. if ( !( convexShape->getObject()->getTypeMask() & sGroundCollisionMask ) )
  834. {
  835. // No, Continue.
  836. continue;
  837. }
  838. // Overlap?
  839. const Box3F &collisionConvexBox = convexShape->getBoundingBox();
  840. if ( convexBox.isOverlapped( collisionConvexBox ) )
  841. {
  842. // Build Contact Information.
  843. convexShape->getPolyList( &sExtrudedPolyList );
  844. }
  845. }
  846. // Valid Collision?
  847. if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() < 0.f || sCollisionList.getTime() > 1.f )
  848. {
  849. // No, Quit Now.
  850. return false;
  851. }
  852. // Use First Collision.
  853. Collision *collision = &sCollisionList[0];
  854. // More Collisions?
  855. if ( sCollisionList.getCount() > 1 )
  856. {
  857. // Check for Better Contacts.
  858. for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ )
  859. {
  860. if ( cp->faceDot > collision->faceDot )
  861. {
  862. // Use this One.
  863. collision = cp;
  864. }
  865. }
  866. }
  867. // Set Properties.
  868. pContactObject = collision->object;
  869. //pContactPoint = collision->point;
  870. pContactPoint = ( preTickPosition + ( preTickVelocity * TickSec * sCollisionList.getTime() ) );
  871. pContactNormal = collision->normal;
  872. // Valid Contact.
  873. return true;
  874. }
  875. //-----------------------------------------------------------------------------
  876. //
  877. // VActorPhysicsController::processCollisions();
  878. //
  879. // ...
  880. //
  881. //-----------------------------------------------------------------------------
  882. void VActorPhysicsController::processCollisions( void )
  883. {
  884. // Find & Resolve Collisions.
  885. Collision *collision;
  886. if ( findCollision( collision ) )
  887. {
  888. // Solve the Collision.
  889. solveCollision( collision );
  890. }
  891. }
  892. //-----------------------------------------------------------------------------
  893. //
  894. // VActorPhysicsController::findCollision( pCollision );
  895. //
  896. // ...
  897. //
  898. //-----------------------------------------------------------------------------
  899. bool VActorPhysicsController::findCollision( Collision *&pCollision )
  900. {
  901. // Setup Collision List.
  902. static CollisionList sCollisionList;
  903. sCollisionList.clear();
  904. static Polyhedron sBoxPolyhedron;
  905. static ExtrudedPolyList sExtrudedPolyList;
  906. // Determine Positions.
  907. const Point3F preTickPosition = getPosition();
  908. const VectorF preTickVelocity = getVelocity();
  909. const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec );
  910. const VectorF postTickVector = postTickPosition - preTickPosition;
  911. // Construct Scaled Box.
  912. Box3F scaledBox = mObject->getObjBox();
  913. scaledBox.minExtents.convolve( mObject->getScale() );
  914. scaledBox.maxExtents.convolve( mObject->getScale() );
  915. // Setup Polyherdron.
  916. MatrixF collisionMatrix( true );
  917. collisionMatrix.setPosition( preTickPosition );
  918. sBoxPolyhedron.buildBox( collisionMatrix, scaledBox );
  919. // Setup Extruded Poly List.
  920. sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector );
  921. sExtrudedPolyList.setVelocity( preTickVelocity );
  922. sExtrudedPolyList.setCollisionList( &sCollisionList );
  923. // Construct World Convex Box & Adjust for Sweep.
  924. Box3F convexBox = scaledBox;
  925. getTransform().mul( convexBox );
  926. convexBox.minExtents += postTickVector;
  927. convexBox.maxExtents += postTickVector;
  928. // Determine the Collision Mask.
  929. const U32 collisionMask = ( isInWater() ) ? ( sGroundCollisionMask | sMoveCollisionMask ) : sMoveCollisionMask;
  930. // Build List of Contacts.
  931. CollisionWorkingList &rList = mConvex.getWorkingList();
  932. for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext )
  933. {
  934. Convex *convexShape = pList->mConvex;
  935. // Valid Collision Target?
  936. if ( !( convexShape->getObject()->getTypeMask() & collisionMask ) )
  937. {
  938. // No, Continue.
  939. continue;
  940. }
  941. // Overlap?
  942. const Box3F &collisionConvexBox = convexShape->getBoundingBox();
  943. if ( convexBox.isOverlapped( collisionConvexBox ) )
  944. {
  945. // Build Contact Information.
  946. convexShape->getPolyList( &sExtrudedPolyList );
  947. }
  948. }
  949. // Valid Collision?
  950. if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() > 1.f )
  951. {
  952. // No, Quit Now.
  953. return false;
  954. }
  955. // Use First Collision.
  956. Collision *collision = &sCollisionList[0];
  957. // More Collisions?
  958. if ( sCollisionList.getCount() > 1 )
  959. {
  960. // Check for Better Contacts.
  961. for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ )
  962. {
  963. if ( cp->faceDot > collision->faceDot )
  964. {
  965. // Use this One.
  966. collision = cp;
  967. }
  968. }
  969. }
  970. // Store Reference.
  971. pCollision = collision;
  972. // Valid Collision.
  973. return true;
  974. }
  975. //-----------------------------------------------------------------------------
  976. //
  977. // VActorPhysicsController::solveCollision( pCollision );
  978. //
  979. // ...
  980. //
  981. //-----------------------------------------------------------------------------
  982. void VActorPhysicsController::solveCollision( Collision *pCollision )
  983. {
  984. // Fetch Velocity.
  985. VectorF velocity = getVelocity();
  986. // Resolve Collision.
  987. velocity -= ( pCollision->normal * mDot( getVelocity(), pCollision->normal ) );
  988. // Pathing?
  989. if ( isPathing() )
  990. {
  991. // Clear X & Y Velocity Adjustments.
  992. // Note: This means that any collisions made during pathing will not
  993. // be solved, unless they only affect Z position. It is up to the
  994. // user to construct Paths which avoid obsticles!
  995. velocity.x = velocity.y = 0.f;
  996. }
  997. // Set Velocity.
  998. setVelocity( velocity );
  999. }
  1000. //-----------------------------------------------------------------------------
  1001. //
  1002. // Update Methods
  1003. //
  1004. //-----------------------------------------------------------------------------
  1005. //-----------------------------------------------------------------------------
  1006. //
  1007. // VActorPhysicsController::onActorEvent( pEvent );
  1008. //
  1009. // ...
  1010. //
  1011. //-----------------------------------------------------------------------------
  1012. void VActorPhysicsController::onActorEvent( const VActor::eEventType &pEvent )
  1013. {
  1014. switch( pEvent )
  1015. {
  1016. case VActor::k_MountEvent :
  1017. {
  1018. // Set Control State.
  1019. setControlState( k_PathControlState );
  1020. // Store Path.
  1021. mMountedPath = dynamic_cast<VPath*>( mObject->getObjectMount() );
  1022. } break;
  1023. case VActor::k_UnmountEvent :
  1024. {
  1025. // Clear Control State.
  1026. clearControlState( k_PathControlState );
  1027. // Clear Path.
  1028. mMountedPath = NULL;
  1029. // Clear X & Y Velocity.
  1030. setVelocity( VectorF( 0.f, 0.f, mVelocity.z ) );
  1031. } break;
  1032. }
  1033. }
  1034. //-----------------------------------------------------------------------------
  1035. //
  1036. // VActorPhysicsController::packUpdate( pConnection, pMask, pStream );
  1037. //
  1038. // ...
  1039. //
  1040. //-----------------------------------------------------------------------------
  1041. U32 VActorPhysicsController::packUpdate( NetConnection *pConnection, U32 pMask, BitStream *pStream )
  1042. {
  1043. // Return Mask.
  1044. U32 retMask = 0;
  1045. // Valid Object?
  1046. if ( !pStream->writeFlag( isValidObject() ) )
  1047. {
  1048. return retMask;
  1049. }
  1050. // Write Move?
  1051. const bool writeMove = ( pMask & VActor::MoveMask ) && !isPathing();
  1052. if ( pStream->writeFlag( writeMove ) )
  1053. {
  1054. // Write Position.
  1055. const Point3F &position = getPosition();
  1056. pStream->write( position.x );
  1057. pStream->write( position.y );
  1058. pStream->write( position.z );
  1059. }
  1060. return retMask;
  1061. }
  1062. //-----------------------------------------------------------------------------
  1063. //
  1064. // VActorPhysicsController::unpackUpdate( pConnection, pStream );
  1065. //
  1066. // ...
  1067. //
  1068. //-----------------------------------------------------------------------------
  1069. void VActorPhysicsController::unpackUpdate( NetConnection *pConnection, BitStream *pStream )
  1070. {
  1071. // Valid Object?
  1072. if ( !pStream->readFlag() )
  1073. {
  1074. return;
  1075. }
  1076. // Read Move?
  1077. if ( pStream->readFlag() )
  1078. {
  1079. // Read Position.
  1080. Point3F position;
  1081. pStream->read( &position.x );
  1082. pStream->read( &position.y );
  1083. pStream->read( &position.z );
  1084. // Apply.
  1085. setPosition( position );
  1086. }
  1087. }