BodyInterface.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt.h>
  4. #include <Physics/Collision/BroadPhase/BroadPhase.h>
  5. #include <Physics/Body/Body.h>
  6. #include <Physics/Body/BodyManager.h>
  7. #include <Physics/Body/BodyInterface.h>
  8. #include <Physics/Body/BodyCreationSettings.h>
  9. #include <Physics/Body/BodyLock.h>
  10. #include <Physics/Body/BodyLockMulti.h>
  11. #include <Physics/Collision/PhysicsMaterial.h>
  12. namespace JPH {
  13. Body *BodyInterface::CreateBody(const BodyCreationSettings &inSettings)
  14. {
  15. return mBodyManager->CreateBody(inSettings);
  16. }
  17. void BodyInterface::DestroyBody(const BodyID &inBodyID)
  18. {
  19. mBodyManager->DestroyBodies(&inBodyID, 1);
  20. }
  21. void BodyInterface::DestroyBodies(const BodyID *inBodyIDs, int inNumber)
  22. {
  23. mBodyManager->DestroyBodies(inBodyIDs, inNumber);
  24. }
  25. void BodyInterface::AddBody(const BodyID &inBodyID, EActivation inActivationMode)
  26. {
  27. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  28. if (lock.Succeeded())
  29. {
  30. Body &body = lock.GetBody();
  31. // Add to broadphase
  32. BodyID id = inBodyID;
  33. BroadPhase::AddState add_state = mBroadPhase->AddBodiesPrepare(&id, 1);
  34. mBroadPhase->AddBodiesFinalize(&id, 1, add_state);
  35. // Optionally activate body
  36. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  37. mBodyManager->ActivateBodies(&inBodyID, 1);
  38. }
  39. }
  40. void BodyInterface::RemoveBody(const BodyID &inBodyID)
  41. {
  42. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  43. if (lock.Succeeded())
  44. {
  45. Body &body = lock.GetBody();
  46. // Deactivate body
  47. if (body.IsActive())
  48. mBodyManager->DeactivateBodies(&inBodyID, 1);
  49. // Remove from broadphase
  50. BodyID id = inBodyID;
  51. mBroadPhase->RemoveBodies(&id, 1);
  52. }
  53. }
  54. bool BodyInterface::IsAdded(const BodyID &inBodyID) const
  55. {
  56. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  57. return lock.SucceededAndIsInBroadPhase();
  58. }
  59. BodyID BodyInterface::CreateAndAddBody(const BodyCreationSettings &inSettings, EActivation inActivationMode)
  60. {
  61. Body *b = CreateBody(inSettings);
  62. if (b == nullptr)
  63. return BodyID(); // Out of bodies
  64. AddBody(b->GetID(), inActivationMode);
  65. return b->GetID();
  66. }
  67. BodyInterface::AddState BodyInterface::AddBodiesPrepare(BodyID *ioBodies, int inNumber)
  68. {
  69. return mBroadPhase->AddBodiesPrepare(ioBodies, inNumber);
  70. }
  71. void BodyInterface::AddBodiesFinalize(BodyID *ioBodies, int inNumber, AddState inAddState, EActivation inActivationMode)
  72. {
  73. BodyLockMultiWrite lock(*mBodyLockInterface, ioBodies, inNumber);
  74. // Add to broadphase
  75. mBroadPhase->AddBodiesFinalize(ioBodies, inNumber, inAddState);
  76. // Optionally activate bodies
  77. if (inActivationMode == EActivation::Activate)
  78. mBodyManager->ActivateBodies(ioBodies, inNumber);
  79. }
  80. void BodyInterface::AddBodiesAbort(BodyID *ioBodies, int inNumber, AddState inAddState)
  81. {
  82. mBroadPhase->AddBodiesAbort(ioBodies, inNumber, inAddState);
  83. }
  84. void BodyInterface::RemoveBodies(BodyID *ioBodies, int inNumber)
  85. {
  86. BodyLockMultiWrite lock(*mBodyLockInterface, ioBodies, inNumber);
  87. // Deactivate bodies
  88. mBodyManager->DeactivateBodies(ioBodies, inNumber);
  89. // Remove from broadphase
  90. mBroadPhase->RemoveBodies(ioBodies, inNumber);
  91. }
  92. void BodyInterface::ActivateBody(const BodyID &inBodyID)
  93. {
  94. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  95. if (lock.Succeeded())
  96. {
  97. Body &body = lock.GetBody();
  98. if (!body.IsActive())
  99. mBodyManager->ActivateBodies(&inBodyID, 1);
  100. }
  101. }
  102. void BodyInterface::ActivateBodies(const BodyID *inBodyIDs, int inNumber)
  103. {
  104. BodyLockMultiWrite lock(*mBodyLockInterface, inBodyIDs, inNumber);
  105. mBodyManager->ActivateBodies(inBodyIDs, inNumber);
  106. }
  107. void BodyInterface::DeactivateBody(const BodyID &inBodyID)
  108. {
  109. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  110. if (lock.Succeeded())
  111. {
  112. Body &body = lock.GetBody();
  113. if (body.IsActive())
  114. mBodyManager->DeactivateBodies(&inBodyID, 1);
  115. }
  116. }
  117. bool BodyInterface::IsActive(const BodyID &inBodyID) const
  118. {
  119. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  120. return lock.Succeeded() && lock.GetBody().IsActive();
  121. }
  122. RefConst<Shape> BodyInterface::GetShape(const BodyID &inBodyID) const
  123. {
  124. RefConst<Shape> shape;
  125. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  126. if (lock.Succeeded())
  127. shape = lock.GetBody().GetShape();
  128. return shape;
  129. }
  130. void BodyInterface::SetShape(const BodyID &inBodyID, const Shape *inShape, bool inUpdateMassProperties, EActivation inActivationMode) const
  131. {
  132. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  133. if (lock.Succeeded())
  134. {
  135. Body &body = lock.GetBody();
  136. // Check if shape actually changed
  137. if (body.GetShape() != inShape)
  138. {
  139. // Update the shape
  140. body.SetShapeInternal(inShape, inUpdateMassProperties);
  141. // Flag collision cache invalid for this body
  142. mBodyManager->InvalidateContactCacheForBody(body);
  143. // Notify broadphase of change
  144. if (body.IsInBroadPhase())
  145. {
  146. BodyID id = body.GetID();
  147. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  148. }
  149. // Optionally activate body
  150. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  151. mBodyManager->ActivateBodies(&inBodyID, 1);
  152. }
  153. }
  154. }
  155. void BodyInterface::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inPreviousCenterOfMass, bool inUpdateMassProperties, EActivation inActivationMode) const
  156. {
  157. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  158. if (lock.Succeeded())
  159. {
  160. Body &body = lock.GetBody();
  161. // Update center of mass, mass and inertia
  162. body.UpdateCenterOfMassInternal(inPreviousCenterOfMass, inUpdateMassProperties);
  163. // Recalculate bounding box
  164. body.CalculateWorldSpaceBoundsInternal();
  165. // Flag collision cache invalid for this body
  166. mBodyManager->InvalidateContactCacheForBody(body);
  167. // Notify broadphase of change
  168. if (body.IsInBroadPhase())
  169. {
  170. BodyID id = body.GetID();
  171. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  172. }
  173. // Optionally activate body
  174. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  175. mBodyManager->ActivateBodies(&inBodyID, 1);
  176. }
  177. }
  178. void BodyInterface::SetObjectLayer(const BodyID &inBodyID, ObjectLayer inLayer)
  179. {
  180. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  181. if (lock.Succeeded())
  182. {
  183. Body &body = lock.GetBody();
  184. // Check if layer actually changed, updating the broadphase is rather expensive
  185. if (body.GetObjectLayer() != inLayer)
  186. {
  187. body.SetObjectLayerInternal(inLayer);
  188. // Notify broadphase of change
  189. if (body.IsInBroadPhase())
  190. {
  191. BodyID id = body.GetID();
  192. mBroadPhase->NotifyBodiesLayerChanged(&id, 1);
  193. }
  194. }
  195. }
  196. }
  197. ObjectLayer BodyInterface::GetObjectLayer(const BodyID &inBodyID) const
  198. {
  199. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  200. if (lock.Succeeded())
  201. return lock.GetBody().GetObjectLayer();
  202. else
  203. return cObjectLayerInvalid;
  204. }
  205. void BodyInterface::SetPositionAndRotation(const BodyID &inBodyID, Vec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode)
  206. {
  207. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  208. if (lock.Succeeded())
  209. {
  210. Body &body = lock.GetBody();
  211. // Update the position
  212. body.SetPositionAndRotationInternal(inPosition, inRotation);
  213. // Notify broadphase of change
  214. if (body.IsInBroadPhase())
  215. {
  216. BodyID id = body.GetID();
  217. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  218. }
  219. // Optionally activate body
  220. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  221. mBodyManager->ActivateBodies(&inBodyID, 1);
  222. }
  223. }
  224. void BodyInterface::SetPositionAndRotationWhenChanged(const BodyID &inBodyID, Vec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode)
  225. {
  226. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  227. if (lock.Succeeded())
  228. {
  229. Body &body = lock.GetBody();
  230. // Check if there is enough change
  231. if (!body.GetPosition().IsClose(inPosition)
  232. || !body.GetRotation().IsClose(inRotation))
  233. {
  234. // Update the position
  235. body.SetPositionAndRotationInternal(inPosition, inRotation);
  236. // Notify broadphase of change
  237. if (body.IsInBroadPhase())
  238. {
  239. BodyID id = body.GetID();
  240. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  241. }
  242. // Optionally activate body
  243. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  244. mBodyManager->ActivateBodies(&inBodyID, 1);
  245. }
  246. }
  247. }
  248. void BodyInterface::GetPositionAndRotation(const BodyID &inBodyID, Vec3 &outPosition, Quat &outRotation) const
  249. {
  250. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  251. if (lock.Succeeded())
  252. {
  253. const Body &body = lock.GetBody();
  254. outPosition = body.GetPosition();
  255. outRotation = body.GetRotation();
  256. }
  257. else
  258. {
  259. outPosition = Vec3::sZero();
  260. outRotation = Quat::sIdentity();
  261. }
  262. }
  263. void BodyInterface::SetPosition(const BodyID &inBodyID, Vec3Arg inPosition, EActivation inActivationMode)
  264. {
  265. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  266. if (lock.Succeeded())
  267. {
  268. Body &body = lock.GetBody();
  269. // Update the position
  270. body.SetPositionAndRotationInternal(inPosition, body.GetRotation());
  271. // Notify broadphase of change
  272. if (body.IsInBroadPhase())
  273. {
  274. BodyID id = body.GetID();
  275. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  276. }
  277. // Optionally activate body
  278. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  279. mBodyManager->ActivateBodies(&inBodyID, 1);
  280. }
  281. }
  282. Vec3 BodyInterface::GetPosition(const BodyID &inBodyID) const
  283. {
  284. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  285. if (lock.Succeeded())
  286. return lock.GetBody().GetPosition();
  287. else
  288. return Vec3::sZero();
  289. }
  290. Vec3 BodyInterface::GetCenterOfMassPosition(const BodyID &inBodyID) const
  291. {
  292. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  293. if (lock.Succeeded())
  294. return lock.GetBody().GetCenterOfMassPosition();
  295. else
  296. return Vec3::sZero();
  297. }
  298. void BodyInterface::SetRotation(const BodyID &inBodyID, QuatArg inRotation, EActivation inActivationMode)
  299. {
  300. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  301. if (lock.Succeeded())
  302. {
  303. Body &body = lock.GetBody();
  304. // Update the position
  305. body.SetPositionAndRotationInternal(body.GetPosition(), inRotation);
  306. // Notify broadphase of change
  307. if (body.IsInBroadPhase())
  308. {
  309. BodyID id = body.GetID();
  310. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  311. }
  312. // Optionally activate body
  313. if (inActivationMode == EActivation::Activate && !body.IsStatic())
  314. mBodyManager->ActivateBodies(&inBodyID, 1);
  315. }
  316. }
  317. Quat BodyInterface::GetRotation(const BodyID &inBodyID) const
  318. {
  319. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  320. if (lock.Succeeded())
  321. return lock.GetBody().GetRotation();
  322. else
  323. return Quat::sIdentity();
  324. }
  325. Mat44 BodyInterface::GetWorldTransform(const BodyID &inBodyID) const
  326. {
  327. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  328. if (lock.Succeeded())
  329. return lock.GetBody().GetWorldTransform();
  330. else
  331. return Mat44::sIdentity();
  332. }
  333. void BodyInterface::MoveKinematic(const BodyID &inBodyID, Vec3Arg inTargetPosition, QuatArg inTargetRotation, float inDeltaTime)
  334. {
  335. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  336. if (lock.Succeeded())
  337. {
  338. Body &body = lock.GetBody();
  339. body.MoveKinematic(inTargetPosition, inTargetRotation, inDeltaTime);
  340. if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()))
  341. mBodyManager->ActivateBodies(&inBodyID, 1);
  342. }
  343. }
  344. void BodyInterface::SetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity)
  345. {
  346. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  347. if (lock.Succeeded())
  348. {
  349. Body &body = lock.GetBody();
  350. if (!body.IsStatic())
  351. {
  352. body.SetLinearVelocityClamped(inLinearVelocity);
  353. body.SetAngularVelocityClamped(inAngularVelocity);
  354. if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()))
  355. mBodyManager->ActivateBodies(&inBodyID, 1);
  356. }
  357. }
  358. }
  359. void BodyInterface::GetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3 &outLinearVelocity, Vec3 &outAngularVelocity) const
  360. {
  361. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  362. if (lock.Succeeded())
  363. {
  364. const Body &body = lock.GetBody();
  365. if (!body.IsStatic())
  366. {
  367. outLinearVelocity = body.GetLinearVelocity();
  368. outAngularVelocity = body.GetAngularVelocity();
  369. return;
  370. }
  371. }
  372. outLinearVelocity = outAngularVelocity = Vec3::sZero();
  373. }
  374. void BodyInterface::SetLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity)
  375. {
  376. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  377. if (lock.Succeeded())
  378. {
  379. Body &body = lock.GetBody();
  380. if (!body.IsStatic())
  381. {
  382. body.SetLinearVelocityClamped(inLinearVelocity);
  383. if (!body.IsActive() && !inLinearVelocity.IsNearZero())
  384. mBodyManager->ActivateBodies(&inBodyID, 1);
  385. }
  386. }
  387. }
  388. Vec3 BodyInterface::GetLinearVelocity(const BodyID &inBodyID) const
  389. {
  390. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  391. if (lock.Succeeded())
  392. {
  393. const Body &body = lock.GetBody();
  394. if (!body.IsStatic())
  395. return body.GetLinearVelocity();
  396. }
  397. return Vec3::sZero();
  398. }
  399. void BodyInterface::AddLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVelocity)
  400. {
  401. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  402. if (lock.Succeeded())
  403. {
  404. Body &body = lock.GetBody();
  405. if (!body.IsStatic())
  406. {
  407. body.SetLinearVelocityClamped(body.GetLinearVelocity() + inLinearVelocity);
  408. if (!body.IsActive() && !body.GetLinearVelocity().IsNearZero())
  409. mBodyManager->ActivateBodies(&inBodyID, 1);
  410. }
  411. }
  412. }
  413. void BodyInterface::SetAngularVelocity(const BodyID &inBodyID, Vec3Arg inAngularVelocity)
  414. {
  415. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  416. if (lock.Succeeded())
  417. {
  418. Body &body = lock.GetBody();
  419. if (!body.IsStatic())
  420. {
  421. body.SetAngularVelocityClamped(inAngularVelocity);
  422. if (!body.IsActive() && !inAngularVelocity.IsNearZero())
  423. mBodyManager->ActivateBodies(&inBodyID, 1);
  424. }
  425. }
  426. }
  427. Vec3 BodyInterface::GetAngularVelocity(const BodyID &inBodyID) const
  428. {
  429. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  430. if (lock.Succeeded())
  431. {
  432. const Body &body = lock.GetBody();
  433. if (!body.IsStatic())
  434. return body.GetAngularVelocity();
  435. }
  436. return Vec3::sZero();
  437. }
  438. Vec3 BodyInterface::GetPointVelocity(const BodyID &inBodyID, Vec3Arg inPoint) const
  439. {
  440. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  441. if (lock.Succeeded())
  442. {
  443. const Body &body = lock.GetBody();
  444. if (!body.IsStatic())
  445. return body.GetPointVelocity(inPoint);
  446. }
  447. return Vec3::sZero();
  448. }
  449. void BodyInterface::AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse)
  450. {
  451. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  452. if (lock.Succeeded())
  453. {
  454. Body &body = lock.GetBody();
  455. if (body.IsDynamic())
  456. {
  457. body.AddImpulse(inImpulse);
  458. if (!body.IsActive())
  459. mBodyManager->ActivateBodies(&inBodyID, 1);
  460. }
  461. }
  462. }
  463. void BodyInterface::AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse, Vec3Arg inPoint)
  464. {
  465. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  466. if (lock.Succeeded())
  467. {
  468. Body &body = lock.GetBody();
  469. if (body.IsDynamic())
  470. {
  471. body.AddImpulse(inImpulse, inPoint);
  472. if (!body.IsActive())
  473. mBodyManager->ActivateBodies(&inBodyID, 1);
  474. }
  475. }
  476. }
  477. void BodyInterface::AddAngularImpulse(const BodyID &inBodyID, Vec3Arg inAngularImpulse)
  478. {
  479. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  480. if (lock.Succeeded())
  481. {
  482. Body &body = lock.GetBody();
  483. if (body.IsDynamic())
  484. {
  485. body.AddAngularImpulse(inAngularImpulse);
  486. if (!body.IsActive())
  487. mBodyManager->ActivateBodies(&inBodyID, 1);
  488. }
  489. }
  490. }
  491. void BodyInterface::SetPositionRotationAndVelocity(const BodyID &inBodyID, Vec3Arg inPosition, QuatArg inRotation, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity)
  492. {
  493. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  494. if (lock.Succeeded())
  495. {
  496. Body &body = lock.GetBody();
  497. // Update the position
  498. body.SetPositionAndRotationInternal(inPosition, inRotation);
  499. // Notify broadphase of change
  500. if (body.IsInBroadPhase())
  501. {
  502. BodyID id = body.GetID();
  503. mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
  504. }
  505. if (!body.IsStatic())
  506. {
  507. body.SetLinearVelocityClamped(inLinearVelocity);
  508. body.SetAngularVelocityClamped(inAngularVelocity);
  509. // Optionally activate body
  510. if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()))
  511. mBodyManager->ActivateBodies(&inBodyID, 1);
  512. }
  513. }
  514. }
  515. void BodyInterface::SetMotionType(const BodyID &inBodyID, EMotionType inMotionType, EActivation inActivationMode)
  516. {
  517. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  518. if (lock.Succeeded())
  519. {
  520. Body &body = lock.GetBody();
  521. // Deactivate if we're making the body static
  522. if (body.IsActive() && inMotionType == EMotionType::Static)
  523. mBodyManager->DeactivateBodies(&inBodyID, 1);
  524. body.SetMotionType(inMotionType);
  525. // Activate body if requested
  526. if (inMotionType != EMotionType::Static && inActivationMode == EActivation::Activate && !body.IsActive())
  527. mBodyManager->ActivateBodies(&inBodyID, 1);
  528. }
  529. }
  530. Mat44 BodyInterface::GetInverseInertia(const BodyID &inBodyID) const
  531. {
  532. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  533. if (lock.Succeeded())
  534. return lock.GetBody().GetInverseInertia();
  535. else
  536. return Mat44::sIdentity();
  537. }
  538. void BodyInterface::SetRestitution(const BodyID &inBodyID, float inRestitution)
  539. {
  540. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  541. if (lock.Succeeded())
  542. lock.GetBody().SetRestitution(inRestitution);
  543. }
  544. float BodyInterface::GetRestitution(const BodyID &inBodyID) const
  545. {
  546. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  547. if (lock.Succeeded())
  548. return lock.GetBody().GetRestitution();
  549. else
  550. return 0.0f;
  551. }
  552. void BodyInterface::SetFriction(const BodyID &inBodyID, float inFriction)
  553. {
  554. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  555. if (lock.Succeeded())
  556. lock.GetBody().SetFriction(inFriction);
  557. }
  558. float BodyInterface::GetFriction(const BodyID &inBodyID) const
  559. {
  560. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  561. if (lock.Succeeded())
  562. return lock.GetBody().GetFriction();
  563. else
  564. return 0.0f;
  565. }
  566. void BodyInterface::SetGravityFactor(const BodyID &inBodyID, float inGravityFactor)
  567. {
  568. BodyLockWrite lock(*mBodyLockInterface, inBodyID);
  569. if (lock.Succeeded() && lock.GetBody().GetMotionPropertiesUnchecked() != nullptr)
  570. lock.GetBody().GetMotionPropertiesUnchecked()->SetGravityFactor(inGravityFactor);
  571. }
  572. float BodyInterface::GetGravityFactor(const BodyID &inBodyID) const
  573. {
  574. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  575. if (lock.Succeeded() && lock.GetBody().GetMotionPropertiesUnchecked() != nullptr)
  576. return lock.GetBody().GetMotionPropertiesUnchecked()->GetGravityFactor();
  577. else
  578. return 1.0f;
  579. }
  580. TransformedShape BodyInterface::GetTransformedShape(const BodyID &inBodyID) const
  581. {
  582. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  583. if (lock.Succeeded())
  584. return lock.GetBody().GetTransformedShape();
  585. else
  586. return TransformedShape();
  587. }
  588. void *BodyInterface::GetUserData(const BodyID &inBodyID) const
  589. {
  590. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  591. if (lock.Succeeded())
  592. return lock.GetBody().GetUserData();
  593. else
  594. return nullptr;
  595. }
  596. const PhysicsMaterial *BodyInterface::GetMaterial(const BodyID &inBodyID, const SubShapeID &inSubShapeID) const
  597. {
  598. BodyLockRead lock(*mBodyLockInterface, inBodyID);
  599. if (lock.Succeeded())
  600. return lock.GetBody().GetShape()->GetMaterial(inSubShapeID);
  601. else
  602. return PhysicsMaterial::sDefault;
  603. }
  604. } // JPH