Rigidbody.cs 29 KB

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