b2Body.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #ifndef B2_BODY_H
  19. #define B2_BODY_H
  20. #include "../Common/b2Math.h"
  21. #include "../Collision/Shapes/b2Shape.h"
  22. #include "Joints/b2Joint.h"
  23. #include "Controllers/b2Controller.h"
  24. #include <memory>
  25. class b2Joint;
  26. class b2Contact;
  27. class b2Controller;
  28. class b2World;
  29. struct b2JointEdge;
  30. struct b2ContactEdge;
  31. struct b2ControllerEdge;
  32. /// A body definition holds all the data needed to construct a rigid body.
  33. /// You can safely re-use body definitions.
  34. struct b2BodyDef
  35. {
  36. /// This constructor sets the body definition default values.
  37. b2BodyDef()
  38. {
  39. massData.center.SetZero();
  40. massData.mass = 0.0f;
  41. massData.I = 0.0f;
  42. userData = NULL;
  43. position.Set(0.0f, 0.0f);
  44. angle = 0.0f;
  45. linearDamping = 0.0f;
  46. angularDamping = 0.0f;
  47. allowSleep = true;
  48. isSleeping = false;
  49. fixedRotation = false;
  50. isBullet = false;
  51. }
  52. /// You can use this to initialized the mass properties of the body.
  53. /// If you prefer, you can set the mass properties after the shapes
  54. /// have been added using b2Body::SetMassFromShapes.
  55. b2MassData massData;
  56. /// Use this to store application specific body data.
  57. void* userData;
  58. /// The world position of the body. Avoid creating bodies at the origin
  59. /// since this can lead to many overlapping shapes.
  60. b2Vec2 position;
  61. /// The world angle of the body in radians.
  62. float32 angle;
  63. /// Linear damping is use to reduce the linear velocity. The damping parameter
  64. /// can be larger than 1.0f but the damping effect becomes sensitive to the
  65. /// time step when the damping parameter is large.
  66. float32 linearDamping;
  67. /// Angular damping is use to reduce the angular velocity. The damping parameter
  68. /// can be larger than 1.0f but the damping effect becomes sensitive to the
  69. /// time step when the damping parameter is large.
  70. float32 angularDamping;
  71. /// Set this flag to false if this body should never fall asleep. Note that
  72. /// this increases CPU usage.
  73. bool allowSleep;
  74. /// Is this body initially sleeping?
  75. bool isSleeping;
  76. /// Should this body be prevented from rotating? Useful for characters.
  77. bool fixedRotation;
  78. /// Is this a fast moving body that should be prevented from tunneling through
  79. /// other moving bodies? Note that all bodies are prevented from tunneling through
  80. /// static bodies.
  81. /// @warning You should use this flag sparingly since it increases processing time.
  82. bool isBullet;
  83. };
  84. /// A rigid body.
  85. class b2Body
  86. {
  87. public:
  88. /// Creates a shape and attach it to this body.
  89. /// @param shapeDef the shape definition.
  90. /// @warning This function is locked during callbacks.
  91. b2Shape* CreateShape(b2ShapeDef* shapeDef);
  92. /// Destroy a shape. This removes the shape from the broad-phase and
  93. /// therefore destroys any contacts associated with this shape. All shapes
  94. /// attached to a body are implicitly destroyed when the body is destroyed.
  95. /// @param shape the shape to be removed.
  96. /// @warning This function is locked during callbacks.
  97. void DestroyShape(b2Shape* shape);
  98. /// Set the mass properties. Note that this changes the center of mass position.
  99. /// If you are not sure how to compute mass properties, use SetMassFromShapes.
  100. /// The inertia tensor is assumed to be relative to the center of mass.
  101. /// @param massData the mass properties.
  102. void SetMass(const b2MassData* massData);
  103. /// Compute the mass properties from the attached shapes. You typically call this
  104. /// after adding all the shapes. If you add or remove shapes later, you may want
  105. /// to call this again. Note that this changes the center of mass position.
  106. void SetMassFromShapes();
  107. /// Set the position of the body's origin and rotation (radians).
  108. /// This breaks any contacts and wakes the other bodies.
  109. /// @param position the new world position of the body's origin (not necessarily
  110. /// the center of mass).
  111. /// @param angle the new world rotation angle of the body in radians.
  112. /// @return false if the movement put a shape outside the world. In this case the
  113. /// body is automatically frozen.
  114. bool SetXForm(const b2Vec2& position, float32 angle);
  115. /// Get the body transform for the body's origin.
  116. /// @return the world transform of the body's origin.
  117. const b2XForm& GetXForm() const;
  118. /// Get the world body origin position.
  119. /// @return the world position of the body's origin.
  120. const b2Vec2& GetPosition() const;
  121. /// Get the angle in radians.
  122. /// @return the current world rotation angle in radians.
  123. float32 GetAngle() const;
  124. /// Get the world position of the center of mass.
  125. const b2Vec2& GetWorldCenter() const;
  126. /// Get the local position of the center of mass.
  127. const b2Vec2& GetLocalCenter() const;
  128. /// Set the linear velocity of the center of mass.
  129. /// @param v the new linear velocity of the center of mass.
  130. void SetLinearVelocity(const b2Vec2& v);
  131. /// Get the linear velocity of the center of mass.
  132. /// @return the linear velocity of the center of mass.
  133. b2Vec2 GetLinearVelocity() const;
  134. /// Set the angular velocity.
  135. /// @param omega the new angular velocity in radians/second.
  136. void SetAngularVelocity(float32 omega);
  137. /// Get the angular velocity.
  138. /// @return the angular velocity in radians/second.
  139. float32 GetAngularVelocity() const;
  140. /// Apply a force at a world point. If the force is not
  141. /// applied at the center of mass, it will generate a torque and
  142. /// affect the angular velocity. This wakes up the body.
  143. /// @param force the world force vector, usually in Newtons (N).
  144. /// @param point the world position of the point of application.
  145. void ApplyForce(const b2Vec2& force, const b2Vec2& point);
  146. /// Apply a torque. This affects the angular velocity
  147. /// without affecting the linear velocity of the center of mass.
  148. /// This wakes up the body.
  149. /// @param torque about the z-axis (out of the screen), usually in N-m.
  150. void ApplyTorque(float32 torque);
  151. /// Apply an impulse at a point. This immediately modifies the velocity.
  152. /// It also modifies the angular velocity if the point of application
  153. /// is not at the center of mass. This wakes up the body.
  154. /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
  155. /// @param point the world position of the point of application.
  156. void ApplyImpulse(const b2Vec2& impulse, const b2Vec2& point);
  157. /// Get the total mass of the body.
  158. /// @return the mass, usually in kilograms (kg).
  159. float32 GetMass() const;
  160. /// Get the central rotational inertia of the body.
  161. /// @return the rotational inertia, usually in kg-m^2.
  162. float32 GetInertia() const;
  163. /// Get the world coordinates of a point given the local coordinates.
  164. /// @param localPoint a point on the body measured relative the the body's origin.
  165. /// @return the same point expressed in world coordinates.
  166. b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const;
  167. /// Get the world coordinates of a vector given the local coordinates.
  168. /// @param localVector a vector fixed in the body.
  169. /// @return the same vector expressed in world coordinates.
  170. b2Vec2 GetWorldVector(const b2Vec2& localVector) const;
  171. /// Gets a local point relative to the body's origin given a world point.
  172. /// @param a point in world coordinates.
  173. /// @return the corresponding local point relative to the body's origin.
  174. b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const;
  175. /// Gets a local vector given a world vector.
  176. /// @param a vector in world coordinates.
  177. /// @return the corresponding local vector.
  178. b2Vec2 GetLocalVector(const b2Vec2& worldVector) const;
  179. /// Get the world linear velocity of a world point attached to this body.
  180. /// @param a point in world coordinates.
  181. /// @return the world velocity of a point.
  182. b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;
  183. /// Get the world velocity of a local point.
  184. /// @param a point in local coordinates.
  185. /// @return the world velocity of a point.
  186. b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const;
  187. /// Is this body treated like a bullet for continuous collision detection?
  188. bool IsBullet() const;
  189. /// Should this body be treated like a bullet for continuous collision detection?
  190. void SetBullet(bool flag);
  191. /// Is this body static (immovable)?
  192. bool IsStatic() const;
  193. /// Is this body dynamic (movable)?
  194. bool IsDynamic() const;
  195. /// Is this body frozen?
  196. bool IsFrozen() const;
  197. /// Is this body sleeping (not simulating).
  198. bool IsSleeping() const;
  199. /// You can disable sleeping on this body.
  200. void AllowSleeping(bool flag);
  201. /// Wake up this body so it will begin simulating.
  202. void WakeUp();
  203. /// Put this body to sleep so it will stop simulating.
  204. /// This also sets the velocity to zero.
  205. void PutToSleep();
  206. /// Get the list of all shapes attached to this body.
  207. b2Shape* GetShapeList();
  208. /// Get the list of all joints attached to this body.
  209. b2JointEdge* GetJointList();
  210. /// Get the list of all controllers attached to this body.
  211. b2ControllerEdge* GetControllerList();
  212. /// Get the next body in the world's body list.
  213. b2Body* GetNext();
  214. /// Get the user data pointer that was provided in the body definition.
  215. void* GetUserData();
  216. /// Set the user data. Use this to store your application specific data.
  217. void SetUserData(void* data);
  218. /// Get the parent world of this body.
  219. b2World* GetWorld();
  220. private:
  221. friend class b2World;
  222. friend class b2Island;
  223. friend class b2ContactManager;
  224. friend class b2ContactSolver;
  225. friend class b2DistanceJoint;
  226. friend class b2GearJoint;
  227. friend class b2LineJoint;
  228. friend class b2MouseJoint;
  229. friend class b2PrismaticJoint;
  230. friend class b2PulleyJoint;
  231. friend class b2RevoluteJoint;
  232. friend class b2Controller;
  233. // m_flags
  234. enum
  235. {
  236. e_frozenFlag = 0x0002,
  237. e_islandFlag = 0x0004,
  238. e_sleepFlag = 0x0008,
  239. e_allowSleepFlag = 0x0010,
  240. e_bulletFlag = 0x0020,
  241. e_fixedRotationFlag = 0x0040,
  242. };
  243. // m_type
  244. enum
  245. {
  246. e_staticType,
  247. e_dynamicType,
  248. e_maxTypes,
  249. };
  250. b2Body(const b2BodyDef* bd, b2World* world);
  251. ~b2Body();
  252. bool SynchronizeShapes();
  253. void SynchronizeTransform();
  254. // This is used to prevent connected bodies from colliding.
  255. // It may lie, depending on the collideConnected flag.
  256. bool IsConnected(const b2Body* other) const;
  257. void Advance(float32 t);
  258. uint16 m_flags;
  259. int16 m_type;
  260. int32 m_islandIndex;
  261. b2XForm m_xf; // the body origin transform
  262. b2Sweep m_sweep; // the swept motion for CCD
  263. b2Vec2 m_linearVelocity;
  264. float32 m_angularVelocity;
  265. b2Vec2 m_force;
  266. float32 m_torque;
  267. b2World* m_world;
  268. b2Body* m_prev;
  269. b2Body* m_next;
  270. b2Shape* m_shapeList;
  271. int32 m_shapeCount;
  272. b2JointEdge* m_jointList;
  273. b2ContactEdge* m_contactList;
  274. b2ControllerEdge* m_controllerList;
  275. float32 m_mass, m_invMass;
  276. float32 m_I, m_invI;
  277. float32 m_linearDamping;
  278. float32 m_angularDamping;
  279. float32 m_sleepTime;
  280. void* m_userData;
  281. };
  282. inline const b2XForm& b2Body::GetXForm() const
  283. {
  284. return m_xf;
  285. }
  286. inline const b2Vec2& b2Body::GetPosition() const
  287. {
  288. return m_xf.position;
  289. }
  290. inline float32 b2Body::GetAngle() const
  291. {
  292. return m_sweep.a;
  293. }
  294. inline const b2Vec2& b2Body::GetWorldCenter() const
  295. {
  296. return m_sweep.c;
  297. }
  298. inline const b2Vec2& b2Body::GetLocalCenter() const
  299. {
  300. return m_sweep.localCenter;
  301. }
  302. inline void b2Body::SetLinearVelocity(const b2Vec2& v)
  303. {
  304. m_linearVelocity = v;
  305. }
  306. inline b2Vec2 b2Body::GetLinearVelocity() const
  307. {
  308. return m_linearVelocity;
  309. }
  310. inline void b2Body::SetAngularVelocity(float32 w)
  311. {
  312. m_angularVelocity = w;
  313. }
  314. inline float32 b2Body::GetAngularVelocity() const
  315. {
  316. return m_angularVelocity;
  317. }
  318. inline float32 b2Body::GetMass() const
  319. {
  320. return m_mass;
  321. }
  322. inline float32 b2Body::GetInertia() const
  323. {
  324. return m_I;
  325. }
  326. inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const
  327. {
  328. return b2Mul(m_xf, localPoint);
  329. }
  330. inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const
  331. {
  332. return b2Mul(m_xf.R, localVector);
  333. }
  334. inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const
  335. {
  336. return b2MulT(m_xf, worldPoint);
  337. }
  338. inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const
  339. {
  340. return b2MulT(m_xf.R, worldVector);
  341. }
  342. inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const
  343. {
  344. return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
  345. }
  346. inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const
  347. {
  348. return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
  349. }
  350. inline bool b2Body::IsBullet() const
  351. {
  352. return (m_flags & e_bulletFlag) == e_bulletFlag;
  353. }
  354. inline void b2Body::SetBullet(bool flag)
  355. {
  356. if (flag)
  357. {
  358. m_flags |= e_bulletFlag;
  359. }
  360. else
  361. {
  362. m_flags &= ~e_bulletFlag;
  363. }
  364. }
  365. inline bool b2Body::IsStatic() const
  366. {
  367. return m_type == e_staticType;
  368. }
  369. inline bool b2Body::IsDynamic() const
  370. {
  371. return m_type == e_dynamicType;
  372. }
  373. inline bool b2Body::IsFrozen() const
  374. {
  375. return (m_flags & e_frozenFlag) == e_frozenFlag;
  376. }
  377. inline bool b2Body::IsSleeping() const
  378. {
  379. return (m_flags & e_sleepFlag) == e_sleepFlag;
  380. }
  381. inline void b2Body::AllowSleeping(bool flag)
  382. {
  383. if (flag)
  384. {
  385. m_flags |= e_allowSleepFlag;
  386. }
  387. else
  388. {
  389. m_flags &= ~e_allowSleepFlag;
  390. WakeUp();
  391. }
  392. }
  393. inline void b2Body::WakeUp()
  394. {
  395. m_flags &= ~e_sleepFlag;
  396. m_sleepTime = 0.0f;
  397. }
  398. inline void b2Body::PutToSleep()
  399. {
  400. m_flags |= e_sleepFlag;
  401. m_sleepTime = 0.0f;
  402. m_linearVelocity.SetZero();
  403. m_angularVelocity = 0.0f;
  404. m_force.SetZero();
  405. m_torque = 0.0f;
  406. }
  407. inline b2Shape* b2Body::GetShapeList()
  408. {
  409. return m_shapeList;
  410. }
  411. inline b2JointEdge* b2Body::GetJointList()
  412. {
  413. return m_jointList;
  414. }
  415. inline b2ControllerEdge* b2Body::GetControllerList()
  416. {
  417. return m_controllerList;
  418. }
  419. inline b2Body* b2Body::GetNext()
  420. {
  421. return m_next;
  422. }
  423. inline void* b2Body::GetUserData()
  424. {
  425. return m_userData;
  426. }
  427. inline void b2Body::SetUserData(void* data)
  428. {
  429. m_userData = data;
  430. }
  431. inline bool b2Body::IsConnected(const b2Body* other) const
  432. {
  433. for (b2JointEdge* jn = m_jointList; jn; jn = jn->next)
  434. {
  435. if (jn->other == other)
  436. return jn->joint->m_collideConnected == false;
  437. }
  438. return false;
  439. }
  440. inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point)
  441. {
  442. if (IsSleeping())
  443. {
  444. WakeUp();
  445. }
  446. m_force += force;
  447. m_torque += b2Cross(point - m_sweep.c, force);
  448. }
  449. inline void b2Body::ApplyTorque(float32 torque)
  450. {
  451. if (IsSleeping())
  452. {
  453. WakeUp();
  454. }
  455. m_torque += torque;
  456. }
  457. inline void b2Body::ApplyImpulse(const b2Vec2& impulse, const b2Vec2& point)
  458. {
  459. if (IsSleeping())
  460. {
  461. WakeUp();
  462. }
  463. m_linearVelocity += m_invMass * impulse;
  464. m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse);
  465. }
  466. inline void b2Body::SynchronizeTransform()
  467. {
  468. m_xf.R.Set(m_sweep.a);
  469. m_xf.position = m_sweep.c - b2Mul(m_xf.R, m_sweep.localCenter);
  470. }
  471. inline void b2Body::Advance(float32 t)
  472. {
  473. // Advance to the new safe time.
  474. m_sweep.Advance(t);
  475. m_sweep.c = m_sweep.c0;
  476. m_sweep.a = m_sweep.a0;
  477. SynchronizeTransform();
  478. }
  479. inline b2World* b2Body::GetWorld()
  480. {
  481. return m_world;
  482. }
  483. #endif