px3Body.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "T3D/physics/physx3/px3Body.h"
  24. #include "T3D/physics/physx3/px3.h"
  25. #include "T3D/physics/physx3/px3Casts.h"
  26. #include "T3D/physics/physx3/px3World.h"
  27. #include "T3D/physics/physx3/px3Collision.h"
  28. #include "console/console.h"
  29. #include "console/consoleTypes.h"
  30. Px3Body::Px3Body() :
  31. mActor( NULL ),
  32. mMaterial( NULL ),
  33. mWorld( NULL ),
  34. mBodyFlags( 0 ),
  35. mIsEnabled( true ),
  36. mIsStatic(false)
  37. {
  38. }
  39. Px3Body::~Px3Body()
  40. {
  41. _releaseActor();
  42. }
  43. void Px3Body::_releaseActor()
  44. {
  45. if ( !mActor )
  46. return;
  47. mActor->userData = NULL;
  48. SafeReleasePhysx(mActor);
  49. mBodyFlags = 0;
  50. if ( mMaterial )
  51. {
  52. mMaterial->release();
  53. }
  54. mColShape = NULL;
  55. }
  56. bool Px3Body::init( PhysicsCollision *shape,
  57. F32 mass,
  58. U32 bodyFlags,
  59. SceneObject *obj,
  60. PhysicsWorld *world )
  61. {
  62. AssertFatal( obj, "Px3Body::init - Got a null scene object!" );
  63. AssertFatal( world, "Px3Body::init - Got a null world!" );
  64. AssertFatal( dynamic_cast<Px3World*>( world ), "Px3Body::init - The world is the wrong type!" );
  65. AssertFatal( shape, "Px3Body::init - Got a null collision shape!" );
  66. AssertFatal( dynamic_cast<Px3Collision*>( shape ), "Px3Body::init - The collision shape is the wrong type!" );
  67. AssertFatal( !((Px3Collision*)shape)->getShapes().empty(), "Px3Body::init - Got empty collision shape!" );
  68. // Cleanup any previous actor.
  69. _releaseActor();
  70. mWorld = (Px3World*)world;
  71. mColShape = (Px3Collision*)shape;
  72. mBodyFlags = bodyFlags;
  73. const bool isKinematic = mBodyFlags & BF_KINEMATIC;
  74. const bool isTrigger = mBodyFlags & BF_TRIGGER;
  75. const bool isDebris = mBodyFlags & BF_DEBRIS;
  76. if ( isKinematic )
  77. {
  78. mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
  79. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  80. actor->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, true);
  81. actor->setMass(getMax( mass, 1.0f ));
  82. }
  83. else if ( mass > 0.0f )
  84. {
  85. mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
  86. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  87. actor->setMaxAngularVelocity(80.f);
  88. }
  89. else
  90. {
  91. mActor = gPhysics3SDK->createRigidStatic(physx::PxTransform(physx::PxIDENTITY()));
  92. mIsStatic = true;
  93. }
  94. mMaterial = gPhysics3SDK->createMaterial(0.6f,0.4f,0.1f);
  95. // Add all the shapes.
  96. const Vector<Px3CollisionDesc*> &shapes = mColShape->getShapes();
  97. for ( U32 i=0; i < shapes.size(); i++ )
  98. {
  99. Px3CollisionDesc* desc = shapes[i];
  100. if( mass > 0.0f )
  101. {
  102. if(desc->pGeometry->getType() == physx::PxGeometryType::eTRIANGLEMESH)
  103. {
  104. Con::errorf("PhysX3 Dynamic Triangle Mesh is not supported.");
  105. }
  106. }
  107. physx::PxShape * pShape = physx::PxRigidActorExt::createExclusiveShape(*mActor, *desc->pGeometry, *mMaterial);
  108. physx::PxFilterData colData;
  109. if(isDebris)
  110. colData.word0 = PX3_DEBRIS;
  111. else if(isTrigger)
  112. colData.word0 = PX3_TRIGGER;
  113. else
  114. colData.word0 = PX3_DEFAULT;
  115. //set local pose - actor->createShape with a local pose is deprecated in physx 3.3
  116. pShape->setLocalPose(desc->pose);
  117. //set the skin width
  118. pShape->setContactOffset(0.01f);
  119. pShape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !isTrigger);
  120. pShape->setFlag(physx::PxShapeFlag::eSCENE_QUERY_SHAPE,true);
  121. pShape->setSimulationFilterData(colData);
  122. pShape->setQueryFilterData(colData);
  123. }
  124. //mass & intertia has to be set after creating the shape
  125. if ( mass > 0.0f )
  126. {
  127. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  128. physx::PxRigidBodyExt::setMassAndUpdateInertia(*actor,mass);
  129. }
  130. mWorld->getScene()->addActor(*mActor);
  131. mIsEnabled = true;
  132. if ( isDebris )
  133. mActor->setDominanceGroup( 31 );
  134. mUserData.setObject( obj );
  135. mUserData.setBody( this );
  136. mActor->userData = &mUserData;
  137. return true;
  138. }
  139. void Px3Body::setMaterial( F32 restitution,
  140. F32 friction,
  141. F32 staticFriction )
  142. {
  143. AssertFatal( mActor, "Px3Body::setMaterial - The actor is null!" );
  144. if ( isDynamic() )
  145. {
  146. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  147. actor->wakeUp();
  148. }
  149. mMaterial->setRestitution(restitution);
  150. mMaterial->setStaticFriction(staticFriction);
  151. mMaterial->setDynamicFriction(friction);
  152. }
  153. void Px3Body::setSleepThreshold( F32 linear, F32 angular )
  154. {
  155. AssertFatal( mActor, "Px3Body::setSleepThreshold - The actor is null!" );
  156. if(mIsStatic)
  157. return;
  158. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  159. physx::PxF32 massNormalized= (linear*linear+angular*angular)/2.0f;
  160. actor->setSleepThreshold(massNormalized);
  161. }
  162. void Px3Body::setDamping( F32 linear, F32 angular )
  163. {
  164. AssertFatal( mActor, "Px3Body::setDamping - The actor is null!" );
  165. if(mIsStatic)
  166. return;
  167. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  168. actor->setLinearDamping( linear );
  169. actor->setAngularDamping( angular );
  170. }
  171. void Px3Body::getState( PhysicsState *outState )
  172. {
  173. AssertFatal( mActor, "Px3Body::getState - The actor is null!" );
  174. AssertFatal( isDynamic(), "Px3Body::getState - This call is only for dynamics!" );
  175. outState->position = px3Cast<Point3F>( mActor->getGlobalPose().p );
  176. outState->orientation = px3Cast<QuatF>( mActor->getGlobalPose().q );
  177. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  178. outState->linVelocity = px3Cast<Point3F>( actor->getLinearVelocity() );
  179. outState->angVelocity = px3Cast<Point3F>( actor->getAngularVelocity() );
  180. outState->sleeping = actor->isSleeping();
  181. outState->momentum = px3Cast<Point3F>( (1.0f/actor->getMass()) * actor->getLinearVelocity() );
  182. }
  183. F32 Px3Body::getMass() const
  184. {
  185. AssertFatal( mActor, "PxBody::getCMassPosition - The actor is null!" );
  186. if(mIsStatic)
  187. return 0;
  188. const physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  189. return actor->getMass();
  190. }
  191. Point3F Px3Body::getCMassPosition() const
  192. {
  193. AssertFatal( mActor, "Px3Body::getCMassPosition - The actor is null!" );
  194. if(mIsStatic)
  195. return px3Cast<Point3F>(mActor->getGlobalPose().p);
  196. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  197. physx::PxTransform pose = actor->getGlobalPose() * actor->getCMassLocalPose();
  198. return px3Cast<Point3F>(pose.p);
  199. }
  200. void Px3Body::setLinVelocity( const Point3F &vel )
  201. {
  202. AssertFatal( mActor, "Px3Body::setLinVelocity - The actor is null!" );
  203. AssertFatal( isDynamic(), "Px3Body::setLinVelocity - This call is only for dynamics!" );
  204. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  205. actor->setLinearVelocity( px3Cast<physx::PxVec3>( vel ) );
  206. }
  207. void Px3Body::setAngVelocity( const Point3F &vel )
  208. {
  209. AssertFatal( mActor, "Px3Body::setAngVelocity - The actor is null!" );
  210. AssertFatal( isDynamic(), "Px3Body::setAngVelocity - This call is only for dynamics!" );
  211. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  212. actor->setAngularVelocity(px3Cast<physx::PxVec3>( vel ) );
  213. }
  214. Point3F Px3Body::getLinVelocity() const
  215. {
  216. AssertFatal( mActor, "Px3Body::getLinVelocity - The actor is null!" );
  217. AssertFatal( isDynamic(), "Px3Body::getLinVelocity - This call is only for dynamics!" );
  218. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  219. return px3Cast<Point3F>( actor->getLinearVelocity() );
  220. }
  221. Point3F Px3Body::getAngVelocity() const
  222. {
  223. AssertFatal( mActor, "Px3Body::getAngVelocity - The actor is null!" );
  224. AssertFatal( isDynamic(), "Px3Body::getAngVelocity - This call is only for dynamics!" );
  225. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  226. return px3Cast<Point3F>( actor->getAngularVelocity() );
  227. }
  228. void Px3Body::setSleeping( bool sleeping )
  229. {
  230. AssertFatal( mActor, "Px3Body::setSleeping - The actor is null!" );
  231. AssertFatal( isDynamic(), "Px3Body::setSleeping - This call is only for dynamics!" );
  232. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  233. if ( sleeping )
  234. actor->putToSleep();
  235. else
  236. actor->wakeUp();
  237. }
  238. bool Px3Body::isDynamic() const
  239. {
  240. AssertFatal( mActor, "PxBody::isDynamic - The actor is null!" );
  241. return !mIsStatic && ( mBodyFlags & BF_KINEMATIC ) == 0;
  242. }
  243. PhysicsWorld* Px3Body::getWorld()
  244. {
  245. return mWorld;
  246. }
  247. PhysicsCollision* Px3Body::getColShape()
  248. {
  249. return mColShape;
  250. }
  251. MatrixF& Px3Body::getTransform( MatrixF *outMatrix )
  252. {
  253. AssertFatal( mActor, "Px3Body::getTransform - The actor is null!" );
  254. *outMatrix = px3Cast<MatrixF>(mActor->getGlobalPose());
  255. return *outMatrix;
  256. }
  257. Box3F Px3Body::getWorldBounds()
  258. {
  259. AssertFatal( mActor, "Px3Body::getTransform - The actor is null!" );
  260. physx::PxBounds3 bounds;
  261. bounds.setEmpty();
  262. physx::PxBounds3 shapeBounds;
  263. U32 shapeCount = mActor->getNbShapes();
  264. physx::PxShape **shapes = new physx::PxShape*[shapeCount];
  265. mActor->getShapes(shapes, shapeCount);
  266. for ( U32 i = 0; i < shapeCount; i++ )
  267. {
  268. // Get the shape's bounds.
  269. shapeBounds = physx::PxShapeExt::getWorldBounds(*shapes[i],*mActor);
  270. // Combine them into the total bounds.
  271. bounds.include( shapeBounds );
  272. }
  273. delete [] shapes;
  274. return px3Cast<Box3F>( bounds );
  275. }
  276. void Px3Body::setSimulationEnabled( bool enabled )
  277. {
  278. if ( mIsEnabled == enabled )
  279. return;
  280. //Don't need to enable/disable eSIMULATION_SHAPE for trigger,it's disabled permanently
  281. if(mBodyFlags & BF_TRIGGER)
  282. return;
  283. U32 shapeCount = mActor->getNbShapes();
  284. physx::PxShape **shapes = new physx::PxShape*[shapeCount];
  285. mActor->getShapes(shapes, shapeCount);
  286. for ( S32 i = 0; i < mActor->getNbShapes(); i++ )
  287. {
  288. shapes[i]->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE,!mIsEnabled);//?????
  289. }
  290. delete [] shapes;
  291. }
  292. void Px3Body::setTransform( const MatrixF &transform )
  293. {
  294. AssertFatal( mActor, "Px3Body::setTransform - The actor is null!" );
  295. mActor->setGlobalPose(px3Cast<physx::PxTransform>(transform),false);
  296. if(mIsStatic)
  297. return;
  298. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  299. bool kinematic = actor->getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC;
  300. // If its dynamic we have more to do.
  301. if ( isDynamic() && !kinematic )
  302. {
  303. actor->setLinearVelocity( physx::PxVec3(0) );
  304. actor->setAngularVelocity( physx::PxVec3(0) );
  305. actor->wakeUp();
  306. }
  307. }
  308. void Px3Body::applyCorrection( const MatrixF &transform )
  309. {
  310. AssertFatal( mActor, "Px3Body::applyCorrection - The actor is null!" );
  311. AssertFatal( isDynamic(), "Px3Body::applyCorrection - This call is only for dynamics!" );
  312. mActor->setGlobalPose( px3Cast<physx::PxTransform>(transform) );
  313. }
  314. void Px3Body::applyImpulse( const Point3F &origin, const Point3F &force )
  315. {
  316. AssertFatal( mActor, "Px3Body::applyImpulse - The actor is null!" );
  317. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  318. if ( mIsEnabled && isDynamic() )
  319. physx::PxRigidBodyExt::addForceAtPos( *actor,px3Cast<physx::PxVec3>(force), px3Cast<physx::PxVec3>(origin), physx::PxForceMode::eIMPULSE );
  320. }
  321. void Px3Body::applyTorque(const Point3F &torque)
  322. {
  323. AssertFatal(mActor, "Px3Body::applyImpulse - The actor is null!");
  324. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  325. if (mIsEnabled && isDynamic())
  326. actor->addTorque(px3Cast<physx::PxVec3>(torque), physx::PxForceMode::eFORCE, true);
  327. }
  328. void Px3Body::applyForce(const Point3F &force)
  329. {
  330. AssertFatal(mActor, "Px3Body::applyTorque - The actor is null!");
  331. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  332. if (mIsEnabled && isDynamic())
  333. actor->addForce(px3Cast<physx::PxVec3>(force), physx::PxForceMode::eFORCE, true);
  334. }
  335. void Px3Body::findContact(SceneObject **contactObject,
  336. VectorF *contactNormal,
  337. Vector<SceneObject*> *outOverlapObjects) const
  338. {
  339. }
  340. void Px3Body::moveKinematicTo(const MatrixF &transform)
  341. {
  342. AssertFatal(mActor, "Px3Body::moveKinematicTo - The actor is null!");
  343. const bool isKinematic = mBodyFlags & BF_KINEMATIC;
  344. if (!isKinematic)
  345. {
  346. Con::errorf("Px3Body::moveKinematicTo is only for kinematic bodies.");
  347. return;
  348. }
  349. mWorld->lockScene();
  350. physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
  351. actor->setKinematicTarget(px3Cast<physx::PxTransform>(transform));
  352. mWorld->unlockScene();
  353. }