Rigidbody.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Collections.Generic;
  5. namespace BansheeEngine
  6. {
  7. /** @addtogroup Physics
  8. * @{
  9. */
  10. /// <summary>
  11. /// Rigidbody is a dynamic physics object that can be moved using forces (or directly). It will interact with other
  12. /// static and dynamic physics objects in the scene accordingly (it will push other non-kinematic rigidbodies,
  13. /// and collide with static objects).
  14. ///
  15. /// The shape and mass of a rigidbody is governed by its colliders. You must attach at least one collider for the
  16. /// rigidbody to be valid. Colliders that are on the same scene object as the rigidbody, or on child scene objects
  17. /// are automatically considered as part of the rigidbody.
  18. /// </summary>
  19. public sealed class Rigidbody : Component
  20. {
  21. internal NativeRigidbody native;
  22. private List<Collider> children = new List<Collider>();
  23. private Joint parentJoint;
  24. [SerializeField]
  25. internal SerializableData serializableData = new SerializableData();
  26. /// <summary>
  27. /// Triggered when some object starts interacting with one of the child colliders. Only triggered if proper
  28. /// collision report mode is turned on.
  29. /// </summary>
  30. public event Action<CollisionData> OnCollisionBegin;
  31. /// <summary>
  32. /// Triggered for every frame that an object remains interacting with one of the child colliders. Only triggered if
  33. /// proper collision report mode is turned on.
  34. /// </summary>
  35. public event Action<CollisionData> OnCollisionStay;
  36. /// <summary>
  37. /// Triggered when some object stops interacting with one of the child colliders. Only triggered if proper collision
  38. /// report mode is turned on.
  39. /// </summary>
  40. public event Action<CollisionData> OnCollisionEnd;
  41. /// <summary>
  42. /// Determines the mass of the object and all of its collider shapes. Only relevant if RigidbodyFlag.AutoMass or
  43. /// RigidbodyFlag.AutoTensors is turned off. Value of zero means the object is immovable (but can be rotated).
  44. /// </summary>
  45. public float Mass
  46. {
  47. get { return serializableData.mass; }
  48. set
  49. {
  50. serializableData.mass = value;
  51. if (native != null)
  52. native.Mass = value;
  53. }
  54. }
  55. /// <summary>
  56. /// Determines if the body is kinematic. Kinematic body will not move in response to external forces (for example
  57. /// gravity, or another object pushing it), essentially behaving like collider. Unlike a collider though, you can
  58. /// still move the object and have other dynamic objects respond correctly (that is, it will push other objects).
  59. /// </summary>
  60. public bool Kinematic
  61. {
  62. get { return serializableData.isKinematic; }
  63. set
  64. {
  65. if (serializableData.isKinematic == value)
  66. return;
  67. serializableData.isKinematic = value;
  68. if (native != null)
  69. {
  70. native.Kinematic = value;
  71. ClearColliders();
  72. UpdateColliders();
  73. }
  74. }
  75. }
  76. /// <summary>
  77. /// Determines if the body is sleeping. Objects that aren't moved/rotated for a while are put to sleep to reduce
  78. /// load on the physics system. You may also manually force objects to sleep or wake up.
  79. /// </summary>
  80. public bool Sleeping
  81. {
  82. get
  83. {
  84. if (native != null)
  85. return native.Sleeping;
  86. return true;
  87. }
  88. set
  89. {
  90. if (native != null)
  91. native.Sleeping = value;
  92. }
  93. }
  94. /// <summary>
  95. /// Threshold of force and torque under which the object will be considered to be put to sleep.
  96. /// </summary>
  97. public float SleepThreshold
  98. {
  99. get { return serializableData.sleepThreshold; }
  100. set
  101. {
  102. serializableData.sleepThreshold = value;
  103. if (native != null)
  104. native.SleepThreshold = value;
  105. }
  106. }
  107. /// <summary>
  108. /// Determines whether or not the rigidbody will have the global gravity force applied to it.
  109. /// </summary>
  110. public bool UseGravity
  111. {
  112. get { return serializableData.useGravity; }
  113. set
  114. {
  115. serializableData.useGravity = value;
  116. if (native != null)
  117. native.UseGravity = value;
  118. }
  119. }
  120. /// <summary>
  121. /// Determines current linear velocity of the body.
  122. /// </summary>
  123. public Vector3 Velocity
  124. {
  125. get
  126. {
  127. if (native != null)
  128. return native.Velocity;
  129. return Vector3.Zero;
  130. }
  131. set
  132. {
  133. if (native != null)
  134. native.Velocity = value;
  135. }
  136. }
  137. /// <summary>
  138. /// Determines current angular velocity of the body.
  139. /// </summary>
  140. public Vector3 AngularVelocity
  141. {
  142. get
  143. {
  144. if (native != null)
  145. return native.AngularVelocity;
  146. return Vector3.Zero;
  147. }
  148. set
  149. {
  150. if (native != null)
  151. native.AngularVelocity = value;
  152. }
  153. }
  154. /// <summary>
  155. /// Determines linear drag of the body. Higher drag values means the object resists linear movement more.
  156. /// </summary>
  157. public float Drag
  158. {
  159. get { return serializableData.linearDrag; }
  160. set
  161. {
  162. serializableData.linearDrag = value;
  163. if (native != null)
  164. native.Drag = value;
  165. }
  166. }
  167. /// <summary>
  168. /// Determines angular drag of the body. Higher drag values means the object resists angular movement more.
  169. /// </summary>
  170. public float AngularDrag
  171. {
  172. get { return serializableData.angularDrag; }
  173. set
  174. {
  175. serializableData.angularDrag = value;
  176. if (native != null)
  177. native.AngularDrag = value;
  178. }
  179. }
  180. /// <summary>
  181. /// Sets the inertia tensor in local mass space. Inertia tensor determines how difficult is to rotate the object.
  182. /// Values of zero in the inertia tensor mean the object will be unable to rotate around a specific axis. Changing
  183. /// this value is only relevant if RigidbodyFlag.AutoTensors is turned off.
  184. /// </summary>
  185. public Vector3 InertiaTensor
  186. {
  187. get { return serializableData.inertiaTensor; }
  188. set
  189. {
  190. serializableData.inertiaTensor = value;
  191. if (native != null)
  192. native.InertiaTensor = value;
  193. }
  194. }
  195. /// <summary>
  196. /// Determines position of the center of the mass. Changing this value is only relevant if RigidbodyFlag.AutoTensors
  197. /// is turned off.
  198. /// </summary>
  199. public Vector3 CenterOfMassPosition
  200. {
  201. get { return serializableData.centerMassPosition; }
  202. set
  203. {
  204. serializableData.centerMassPosition = value;
  205. if (native != null)
  206. native.CenterOfMassPosition = value;
  207. }
  208. }
  209. /// <summary>
  210. /// Determines rotation of the inertia tensor (rotation of the center of mass frame). Changing this value is only
  211. /// relevant if RigidbodyFlag.AutoTensors is turned off.
  212. /// </summary>
  213. public Quaternion CenterOfMassRotation
  214. {
  215. get { return serializableData.centerMassRotation; }
  216. set
  217. {
  218. serializableData.centerMassRotation = value;
  219. if (native != null)
  220. native.CenterOfMassRotation = value;
  221. }
  222. }
  223. /// <summary>
  224. /// Determines maximum angular velocity of the rigidbody. Velocity will be clamped to this value.
  225. /// </summary>
  226. public float MaxAngularVelocity
  227. {
  228. get { return serializableData.maxAngularVelocity; }
  229. set
  230. {
  231. serializableData.maxAngularVelocity = value;
  232. if (native != null)
  233. native.MaxAngularVelocity = value;
  234. }
  235. }
  236. /// <summary>
  237. /// Determines number of iterations to use when solving for position. Higher values can improve precision and
  238. /// numerical stability of the simulation.
  239. /// </summary>
  240. public int PositionSolverCount
  241. {
  242. get { return serializableData.positionSolverCount; }
  243. set
  244. {
  245. serializableData.positionSolverCount = value;
  246. if (native != null)
  247. serializableData.positionSolverCount = value;
  248. }
  249. }
  250. /// <summary>
  251. /// Determines number of iterations to use when solving for velocity. Higher values can improve precision and
  252. /// numerical stability of the simulation.
  253. /// </summary>
  254. public int VelocitySolverCount
  255. {
  256. get { return serializableData.velocitySolverCount; }
  257. set
  258. {
  259. serializableData.velocitySolverCount = value;
  260. if (native != null)
  261. serializableData.velocitySolverCount = value;
  262. }
  263. }
  264. /// <summary>
  265. /// Determines interpolation mode that controls how is the rigidbody transfrom updated from the physics simulation.
  266. /// </summary>
  267. public RigidbodyInterpolationMode InterpolationMode
  268. {
  269. get { return serializableData.interpolationMode; }
  270. set
  271. {
  272. serializableData.interpolationMode = value;
  273. if (native != null)
  274. serializableData.interpolationMode = value;
  275. }
  276. }
  277. /// <summary>
  278. /// Determines which (if any) collision events are reported.
  279. /// </summary>
  280. public CollisionReportMode CollisionReportMode
  281. {
  282. get { return serializableData.collisionReportMode; }
  283. set
  284. {
  285. if (serializableData.collisionReportMode == value)
  286. return;
  287. serializableData.collisionReportMode = value;
  288. foreach (var entry in children)
  289. entry.UpdateCollisionReportMode();
  290. }
  291. }
  292. /// <summary>
  293. /// Various flags that control the behaviour of the rigidbody.
  294. /// </summary>
  295. public RigidbodyFlag Flags
  296. {
  297. get { return serializableData.flags; }
  298. set
  299. {
  300. if (serializableData.flags == value)
  301. return;
  302. serializableData.flags = value;
  303. if (native != null)
  304. {
  305. native.Flags = value;
  306. native.UpdateMassDistribution();
  307. }
  308. }
  309. }
  310. /// <summary>
  311. /// Moves the rigidbody to a specific position. This method will ensure physically correct movement, meaning the
  312. /// body will collide with other objects along the way.
  313. /// </summary>
  314. /// <param name="position">New position for the body, in world space.</param>
  315. public void Move(Vector3 position)
  316. {
  317. if (native != null)
  318. native.Move(position);
  319. NotifyFlags = TransformChangedFlags.None;
  320. SceneObject.Position = position;
  321. NotifyFlags = TransformChangedFlags.Transform | TransformChangedFlags.Parent;
  322. }
  323. /// <summary>
  324. /// Rotates the rigidbody. This method will ensure physically correct rotation, meaning the body will collide with
  325. /// other objects along the way.
  326. /// </summary>
  327. /// <param name="rotation">New orientation of the body, in world space.</param>
  328. public void Rotate(Quaternion rotation)
  329. {
  330. if (native != null)
  331. native.Rotate(rotation);
  332. NotifyFlags = TransformChangedFlags.None;
  333. SceneObject.Rotation = rotation;
  334. NotifyFlags = TransformChangedFlags.Transform | TransformChangedFlags.Parent;
  335. }
  336. /// <summary>
  337. /// Applies a force to the center of the mass of the rigidbody. This will produce linear momentum.
  338. /// </summary>
  339. /// <param name="force">Force to apply.</param>
  340. /// <param name="mode">Determines what type of force was applied.</param>
  341. public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force)
  342. {
  343. if (native != null)
  344. native.AddForce(force, mode);
  345. }
  346. /// <summary>
  347. /// Applies a torque to the rigidbody. This will produce angular momentum.
  348. /// </summary>
  349. /// <param name="torque">Torque to apply.</param>
  350. /// <param name="mode">Determines what type of torque was applied.</param>
  351. public void AddTorque(Vector3 torque, ForceMode mode = ForceMode.Force)
  352. {
  353. if (native != null)
  354. native.AddTorque(torque, mode);
  355. }
  356. /// <summary>
  357. /// Applies a force to a specific point on the rigidbody. This will in most cases produce both linear and angular
  358. /// momentum.
  359. /// </summary>
  360. /// <param name="force">Force to apply.</param>
  361. /// <param name="position">World space point to apply the force at.</param>
  362. /// <param name="mode">Determines what type of force was applied.</param>
  363. public void AddForceAtPoint(Vector3 force, Vector3 position, PointForceMode mode = PointForceMode.Force)
  364. {
  365. if (native != null)
  366. native.AddForceAtPoint(force, position, mode);
  367. }
  368. /// <summary>
  369. /// Returns the total (linear + angular) velocity at a specific point.
  370. /// </summary>
  371. /// <param name="position">Point in world space.</param>
  372. /// <returns>Total velocity of the point.</returns>
  373. public Vector3 GetVelocityAtPoint(Vector3 position)
  374. {
  375. if (native != null)
  376. return native.GetVelocityAtPoint(position);
  377. return position;
  378. }
  379. /// <summary>
  380. /// Triggered when one of the child colliders begins touching another object.
  381. /// </summary>
  382. /// <param name="data">Data about the collision.</param>
  383. internal void DoOnCollisionBegin(CollisionData data)
  384. {
  385. if (OnCollisionBegin != null)
  386. OnCollisionBegin(data);
  387. }
  388. /// <summary>
  389. /// Triggered when one of the child colliders ends touching another object.
  390. /// </summary>
  391. /// <param name="data">Data about the collision.</param>
  392. internal void DoOnCollisionStay(CollisionData data)
  393. {
  394. if (OnCollisionStay != null)
  395. OnCollisionStay(data);
  396. }
  397. /// <summary>
  398. /// Triggered when one of the child colliders ends touching another object.
  399. /// </summary>
  400. /// <param name="data">Data about the collision.</param>
  401. internal void DoOnCollisionEnd(CollisionData data)
  402. {
  403. if (OnCollisionEnd != null)
  404. OnCollisionEnd(data);
  405. }
  406. /// <summary>
  407. /// Sets that joint that this rigidbody is attached to. Allows the rigidbody to notify the joint when it moves.
  408. /// </summary>
  409. /// <param name="joint">Joint the rigidbody is attached to, or null if none.</param>
  410. internal void SetJoint(Joint joint)
  411. {
  412. parentJoint = joint;
  413. }
  414. /// <summary>
  415. /// Recalculates rigidbody's mass, inertia tensors and center of mass depending on the currently set child
  416. /// colliders. This should be called whenever relevant child collider properties change(like mass or shape).
  417. ///
  418. /// If automatic tensor calculation is turned off then this will do nothing. If automatic mass calculation is turned
  419. /// off then this will use the mass set directly on the body using <see cref="Mass"/>.
  420. /// </summary>
  421. internal void UpdateMassDistribution()
  422. {
  423. if (native != null)
  424. native.UpdateMassDistribution();
  425. }
  426. /// <summary>
  427. /// Unregisters all child colliders from the Rigidbody.
  428. /// </summary>
  429. internal void ClearColliders()
  430. {
  431. foreach (var collider in children)
  432. collider.SetRigidbody(null, true);
  433. children.Clear();
  434. if (native != null)
  435. native.RemoveColliders();
  436. }
  437. /// <summary>
  438. /// Registers a new collider with the Rigidbody. This collider will then be used to calculate Rigidbody's geometry
  439. /// used for collisions, and optionally (depending on set flags) total mass, inertia tensors and center of mass.
  440. /// </summary>
  441. /// <param name="collider">Collider to register.</param>
  442. internal void AddCollider(Collider collider)
  443. {
  444. if (native == null)
  445. return;
  446. children.Add(collider);
  447. native.AddCollider(collider);
  448. }
  449. /// <summary>
  450. /// Unregisters the collider from the Rigidbody.
  451. /// </summary>
  452. /// <param name="collider">Collider to unregister.</param>
  453. internal void RemoveCollider(Collider collider)
  454. {
  455. if (native == null)
  456. return;
  457. if (children.Exists(x => x == collider))
  458. {
  459. native.RemoveCollider(collider);
  460. children.Remove(collider);
  461. }
  462. }
  463. private void OnInitialize()
  464. {
  465. NotifyFlags = TransformChangedFlags.Transform | TransformChangedFlags.Parent;
  466. }
  467. private void OnEnable()
  468. {
  469. RestoreNative();
  470. }
  471. private void OnDisable()
  472. {
  473. DestroyNative();
  474. }
  475. private void OnDestroy()
  476. {
  477. DestroyNative();
  478. }
  479. private void OnTransformChanged(TransformChangedFlags flags)
  480. {
  481. if (!SceneObject.Active)
  482. return;
  483. if ((flags & TransformChangedFlags.Parent) != 0)
  484. {
  485. ClearColliders();
  486. UpdateColliders();
  487. if ((serializableData.flags & RigidbodyFlag.AutoTensors) != 0)
  488. native.UpdateMassDistribution();
  489. #if DEBUG
  490. CheckForNestedRigibody();
  491. #endif
  492. }
  493. native.Position = SceneObject.Position;
  494. native.Rotation = SceneObject.Rotation;
  495. if (parentJoint != null)
  496. parentJoint.NotifyRigidbodyMoved(this);
  497. }
  498. /// <summary>
  499. /// Searches child scene objects for Collider components and attaches them to the rigidbody. Make sure to call
  500. /// <see cref="ClearColliders"/> if you need to clear old colliders first.
  501. /// </summary>
  502. private void UpdateColliders()
  503. {
  504. Stack<SceneObject> todo = new Stack<SceneObject>();
  505. todo.Push(SceneObject);
  506. while (todo.Count > 0)
  507. {
  508. SceneObject currentSO = todo.Pop();
  509. if (currentSO.GetComponent<Collider>() != null)
  510. {
  511. Collider[] colliders = currentSO.GetComponents<Collider>();
  512. foreach (var entry in colliders)
  513. {
  514. if (!entry.IsValidParent(this))
  515. continue;
  516. if (entry.native == null)
  517. continue;
  518. entry.SetRigidbody(this, true);
  519. entry.native.Rigidbody = native;
  520. children.Add(entry);
  521. native.AddCollider(entry);
  522. }
  523. }
  524. int childCount = currentSO.GetNumChildren();
  525. for (int i = 0; i < childCount; i++)
  526. {
  527. SceneObject child = currentSO.GetChild(i);
  528. if (child.GetComponent<Rigidbody>() != null)
  529. continue;
  530. todo.Push(child);
  531. }
  532. }
  533. }
  534. /// <summary>
  535. /// Checks if the rigidbody is nested under another rigidbody, and throws out a warning if so.
  536. /// </summary>
  537. private void CheckForNestedRigibody()
  538. {
  539. SceneObject currentSO = SceneObject.Parent;
  540. while (currentSO != null)
  541. {
  542. if (currentSO.GetComponent<Rigidbody>() != null)
  543. {
  544. Debug.LogWarning("Nested Rigidbodies detected. This will result in inconsistent transformations. " +
  545. "To parent one Rigidbody to another move its colliders to the new parent, but remove the " +
  546. "Rigidbody component.");
  547. return;
  548. }
  549. currentSO = currentSO.Parent;
  550. }
  551. }
  552. /// <summary>
  553. /// Destroys the internal rigidbody representation.
  554. /// </summary>
  555. private void DestroyNative()
  556. {
  557. ClearColliders();
  558. if (native != null)
  559. {
  560. native.Destroy();
  561. native = null;
  562. }
  563. }
  564. /// <summary>
  565. /// Restores internal rigidbody representation and assigns it the properties stored by the component.
  566. /// </summary>
  567. private void RestoreNative()
  568. {
  569. native = new NativeRigidbody(SceneObject);
  570. native.Component = this;
  571. UpdateColliders();
  572. #if DEBUG
  573. CheckForNestedRigibody();
  574. #endif
  575. native.Position = SceneObject.Position;
  576. native.Rotation = SceneObject.Rotation;
  577. // Note: Merge into one call to avoid many virtual function calls
  578. native.PositionSolverCount = serializableData.positionSolverCount;
  579. native.VelocitySolverCount = serializableData.velocitySolverCount;
  580. native.MaxAngularVelocity = serializableData.maxAngularVelocity;
  581. native.Drag = serializableData.linearDrag;;
  582. native.AngularDrag = serializableData.angularDrag;
  583. native.SleepThreshold = serializableData.sleepThreshold;
  584. native.UseGravity = serializableData.useGravity;
  585. native.Kinematic = serializableData.isKinematic;
  586. native.InterpolationMode = serializableData.interpolationMode;
  587. native.Flags = serializableData.flags;
  588. if ((serializableData.flags & RigidbodyFlag.AutoTensors) == 0)
  589. {
  590. native.CenterOfMassPosition = serializableData.centerMassPosition;
  591. native.CenterOfMassRotation = serializableData.centerMassRotation;
  592. native.InertiaTensor = serializableData.inertiaTensor;
  593. native.Mass = serializableData.mass;
  594. }
  595. else
  596. {
  597. if ((serializableData.flags & RigidbodyFlag.AutoMass) == 0)
  598. native.Mass = serializableData.mass;
  599. native.UpdateMassDistribution();
  600. }
  601. }
  602. /// <summary>
  603. /// Holds all data the rigidbody component needs to persist through serialization.
  604. /// </summary>
  605. [SerializeObject]
  606. internal class SerializableData
  607. {
  608. public int positionSolverCount = 4;
  609. public int velocitySolverCount = 1;
  610. public RigidbodyFlag flags = RigidbodyFlag.AutoTensors | RigidbodyFlag.AutoMass;
  611. public RigidbodyInterpolationMode interpolationMode = RigidbodyInterpolationMode.None;
  612. public CollisionReportMode collisionReportMode = CollisionReportMode.None;
  613. public Vector3 centerMassPosition = Vector3.Zero;
  614. public Quaternion centerMassRotation = Quaternion.Identity;
  615. public Vector3 inertiaTensor = Vector3.Zero;
  616. public float mass = 0.0f;
  617. public float maxAngularVelocity = 1.0f;
  618. public float linearDrag = 0.0f;
  619. public float angularDrag = 0.0f;
  620. public float sleepThreshold = 0.0f;
  621. public bool useGravity = true;
  622. public bool isKinematic = false;
  623. }
  624. }
  625. /// <summary>
  626. /// Type of force or torque that can be applied to a rigidbody.
  627. /// </summary>
  628. public enum ForceMode
  629. {
  630. /// <summary>
  631. /// Value applied is a force.
  632. /// </summary>
  633. Force,
  634. /// <summary>
  635. /// Value applied is an impulse (a direct change in its linear or angular momentum).
  636. /// </summary>
  637. Impulse,
  638. /// <summary>
  639. /// Value applied is velocity.
  640. /// </summary>
  641. Velocity,
  642. /// <summary>
  643. /// Value applied is accelearation.
  644. /// </summary>
  645. Acceleration
  646. }
  647. /// <summary>
  648. /// Type of force that can be applied to a rigidbody at an arbitrary point.
  649. /// </summary>
  650. public enum PointForceMode
  651. {
  652. /// <summary>
  653. /// Value applied is a force.
  654. /// </summary>
  655. Force,
  656. /// <summary>
  657. /// Value applied is an impulse (a direct change in its linear or angular momentum).
  658. /// </summary>
  659. Impulse,
  660. }
  661. /// <summary>
  662. /// Flags that control options of a Rigidbody object.
  663. /// </summary>
  664. [Flags]
  665. public enum RigidbodyFlag
  666. {
  667. /// <summary>
  668. /// No options.
  669. /// </summary>
  670. None = 0x00,
  671. /// <summary>
  672. /// Automatically calculate center of mass transform and inertia tensors from child shapes (colliders)
  673. /// </summary>
  674. AutoTensors = 0x01,
  675. /// <summary>
  676. /// Calculate mass distribution from child shapes (colliders). Only relevant when auto-tensors is on.
  677. /// </summary>
  678. AutoMass = 0x02,
  679. /// <summary>
  680. /// Enables continous collision detection. This can prevent fast moving bodies from tunneling through each other.
  681. /// This must also be enabled globally in Physics otherwise the flag will be ignored.
  682. /// </summary>
  683. CCD = 0x04
  684. }
  685. /// <summary>
  686. /// Determines interpolation mode for a rigidbody transform during physics simulation.
  687. /// </summary>
  688. public enum RigidbodyInterpolationMode
  689. {
  690. /// <summary>
  691. /// No interpolation is performed, physics transform is copied straight to the rigidbody when physics tick is done.
  692. /// </summary>
  693. None,
  694. /// <summary>
  695. /// Physics transfrom from the most recent tick is saved and slowly interpolated to during the following render
  696. /// frames. This can improve smoothness of the visible movement at framerates higher than the physics simulation
  697. /// but will introduce a delay of one physics tick to all such objects. This can create slight inconsistencies as
  698. /// non-interpolated objects will have no such delay, as well as cause input lag due to the delayed reaction.
  699. /// </summary>
  700. Interpolate,
  701. /// <summary>
  702. /// Physics transform movement will be extrapolated from the last physics simulation tick. This will improve
  703. /// smoothness of visible movement at framerates higher than the physics simulation. Unlike Interpolate it will
  704. /// not introduce an input delay, but will introduce an error as the exact position/rotation of the objects is
  705. /// extrapolated from the last frame's movement and velocities.
  706. /// </summary>
  707. Extrapolate
  708. }
  709. /** @} */
  710. }