Box2D  2.2.0
A 2D Physics Engine for Games
b2Body.h
00001 /*
00002 * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
00003 *
00004 * This software is provided 'as-is', without any express or implied
00005 * warranty.  In no event will the authors be held liable for any damages
00006 * arising from the use of this software.
00007 * Permission is granted to anyone to use this software for any purpose,
00008 * including commercial applications, and to alter it and redistribute it
00009 * freely, subject to the following restrictions:
00010 * 1. The origin of this software must not be misrepresented; you must not
00011 * claim that you wrote the original software. If you use this software
00012 * in a product, an acknowledgment in the product documentation would be
00013 * appreciated but is not required.
00014 * 2. Altered source versions must be plainly marked as such, and must not be
00015 * misrepresented as being the original software.
00016 * 3. This notice may not be removed or altered from any source distribution.
00017 */
00018 
00019 #ifndef B2_BODY_H
00020 #define B2_BODY_H
00021 
00022 #include <Box2D/Common/b2Math.h>
00023 #include <Box2D/Collision/Shapes/b2Shape.h>
00024 #include <memory>
00025 
00026 class b2Fixture;
00027 class b2Joint;
00028 class b2Contact;
00029 class b2Controller;
00030 class b2World;
00031 struct b2FixtureDef;
00032 struct b2JointEdge;
00033 struct b2ContactEdge;
00034 
00039 enum b2BodyType
00040 {
00041         b2_staticBody = 0,
00042         b2_kinematicBody,
00043         b2_dynamicBody
00044 
00045         // TODO_ERIN
00046         //b2_bulletBody,
00047 };
00048 
00051 struct b2BodyDef
00052 {
00054         b2BodyDef()
00055         {
00056                 userData = NULL;
00057                 position.Set(0.0f, 0.0f);
00058                 angle = 0.0f;
00059                 linearVelocity.Set(0.0f, 0.0f);
00060                 angularVelocity = 0.0f;
00061                 linearDamping = 0.0f;
00062                 angularDamping = 0.0f;
00063                 allowSleep = true;
00064                 awake = true;
00065                 fixedRotation = false;
00066                 bullet = false;
00067                 type = b2_staticBody;
00068                 active = true;
00069                 gravityScale = 1.0f;
00070         }
00071 
00074         b2BodyType type;
00075 
00078         b2Vec2 position;
00079 
00081         float32 angle;
00082 
00084         b2Vec2 linearVelocity;
00085 
00087         float32 angularVelocity;
00088 
00092         float32 linearDamping;
00093 
00097         float32 angularDamping;
00098 
00101         bool allowSleep;
00102 
00104         bool awake;
00105 
00107         bool fixedRotation;
00108 
00113         bool bullet;
00114 
00116         bool active;
00117 
00119         void* userData;
00120 
00122         float32 gravityScale;
00123 };
00124 
00126 class b2Body
00127 {
00128 public:
00136         b2Fixture* CreateFixture(const b2FixtureDef* def);
00137 
00145         b2Fixture* CreateFixture(const b2Shape* shape, float32 density);
00146 
00154         void DestroyFixture(b2Fixture* fixture);
00155 
00161         void SetTransform(const b2Vec2& position, float32 angle);
00162 
00165         const b2Transform& GetTransform() const;
00166 
00169         const b2Vec2& GetPosition() const;
00170 
00173         float32 GetAngle() const;
00174 
00176         const b2Vec2& GetWorldCenter() const;
00177 
00179         const b2Vec2& GetLocalCenter() const;
00180 
00183         void SetLinearVelocity(const b2Vec2& v);
00184 
00187         b2Vec2 GetLinearVelocity() const;
00188 
00191         void SetAngularVelocity(float32 omega);
00192 
00195         float32 GetAngularVelocity() const;
00196 
00202         void ApplyForce(const b2Vec2& force, const b2Vec2& point);
00203 
00206         void ApplyForceToCenter(const b2Vec2& force);
00207 
00212         void ApplyTorque(float32 torque);
00213 
00219         void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point);
00220 
00223         void ApplyAngularImpulse(float32 impulse);
00224 
00227         float32 GetMass() const;
00228 
00231         float32 GetInertia() const;
00232 
00235         void GetMassData(b2MassData* data) const;
00236 
00242         void SetMassData(const b2MassData* data);
00243 
00247         void ResetMassData();
00248 
00252         b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const;
00253 
00257         b2Vec2 GetWorldVector(const b2Vec2& localVector) const;
00258 
00262         b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const;
00263 
00267         b2Vec2 GetLocalVector(const b2Vec2& worldVector) const;
00268 
00272         b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;
00273 
00277         b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const;
00278 
00280         float32 GetLinearDamping() const;
00281 
00283         void SetLinearDamping(float32 linearDamping);
00284 
00286         float32 GetAngularDamping() const;
00287 
00289         void SetAngularDamping(float32 angularDamping);
00290 
00292         float32 GetGravityScale() const;
00293 
00295         void SetGravityScale(float32 scale);
00296 
00298         void SetType(b2BodyType type);
00299 
00301         b2BodyType GetType() const;
00302 
00304         void SetBullet(bool flag);
00305 
00307         bool IsBullet() const;
00308 
00311         void SetSleepingAllowed(bool flag);
00312 
00314         bool IsSleepingAllowed() const;
00315 
00319         void SetAwake(bool flag);
00320 
00323         bool IsAwake() const;
00324 
00338         void SetActive(bool flag);
00339 
00341         bool IsActive() const;
00342 
00345         void SetFixedRotation(bool flag);
00346 
00348         bool IsFixedRotation() const;
00349 
00351         b2Fixture* GetFixtureList();
00352         const b2Fixture* GetFixtureList() const;
00353 
00355         b2JointEdge* GetJointList();
00356         const b2JointEdge* GetJointList() const;
00357 
00361         b2ContactEdge* GetContactList();
00362         const b2ContactEdge* GetContactList() const;
00363 
00365         b2Body* GetNext();
00366         const b2Body* GetNext() const;
00367 
00369         void* GetUserData() const;
00370 
00372         void SetUserData(void* data);
00373 
00375         b2World* GetWorld();
00376         const b2World* GetWorld() const;
00377 
00378 private:
00379 
00380         friend class b2World;
00381         friend class b2Island;
00382         friend class b2ContactManager;
00383         friend class b2ContactSolver;
00384         friend class b2Contact;
00385         
00386         friend class b2DistanceJoint;
00387         friend class b2GearJoint;
00388         friend class b2WheelJoint;
00389         friend class b2MouseJoint;
00390         friend class b2PrismaticJoint;
00391         friend class b2PulleyJoint;
00392         friend class b2RevoluteJoint;
00393         friend class b2WeldJoint;
00394         friend class b2FrictionJoint;
00395         friend class b2RopeJoint;
00396 
00397         // m_flags
00398         enum
00399         {
00400                 e_islandFlag            = 0x0001,
00401                 e_awakeFlag                     = 0x0002,
00402                 e_autoSleepFlag         = 0x0004,
00403                 e_bulletFlag            = 0x0008,
00404                 e_fixedRotationFlag     = 0x0010,
00405                 e_activeFlag            = 0x0020,
00406                 e_toiFlag                       = 0x0040
00407         };
00408 
00409         b2Body(const b2BodyDef* bd, b2World* world);
00410         ~b2Body();
00411 
00412         void SynchronizeFixtures();
00413         void SynchronizeTransform();
00414 
00415         // This is used to prevent connected bodies from colliding.
00416         // It may lie, depending on the collideConnected flag.
00417         bool ShouldCollide(const b2Body* other) const;
00418 
00419         void Advance(float32 t);
00420 
00421         b2BodyType m_type;
00422 
00423         uint16 m_flags;
00424 
00425         int32 m_islandIndex;
00426 
00427         b2Transform m_xf;               // the body origin transform
00428         b2Sweep m_sweep;                // the swept motion for CCD
00429 
00430         b2Vec2 m_linearVelocity;
00431         float32 m_angularVelocity;
00432 
00433         b2Vec2 m_force;
00434         float32 m_torque;
00435 
00436         b2World* m_world;
00437         b2Body* m_prev;
00438         b2Body* m_next;
00439 
00440         b2Fixture* m_fixtureList;
00441         int32 m_fixtureCount;
00442 
00443         b2JointEdge* m_jointList;
00444         b2ContactEdge* m_contactList;
00445 
00446         float32 m_mass, m_invMass;
00447 
00448         // Rotational inertia about the center of mass.
00449         float32 m_I, m_invI;
00450 
00451         float32 m_linearDamping;
00452         float32 m_angularDamping;
00453         float32 m_gravityScale;
00454 
00455         float32 m_sleepTime;
00456 
00457         void* m_userData;
00458 };
00459 
00460 inline b2BodyType b2Body::GetType() const
00461 {
00462         return m_type;
00463 }
00464 
00465 inline const b2Transform& b2Body::GetTransform() const
00466 {
00467         return m_xf;
00468 }
00469 
00470 inline const b2Vec2& b2Body::GetPosition() const
00471 {
00472         return m_xf.p;
00473 }
00474 
00475 inline float32 b2Body::GetAngle() const
00476 {
00477         return m_xf.q.GetAngle();
00478 }
00479 
00480 inline const b2Vec2& b2Body::GetWorldCenter() const
00481 {
00482         return m_sweep.c;
00483 }
00484 
00485 inline const b2Vec2& b2Body::GetLocalCenter() const
00486 {
00487         return m_sweep.localCenter;
00488 }
00489 
00490 inline void b2Body::SetLinearVelocity(const b2Vec2& v)
00491 {
00492         if (m_type == b2_staticBody)
00493         {
00494                 return;
00495         }
00496 
00497         if (b2Dot(v,v) > 0.0f)
00498         {
00499                 SetAwake(true);
00500         }
00501 
00502         m_linearVelocity = v;
00503 }
00504 
00505 inline b2Vec2 b2Body::GetLinearVelocity() const
00506 {
00507         return m_linearVelocity;
00508 }
00509 
00510 inline void b2Body::SetAngularVelocity(float32 w)
00511 {
00512         if (m_type == b2_staticBody)
00513         {
00514                 return;
00515         }
00516 
00517         if (w * w > 0.0f)
00518         {
00519                 SetAwake(true);
00520         }
00521 
00522         m_angularVelocity = w;
00523 }
00524 
00525 inline float32 b2Body::GetAngularVelocity() const
00526 {
00527         return m_angularVelocity;
00528 }
00529 
00530 inline float32 b2Body::GetMass() const
00531 {
00532         return m_mass;
00533 }
00534 
00535 inline float32 b2Body::GetInertia() const
00536 {
00537         return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
00538 }
00539 
00540 inline void b2Body::GetMassData(b2MassData* data) const
00541 {
00542         data->mass = m_mass;
00543         data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
00544         data->center = m_sweep.localCenter;
00545 }
00546 
00547 inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const
00548 {
00549         return b2Mul(m_xf, localPoint);
00550 }
00551 
00552 inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const
00553 {
00554         return b2Mul(m_xf.q, localVector);
00555 }
00556 
00557 inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const
00558 {
00559         return b2MulT(m_xf, worldPoint);
00560 }
00561 
00562 inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const
00563 {
00564         return b2MulT(m_xf.q, worldVector);
00565 }
00566 
00567 inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const
00568 {
00569         return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
00570 }
00571 
00572 inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const
00573 {
00574         return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
00575 }
00576 
00577 inline float32 b2Body::GetLinearDamping() const
00578 {
00579         return m_linearDamping;
00580 }
00581 
00582 inline void b2Body::SetLinearDamping(float32 linearDamping)
00583 {
00584         m_linearDamping = linearDamping;
00585 }
00586 
00587 inline float32 b2Body::GetAngularDamping() const
00588 {
00589         return m_angularDamping;
00590 }
00591 
00592 inline void b2Body::SetAngularDamping(float32 angularDamping)
00593 {
00594         m_angularDamping = angularDamping;
00595 }
00596 
00597 inline float32 b2Body::GetGravityScale() const
00598 {
00599         return m_gravityScale;
00600 }
00601 
00602 inline void b2Body::SetGravityScale(float32 scale)
00603 {
00604         m_gravityScale = scale;
00605 }
00606 
00607 inline void b2Body::SetBullet(bool flag)
00608 {
00609         if (flag)
00610         {
00611                 m_flags |= e_bulletFlag;
00612         }
00613         else
00614         {
00615                 m_flags &= ~e_bulletFlag;
00616         }
00617 }
00618 
00619 inline bool b2Body::IsBullet() const
00620 {
00621         return (m_flags & e_bulletFlag) == e_bulletFlag;
00622 }
00623 
00624 inline void b2Body::SetAwake(bool flag)
00625 {
00626         if (flag)
00627         {
00628                 if ((m_flags & e_awakeFlag) == 0)
00629                 {
00630                         m_flags |= e_awakeFlag;
00631                         m_sleepTime = 0.0f;
00632                 }
00633         }
00634         else
00635         {
00636                 m_flags &= ~e_awakeFlag;
00637                 m_sleepTime = 0.0f;
00638                 m_linearVelocity.SetZero();
00639                 m_angularVelocity = 0.0f;
00640                 m_force.SetZero();
00641                 m_torque = 0.0f;
00642         }
00643 }
00644 
00645 inline bool b2Body::IsAwake() const
00646 {
00647         return (m_flags & e_awakeFlag) == e_awakeFlag;
00648 }
00649 
00650 inline bool b2Body::IsActive() const
00651 {
00652         return (m_flags & e_activeFlag) == e_activeFlag;
00653 }
00654 
00655 inline void b2Body::SetFixedRotation(bool flag)
00656 {
00657         if (flag)
00658         {
00659                 m_flags |= e_fixedRotationFlag;
00660         }
00661         else
00662         {
00663                 m_flags &= ~e_fixedRotationFlag;
00664         }
00665 
00666         ResetMassData();
00667 }
00668 
00669 inline bool b2Body::IsFixedRotation() const
00670 {
00671         return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag;
00672 }
00673 
00674 inline void b2Body::SetSleepingAllowed(bool flag)
00675 {
00676         if (flag)
00677         {
00678                 m_flags |= e_autoSleepFlag;
00679         }
00680         else
00681         {
00682                 m_flags &= ~e_autoSleepFlag;
00683                 SetAwake(true);
00684         }
00685 }
00686 
00687 inline bool b2Body::IsSleepingAllowed() const
00688 {
00689         return (m_flags & e_autoSleepFlag) == e_autoSleepFlag;
00690 }
00691 
00692 inline b2Fixture* b2Body::GetFixtureList()
00693 {
00694         return m_fixtureList;
00695 }
00696 
00697 inline const b2Fixture* b2Body::GetFixtureList() const
00698 {
00699         return m_fixtureList;
00700 }
00701 
00702 inline b2JointEdge* b2Body::GetJointList()
00703 {
00704         return m_jointList;
00705 }
00706 
00707 inline const b2JointEdge* b2Body::GetJointList() const
00708 {
00709         return m_jointList;
00710 }
00711 
00712 inline b2ContactEdge* b2Body::GetContactList()
00713 {
00714         return m_contactList;
00715 }
00716 
00717 inline const b2ContactEdge* b2Body::GetContactList() const
00718 {
00719         return m_contactList;
00720 }
00721 
00722 inline b2Body* b2Body::GetNext()
00723 {
00724         return m_next;
00725 }
00726 
00727 inline const b2Body* b2Body::GetNext() const
00728 {
00729         return m_next;
00730 }
00731 
00732 inline void b2Body::SetUserData(void* data)
00733 {
00734         m_userData = data;
00735 }
00736 
00737 inline void* b2Body::GetUserData() const
00738 {
00739         return m_userData;
00740 }
00741 
00742 inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point)
00743 {
00744         if (m_type != b2_dynamicBody)
00745         {
00746                 return;
00747         }
00748 
00749         if (IsAwake() == false)
00750         {
00751                 SetAwake(true);
00752         }
00753 
00754         m_force += force;
00755         m_torque += b2Cross(point - m_sweep.c, force);
00756 }
00757 
00758 inline void b2Body::ApplyForceToCenter(const b2Vec2& force)
00759 {
00760         if (m_type != b2_dynamicBody)
00761         {
00762                 return;
00763         }
00764 
00765         if (IsAwake() == false)
00766         {
00767                 SetAwake(true);
00768         }
00769 
00770         m_force += force;
00771 }
00772 
00773 inline void b2Body::ApplyTorque(float32 torque)
00774 {
00775         if (m_type != b2_dynamicBody)
00776         {
00777                 return;
00778         }
00779 
00780         if (IsAwake() == false)
00781         {
00782                 SetAwake(true);
00783         }
00784 
00785         m_torque += torque;
00786 }
00787 
00788 inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point)
00789 {
00790         if (m_type != b2_dynamicBody)
00791         {
00792                 return;
00793         }
00794 
00795         if (IsAwake() == false)
00796         {
00797                 SetAwake(true);
00798         }
00799         m_linearVelocity += m_invMass * impulse;
00800         m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse);
00801 }
00802 
00803 inline void b2Body::ApplyAngularImpulse(float32 impulse)
00804 {
00805         if (m_type != b2_dynamicBody)
00806         {
00807                 return;
00808         }
00809 
00810         if (IsAwake() == false)
00811         {
00812                 SetAwake(true);
00813         }
00814         m_angularVelocity += m_invI * impulse;
00815 }
00816 
00817 inline void b2Body::SynchronizeTransform()
00818 {
00819         m_xf.q.Set(m_sweep.a);
00820         m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter);
00821 }
00822 
00823 inline void b2Body::Advance(float32 alpha)
00824 {
00825         // Advance to the new safe time. This doesn't sync the broad-phase.
00826         m_sweep.Advance(alpha);
00827         m_sweep.c = m_sweep.c0;
00828         m_sweep.a = m_sweep.a0;
00829         m_xf.q.Set(m_sweep.a);
00830         m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter);
00831 }
00832 
00833 inline b2World* b2Body::GetWorld()
00834 {
00835         return m_world;
00836 }
00837 
00838 inline const b2World* b2Body::GetWorld() const
00839 {
00840         return m_world;
00841 }
00842 
00843 #endif
 All Classes Files Functions Variables Enumerations Enumerator Defines