BodyInterface.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <Jolt/Jolt.h>
  5. #include <Jolt/Physics/Collision/BroadPhase/BroadPhase.h>
  6. #include <Jolt/Physics/Body/Body.h>
  7. #include <Jolt/Physics/Body/BodyManager.h>
  8. #include <Jolt/Physics/Body/BodyInterface.h>
  9. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  10. #include <Jolt/Physics/Body/BodyLock.h>
  11. #include <Jolt/Physics/Body/BodyLockMulti.h>
  12. #include <Jolt/Physics/Collision/PhysicsMaterial.h>
  13. #include <Jolt/Physics/Constraints/TwoBodyConstraint.h>
  14. JPH_NAMESPACE_BEGIN
  15. Body *BodyInterface::CreateBody(const BodyCreationSettings &inSettings)
  16. {
  17. Body *body = mBodyManager->AllocateBody(inSettings);
  18. if (!mBodyManager->AddBody(body))
  19. {
  20. mBodyManager->FreeBody(body);
  21. return nullptr;
  22. }
  23. return body;
  24. }
  25. Body *BodyInterface::CreateSoftBody(const SoftBodyCreationSettings &inSettings)
  26. {
  27. Body *body = mBodyManager->AllocateSoftBody(inSettings);
  28. if (!mBodyManager->AddBody(body))
  29. {
  30. mBodyManager->FreeBody(body);
  31. return nullptr;
  32. }
  33. return body;
  34. }
  35. Body *BodyInterface::CreateBodyWithID(const BodyID &inBodyID, const BodyCreationSettings &inSettings)
  36. {
  37. Body *body = mBodyManager->AllocateBody(inSettings);
  38. if (!mBodyManager->AddBodyWithCustomID(body, inBodyID))
  39. {
  40. mBodyManager->FreeBody(body);
  41. return nullptr;
  42. }
  43. return body;
  44. }
  45. Body *BodyInterface::CreateSoftBodyWithID(const BodyID &inBodyID, const SoftBodyCreationSettings &inSettings)
  46. {
  47. Body *body = mBodyManager->AllocateSoftBody(inSettings);
  48. if (!mBodyManager->AddBodyWithCustomID(body, inBodyID))
  49. {
  50. mBodyManager->FreeBody(body);
  51. return nullptr;
  52. }
  53. return body;
  54. }
  55. Body *BodyInterface::CreateBodyWithoutID(const BodyCreationSettings &inSettings) const
  56. {
  57. return mBodyManager->AllocateBody(inSettings);
  58. }
  59. Body *BodyInterface::CreateSoftBodyWithoutID(const SoftBodyCreationSettings &inSettings) const
  60. {
  61. return mBodyManager->AllocateSoftBody(inSettings);
  62. }
  63. void BodyInterface::DestroyBodyWithoutID(Body *inBody) const
  64. {
  65. mBodyManager->FreeBody(inBody);
  66. }
  67. bool BodyInterface::AssignBodyID(Body *ioBody)
  68. {
  69. return mBodyManager->AddBody(ioBody);
  70. }
  71. bool BodyInterface::AssignBodyID(Body *ioBody, const BodyID &inBodyID)
  72. {
  73. return mBodyManager->AddBodyWithCustomID(ioBody, inBodyID);
  74. }
  75. Body *BodyInterface::UnassignBodyID(const BodyID &inBodyID)
  76. {
  77. Body *body = nullptr;
  78. mBodyManager->RemoveBodies(&inBodyID, 1, &body);
  79. return body;
  80. }
  81. void BodyInterface::UnassignBodyIDs(const BodyID *inBodyIDs, int inNumber, Body **outBodies)
  82. {
  83. mBodyManager->RemoveBodies(inBodyIDs, inNumber, outBodies);
  84. }
  85. void BodyInterface::DestroyBody(const BodyID &inBodyID)
  86. {
  87. mBodyManager->DestroyBodies(&inBodyID, 1);
  88. }
  89. void BodyInterface::DestroyBodies(const BodyID *inBodyIDs, int inNumber)
  90. {
  91. mBodyManager->DestroyBodies(inBodyIDs, inNumber);
  92. }
  93. void BodyInterface::AddBody(const BodyID &inBodyID, EActivation inActivationMode)
  94. {
  95. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  96. if (lock.Succeeded())
  97. {
  98. const Body &body = lock.GetBody();
  99. // Add to broadphase
  100. BodyID id = inBodyID;
  101. BroadPhase::AddState add_state = mBroadPhase->AddBodiesPrepare(&id, 1);
  102. mBroadPhase->AddBodiesFinalize(&id, 1, add_state);
  103. // Optionally activate body
  104. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  105. mBodyManager->ActivateBodies(&inBodyID, 1);
  106. }
  107. }
  108. void BodyInterface::RemoveBody(const BodyID &inBodyID)
  109. {
  110. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  111. if (lock.Succeeded())
  112. {
  113. const Body &body = lock.GetBody();
  114. // Deactivate body
  115. if (body.IsActive())
  116. mBodyManager->DeactivateBodies(&inBodyID, 1);
  117. // Remove from broadphase
  118. BodyID id = inBodyID;
  119. mBroadPhase->RemoveBodies(&id, 1);
  120. }
  121. }
  122. bool BodyInterface::IsAdded(const BodyID &inBodyID) const
  123. {
  124. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  125. return lock.SucceededAndIsInBroadPhase();
  126. }
  127. BodyID BodyInterface::CreateAndAddBody(const BodyCreationSettings &inSettings, EActivation inActivationMode)
  128. {
  129. const Body *b = CreateBody(inSettings);
  130. if (b == nullptr)
  131. return BodyID(); // Out of bodies
  132. AddBody(b->GetID(), inActivationMode);
  133. return b->GetID();
  134. }
  135. BodyID BodyInterface::CreateAndAddSoftBody(const SoftBodyCreationSettings &inSettings, EActivation inActivationMode)
  136. {
  137. const Body *b = CreateSoftBody(inSettings);
  138. if (b == nullptr)
  139. return BodyID(); // Out of bodies
  140. AddBody(b->GetID(), inActivationMode);
  141. return b->GetID();
  142. }
  143. BodyInterface::AddState BodyInterface::AddBodiesPrepare(BodyID *ioBodies, int inNumber)
  144. {
  145. return mBroadPhase->AddBodiesPrepare(ioBodies, inNumber);
  146. }
  147. void BodyInterface::AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState, EActivation inActivationMode)
  148. {
  149. BodyLockMultiWrite lock(*mBodyLockInterface, ioBodies, inNumber);
  150. // Add to broadphase
  151. mBroadPhase->AddBodiesFinalize(ioBodies, inNumber, inAddState);
  152. // Optionally activate bodies
  153. if (inActivationMode == EActivation::Activate)
  154. mBodyManager->ActivateBodies(ioBodies, inNumber);
  155. }
  156. void BodyInterface::AddBodiesAbort(BodyID *ioBodies, int inNumber, AddState inAddState)
  157. {
  158. mBroadPhase->AddBodiesAbort(ioBodies, inNumber, inAddState);
  159. }
  160. void BodyInterface::RemoveBodies(BodyID *ioBodies, int inNumber)
  161. {
  162. BodyLockMultiWrite lock(*mBodyLockInterface, ioBodies, inNumber);
  163. // Deactivate bodies
  164. mBodyManager->DeactivateBodies(ioBodies, inNumber);
  165. // Remove from broadphase
  166. mBroadPhase->RemoveBodies(ioBodies, inNumber);
  167. }
  168. void BodyInterface::ActivateBody(const BodyID &inBodyID)
  169. {
  170. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  171. if (lock.Succeeded())
  172. {
  173. const Body &body = lock.GetBody();
  174. if (!body.IsActive())
  175. mBodyManager->ActivateBodies(&inBodyID, 1);
  176. }
  177. }
  178. void BodyInterface::ActivateBodies(const BodyID *inBodyIDs, int inNumber)
  179. {
  180. BodyLockMultiWrite lock(*mBodyLockInterface, inBodyIDs, inNumber);
  181. mBodyManager->ActivateBodies(inBodyIDs, inNumber);
  182. }
  183. void BodyInterface::DeactivateBody(const BodyID &inBodyID)
  184. {
  185. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  186. if (lock.Succeeded())
  187. {
  188. const Body &body = lock.GetBody();
  189. if (body.IsActive())
  190. mBodyManager->DeactivateBodies(&inBodyID, 1);
  191. }
  192. }
  193. void BodyInterface::DeactivateBodies(const BodyID *inBodyIDs, int inNumber)
  194. {
  195. BodyLockMultiWrite lock(*mBodyLockInterface, inBodyIDs, inNumber);
  196. mBodyManager->DeactivateBodies(inBodyIDs, inNumber);
  197. }
  198. bool BodyInterface::IsActive(const BodyID &inBodyID) const
  199. {
  200. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  201. return lock.Succeeded() && lock.GetBody().IsActive();
  202. }
  203. TwoBodyConstraint *BodyInterface::CreateConstraint(const TwoBodyConstraintSettings *inSettings, const BodyID &inBodyID1, const BodyID &inBodyID2)
  204. {
  205. BodyID constraint_bodies[] = { inBodyID1, inBodyID2 };
  206. BodyLockMultiWrite lock(*mBodyLockInterface, constraint_bodies, 2);
  207. Body *body1 = lock.GetBody(0);
  208. Body *body2 = lock.GetBody(1);
  209. JPH_ASSERT(body1 != body2);
  210. JPH_ASSERT(body1 != nullptr || body2 != nullptr);
  211. return inSettings->Create(body1 != nullptr? *body1 : Body::sFixedToWorld, body2 != nullptr? *body2 : Body::sFixedToWorld);
  212. }
  213. void BodyInterface::ActivateConstraint(const TwoBodyConstraint *inConstraint)
  214. {
  215. BodyID bodies[] = { inConstraint->GetBody1()->GetID(), inConstraint->GetBody2()->GetID() };
  216. ActivateBodies(bodies, 2);
  217. }
  218. RefConst<Shape> BodyInterface::GetShape(const BodyID &inBodyID) const
  219. {
  220. RefConst<Shape> shape;
  221. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  222. if (lock.Succeeded())
  223. shape = lock.GetBody().GetShape();
  224. return shape;
  225. }
  226. void BodyInterface::SetShape(const BodyID &inBodyID, const Shape *inShape, bool inUpdateMassProperties, EActivation inActivationMode) const
  227. {
  228. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  229. if (lock.Succeeded())
  230. {
  231. Body &body = lock.GetBody();
  232. // Check if shape actually changed
  233. if (body.GetShape() != inShape)
  234. {
  235. // Update the shape
  236. body.SetShapeInternal(inShape, inUpdateMassProperties);
  237. // Flag collision cache invalid for this body
  238. mBodyManager->InvalidateContactCacheForBody(body);
  239. // Notify broadphase of change
  240. if (body.IsInBroadPhase())
  241. {
  242. BodyID id = body.GetID();
  243. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  244. }
  245. // Optionally activate body
  246. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  247. mBodyManager->ActivateBodies(&inBodyID, 1);
  248. }
  249. }
  250. }
  251. void BodyInterface::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inPreviousCenterOfMass, bool inUpdateMassProperties, EActivation inActivationMode) const
  252. {
  253. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  254. if (lock.Succeeded())
  255. {
  256. Body &body = lock.GetBody();
  257. // Update center of mass, mass and inertia
  258. body.UpdateCenterOfMassInternal(inPreviousCenterOfMass, inUpdateMassProperties);
  259. // Recalculate bounding box
  260. body.CalculateWorldSpaceBoundsInternal();
  261. // Flag collision cache invalid for this body
  262. mBodyManager->InvalidateContactCacheForBody(body);
  263. // Notify broadphase of change
  264. if (body.IsInBroadPhase())
  265. {
  266. BodyID id = body.GetID();
  267. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  268. }
  269. // Optionally activate body
  270. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  271. mBodyManager->ActivateBodies(&inBodyID, 1);
  272. }
  273. }
  274. void BodyInterface::SetObjectLayer(const BodyID &inBodyID, ObjectLayer inLayer)
  275. {
  276. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  277. if (lock.Succeeded())
  278. {
  279. Body &body = lock.GetBody();
  280. // Check if layer actually changed, updating the broadphase is rather expensive
  281. if (body.GetObjectLayer() != inLayer)
  282. {
  283. // Update the layer on the body
  284. mBodyManager->SetBodyObjectLayerInternal(body, inLayer);
  285. // Notify broadphase of change
  286. if (body.IsInBroadPhase())
  287. {
  288. BodyID id = body.GetID();
  289. mBroadPhase->NotifyBodiesLayerChanged(&id, 1);
  290. }
  291. }
  292. }
  293. }
  294. ObjectLayer BodyInterface::GetObjectLayer(const BodyID &inBodyID) const
  295. {
  296. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  297. if (lock.Succeeded())
  298. return lock.GetBody().GetObjectLayer();
  299. else
  300. return cObjectLayerInvalid;
  301. }
  302. void BodyInterface::SetPositionAndRotation(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode)
  303. {
  304. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  305. if (lock.Succeeded())
  306. {
  307. Body &body = lock.GetBody();
  308. // Update the position
  309. body.SetPositionAndRotationInternal(inPosition, inRotation);
  310. // Notify broadphase of change
  311. if (body.IsInBroadPhase())
  312. {
  313. BodyID id = body.GetID();
  314. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  315. }
  316. // Optionally activate body
  317. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  318. mBodyManager->ActivateBodies(&inBodyID, 1);
  319. }
  320. }
  321. void BodyInterface::SetPositionAndRotationWhenChanged(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode)
  322. {
  323. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  324. if (lock.Succeeded())
  325. {
  326. Body &body = lock.GetBody();
  327. // Check if there is enough change
  328. if (!body.GetPosition().IsClose(inPosition)
  329. || !body.GetRotation().IsClose(inRotation))
  330. {
  331. // Update the position
  332. body.SetPositionAndRotationInternal(inPosition, inRotation);
  333. // Notify broadphase of change
  334. if (body.IsInBroadPhase())
  335. {
  336. BodyID id = body.GetID();
  337. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  338. }
  339. // Optionally activate body
  340. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  341. mBodyManager->ActivateBodies(&inBodyID, 1);
  342. }
  343. }
  344. }
  345. void BodyInterface::GetPositionAndRotation(const BodyID &inBodyID, RVec3 &outPosition, Quat &outRotation) const
  346. {
  347. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  348. if (lock.Succeeded())
  349. {
  350. const Body &body = lock.GetBody();
  351. outPosition = body.GetPosition();
  352. outRotation = body.GetRotation();
  353. }
  354. else
  355. {
  356. outPosition = RVec3::sZero();
  357. outRotation = Quat::sIdentity();
  358. }
  359. }
  360. void BodyInterface::SetPosition(const BodyID &inBodyID, RVec3Arg inPosition, EActivation inActivationMode)
  361. {
  362. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  363. if (lock.Succeeded())
  364. {
  365. Body &body = lock.GetBody();
  366. // Update the position
  367. body.SetPositionAndRotationInternal(inPosition, body.GetRotation());
  368. // Notify broadphase of change
  369. if (body.IsInBroadPhase())
  370. {
  371. BodyID id = body.GetID();
  372. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  373. }
  374. // Optionally activate body
  375. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  376. mBodyManager->ActivateBodies(&inBodyID, 1);
  377. }
  378. }
  379. RVec3 BodyInterface::GetPosition(const BodyID &inBodyID) const
  380. {
  381. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  382. if (lock.Succeeded())
  383. return lock.GetBody().GetPosition();
  384. else
  385. return RVec3::sZero();
  386. }
  387. RVec3 BodyInterface::GetCenterOfMassPosition(const BodyID &inBodyID) const
  388. {
  389. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  390. if (lock.Succeeded())
  391. return lock.GetBody().GetCenterOfMassPosition();
  392. else
  393. return RVec3::sZero();
  394. }
  395. void BodyInterface::SetRotation(const BodyID &inBodyID, QuatArg inRotation, EActivation inActivationMode)
  396. {
  397. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  398. if (lock.Succeeded())
  399. {
  400. Body &body = lock.GetBody();
  401. // Update the position
  402. body.SetPositionAndRotationInternal(body.GetPosition(), inRotation);
  403. // Notify broadphase of change
  404. if (body.IsInBroadPhase())
  405. {
  406. BodyID id = body.GetID();
  407. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  408. }
  409. // Optionally activate body
  410. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  411. mBodyManager->ActivateBodies(&inBodyID, 1);
  412. }
  413. }
  414. Quat BodyInterface::GetRotation(const BodyID &inBodyID) const
  415. {
  416. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  417. if (lock.Succeeded())
  418. return lock.GetBody().GetRotation();
  419. else
  420. return Quat::sIdentity();
  421. }
  422. RMat44 BodyInterface::GetWorldTransform(const BodyID &inBodyID) const
  423. {
  424. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  425. if (lock.Succeeded())
  426. return lock.GetBody().GetWorldTransform();
  427. else
  428. return RMat44::sIdentity();
  429. }
  430. RMat44 BodyInterface::GetCenterOfMassTransform(const BodyID &inBodyID) const
  431. {
  432. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  433. if (lock.Succeeded())
  434. return lock.GetBody().GetCenterOfMassTransform();
  435. else
  436. return RMat44::sIdentity();
  437. }
  438. void BodyInterface::MoveKinematic(const BodyID &inBodyID, RVec3Arg inTargetPosition, QuatArg inTargetRotation, float inDeltaTime)
  439. {
  440. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  441. if (lock.Succeeded())
  442. {
  443. Body &body = lock.GetBody();
  444. body.MoveKinematic(inTargetPosition, inTargetRotation, inDeltaTime);
  445. if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()))
  446. mBodyManager->ActivateBodies(&inBodyID, 1);
  447. }
  448. }
  449. void BodyInterface::SetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity)
  450. {
  451. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  452. if (lock.Succeeded())
  453. {
  454. Body &body = lock.GetBody();
  455. if (!body.IsStatic())
  456. {
  457. body.SetLinearVelocityClamped(inLinearVelocity);
  458. body.SetAngularVelocityClamped(inAngularVelocity);
  459. if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()))
  460. mBodyManager->ActivateBodies(&inBodyID, 1);
  461. }
  462. }
  463. }
  464. void BodyInterface::GetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const
  465. {
  466. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  467. if (lock.Succeeded())
  468. {
  469. const Body &body = lock.GetBody();
  470. if (!body.IsStatic())
  471. {
  472. outLinearVelocity = body.GetLinearVelocity();
  473. outAngularVelocity = body.GetAngularVelocity();
  474. return;
  475. }
  476. }
  477. outLinearVelocity = outAngularVelocity = Vec3::sZero();
  478. }
  479. void BodyInterface::SetLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity)
  480. {
  481. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  482. if (lock.Succeeded())
  483. {
  484. Body &body = lock.GetBody();
  485. if (!body.IsStatic())
  486. {
  487. body.SetLinearVelocityClamped(inLinearVelocity);
  488. if (!body.IsActive() && !inLinearVelocity.IsNearZero())
  489. mBodyManager->ActivateBodies(&inBodyID, 1);
  490. }
  491. }
  492. }
  493. Vec3 BodyInterface::GetLinearVelocity(const BodyID &inBodyID) const
  494. {
  495. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  496. if (lock.Succeeded())
  497. {
  498. const Body &body = lock.GetBody();
  499. if (!body.IsStatic())
  500. return body.GetLinearVelocity();
  501. }
  502. return Vec3::sZero();
  503. }
  504. void BodyInterface::AddLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity)
  505. {
  506. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  507. if (lock.Succeeded())
  508. {
  509. Body &body = lock.GetBody();
  510. if (!body.IsStatic())
  511. {
  512. body.SetLinearVelocityClamped(body.GetLinearVelocity() + inLinearVelocity);
  513. if (!body.IsActive() && !body.GetLinearVelocity().IsNearZero())
  514. mBodyManager->ActivateBodies(&inBodyID, 1);
  515. }
  516. }
  517. }
  518. void BodyInterface::AddLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity)
  519. {
  520. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  521. if (lock.Succeeded())
  522. {
  523. Body &body = lock.GetBody();
  524. if (!body.IsStatic())
  525. {
  526. body.SetLinearVelocityClamped(body.GetLinearVelocity() + inLinearVelocity);
  527. body.SetAngularVelocityClamped(body.GetAngularVelocity() + inAngularVelocity);
  528. if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()))
  529. mBodyManager->ActivateBodies(&inBodyID, 1);
  530. }
  531. }
  532. }
  533. void BodyInterface::SetAngularVelocity(const BodyID &inBodyID, Vec3Arg inAngularVelocity)
  534. {
  535. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  536. if (lock.Succeeded())
  537. {
  538. Body &body = lock.GetBody();
  539. if (!body.IsStatic())
  540. {
  541. body.SetAngularVelocityClamped(inAngularVelocity);
  542. if (!body.IsActive() && !inAngularVelocity.IsNearZero())
  543. mBodyManager->ActivateBodies(&inBodyID, 1);
  544. }
  545. }
  546. }
  547. Vec3 BodyInterface::GetAngularVelocity(const BodyID &inBodyID) const
  548. {
  549. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  550. if (lock.Succeeded())
  551. {
  552. const Body &body = lock.GetBody();
  553. if (!body.IsStatic())
  554. return body.GetAngularVelocity();
  555. }
  556. return Vec3::sZero();
  557. }
  558. Vec3 BodyInterface::GetPointVelocity(const BodyID &inBodyID, RVec3Arg inPoint) const
  559. {
  560. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  561. if (lock.Succeeded())
  562. {
  563. const Body &body = lock.GetBody();
  564. if (!body.IsStatic())
  565. return body.GetPointVelocity(inPoint);
  566. }
  567. return Vec3::sZero();
  568. }
  569. void BodyInterface::AddForce(const BodyID &inBodyID, Vec3Arg inForce)
  570. {
  571. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  572. if (lock.Succeeded())
  573. {
  574. Body &body = lock.GetBody();
  575. if (body.IsDynamic())
  576. {
  577. body.AddForce(inForce);
  578. if (!body.IsActive())
  579. mBodyManager->ActivateBodies(&inBodyID, 1);
  580. }
  581. }
  582. }
  583. void BodyInterface::AddForce(const BodyID &inBodyID, Vec3Arg inForce, RVec3Arg inPoint)
  584. {
  585. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  586. if (lock.Succeeded())
  587. {
  588. Body &body = lock.GetBody();
  589. if (body.IsDynamic())
  590. {
  591. body.AddForce(inForce, inPoint);
  592. if (!body.IsActive())
  593. mBodyManager->ActivateBodies(&inBodyID, 1);
  594. }
  595. }
  596. }
  597. void BodyInterface::AddTorque(const BodyID &inBodyID, Vec3Arg inTorque)
  598. {
  599. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  600. if (lock.Succeeded())
  601. {
  602. Body &body = lock.GetBody();
  603. if (body.IsDynamic())
  604. {
  605. body.AddTorque(inTorque);
  606. if (!body.IsActive())
  607. mBodyManager->ActivateBodies(&inBodyID, 1);
  608. }
  609. }
  610. }
  611. void BodyInterface::AddForceAndTorque(const BodyID &inBodyID, Vec3Arg inForce, Vec3Arg inTorque)
  612. {
  613. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  614. if (lock.Succeeded())
  615. {
  616. Body &body = lock.GetBody();
  617. if (body.IsDynamic())
  618. {
  619. body.AddForce(inForce);
  620. body.AddTorque(inTorque);
  621. if (!body.IsActive())
  622. mBodyManager->ActivateBodies(&inBodyID, 1);
  623. }
  624. }
  625. }
  626. void BodyInterface::AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse)
  627. {
  628. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  629. if (lock.Succeeded())
  630. {
  631. Body &body = lock.GetBody();
  632. if (body.IsDynamic())
  633. {
  634. body.AddImpulse(inImpulse);
  635. if (!body.IsActive())
  636. mBodyManager->ActivateBodies(&inBodyID, 1);
  637. }
  638. }
  639. }
  640. void BodyInterface::AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse, RVec3Arg inPoint)
  641. {
  642. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  643. if (lock.Succeeded())
  644. {
  645. Body &body = lock.GetBody();
  646. if (body.IsDynamic())
  647. {
  648. body.AddImpulse(inImpulse, inPoint);
  649. if (!body.IsActive())
  650. mBodyManager->ActivateBodies(&inBodyID, 1);
  651. }
  652. }
  653. }
  654. void BodyInterface::AddAngularImpulse(const BodyID &inBodyID, Vec3Arg inAngularImpulse)
  655. {
  656. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  657. if (lock.Succeeded())
  658. {
  659. Body &body = lock.GetBody();
  660. if (body.IsDynamic())
  661. {
  662. body.AddAngularImpulse(inAngularImpulse);
  663. if (!body.IsActive())
  664. mBodyManager->ActivateBodies(&inBodyID, 1);
  665. }
  666. }
  667. }
  668. void BodyInterface::SetPositionRotationAndVelocity(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity)
  669. {
  670. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  671. if (lock.Succeeded())
  672. {
  673. Body &body = lock.GetBody();
  674. // Update the position
  675. body.SetPositionAndRotationInternal(inPosition, inRotation);
  676. // Notify broadphase of change
  677. if (body.IsInBroadPhase())
  678. {
  679. BodyID id = body.GetID();
  680. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  681. }
  682. if (!body.IsStatic())
  683. {
  684. body.SetLinearVelocityClamped(inLinearVelocity);
  685. body.SetAngularVelocityClamped(inAngularVelocity);
  686. // Optionally activate body
  687. if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()))
  688. mBodyManager->ActivateBodies(&inBodyID, 1);
  689. }
  690. }
  691. }
  692. void BodyInterface::SetMotionType(const BodyID &inBodyID, EMotionType inMotionType, EActivation inActivationMode)
  693. {
  694. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  695. if (lock.Succeeded())
  696. {
  697. Body &body = lock.GetBody();
  698. // Deactivate if we're making the body static
  699. if (body.IsActive() && inMotionType == EMotionType::Static)
  700. mBodyManager->DeactivateBodies(&inBodyID, 1);
  701. body.SetMotionType(inMotionType);
  702. // Activate body if requested
  703. if (inMotionType != EMotionType::Static && inActivationMode == EActivation::Activate && !body.IsActive())
  704. mBodyManager->ActivateBodies(&inBodyID, 1);
  705. }
  706. }
  707. EBodyType BodyInterface::GetBodyType(const BodyID &inBodyID) const
  708. {
  709. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  710. if (lock.Succeeded())
  711. return lock.GetBody().GetBodyType();
  712. else
  713. return EBodyType::RigidBody;
  714. }
  715. EMotionType BodyInterface::GetMotionType(const BodyID &inBodyID) const
  716. {
  717. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  718. if (lock.Succeeded())
  719. return lock.GetBody().GetMotionType();
  720. else
  721. return EMotionType::Static;
  722. }
  723. void BodyInterface::SetMotionQuality(const BodyID &inBodyID, EMotionQuality inMotionQuality)
  724. {
  725. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  726. if (lock.Succeeded())
  727. mBodyManager->SetMotionQuality(lock.GetBody(), inMotionQuality);
  728. }
  729. EMotionQuality BodyInterface::GetMotionQuality(const BodyID &inBodyID) const
  730. {
  731. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  732. if (lock.Succeeded() && !lock.GetBody().IsStatic())
  733. return lock.GetBody().GetMotionProperties()->GetMotionQuality();
  734. else
  735. return EMotionQuality::Discrete;
  736. }
  737. Mat44 BodyInterface::GetInverseInertia(const BodyID &inBodyID) const
  738. {
  739. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  740. if (lock.Succeeded())
  741. return lock.GetBody().GetInverseInertia();
  742. else
  743. return Mat44::sIdentity();
  744. }
  745. void BodyInterface::SetRestitution(const BodyID &inBodyID, float inRestitution)
  746. {
  747. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  748. if (lock.Succeeded())
  749. lock.GetBody().SetRestitution(inRestitution);
  750. }
  751. float BodyInterface::GetRestitution(const BodyID &inBodyID) const
  752. {
  753. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  754. if (lock.Succeeded())
  755. return lock.GetBody().GetRestitution();
  756. else
  757. return 0.0f;
  758. }
  759. void BodyInterface::SetFriction(const BodyID &inBodyID, float inFriction)
  760. {
  761. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  762. if (lock.Succeeded())
  763. lock.GetBody().SetFriction(inFriction);
  764. }
  765. float BodyInterface::GetFriction(const BodyID &inBodyID) const
  766. {
  767. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  768. if (lock.Succeeded())
  769. return lock.GetBody().GetFriction();
  770. else
  771. return 0.0f;
  772. }
  773. void BodyInterface::SetGravityFactor(const BodyID &inBodyID, float inGravityFactor)
  774. {
  775. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  776. if (lock.Succeeded() && lock.GetBody().GetMotionPropertiesUnchecked() != nullptr)
  777. lock.GetBody().GetMotionPropertiesUnchecked()->SetGravityFactor(inGravityFactor);
  778. }
  779. float BodyInterface::GetGravityFactor(const BodyID &inBodyID) const
  780. {
  781. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  782. if (lock.Succeeded() && lock.GetBody().GetMotionPropertiesUnchecked() != nullptr)
  783. return lock.GetBody().GetMotionPropertiesUnchecked()->GetGravityFactor();
  784. else
  785. return 1.0f;
  786. }
  787. TransformedShape BodyInterface::GetTransformedShape(const BodyID &inBodyID) const
  788. {
  789. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  790. if (lock.Succeeded())
  791. return lock.GetBody().GetTransformedShape();
  792. else
  793. return TransformedShape();
  794. }
  795. uint64 BodyInterface::GetUserData(const BodyID &inBodyID) const
  796. {
  797. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  798. if (lock.Succeeded())
  799. return lock.GetBody().GetUserData();
  800. else
  801. return 0;
  802. }
  803. void BodyInterface::SetUserData(const BodyID &inBodyID, uint64 inUserData) const
  804. {
  805. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  806. if (lock.Succeeded())
  807. lock.GetBody().SetUserData(inUserData);
  808. }
  809. const PhysicsMaterial *BodyInterface::GetMaterial(const BodyID &inBodyID, const SubShapeID &inSubShapeID) const
  810. {
  811. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  812. if (lock.Succeeded())
  813. return lock.GetBody().GetShape()->GetMaterial(inSubShapeID);
  814. else
  815. return PhysicsMaterial::sDefault;
  816. }
  817. void BodyInterface::InvalidateContactCache(const BodyID &inBodyID)
  818. {
  819. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  820. if (lock.Succeeded())
  821. mBodyManager->InvalidateContactCacheForBody(lock.GetBody());
  822. }
  823. JPH_NAMESPACE_END