VActorPhysicsController.cpp 36 KB

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