Box2D  2.2.1
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 
00379         void Dump();
00380 
00381 private:
00382 
00383         friend class b2World;
00384         friend class b2Island;
00385         friend class b2ContactManager;
00386         friend class b2ContactSolver;
00387         friend class b2Contact;
00388         
00389         friend class b2DistanceJoint;
00390         friend class b2GearJoint;
00391         friend class b2WheelJoint;
00392         friend class b2MouseJoint;
00393         friend class b2PrismaticJoint;
00394         friend class b2PulleyJoint;
00395         friend class b2RevoluteJoint;
00396         friend class b2WeldJoint;
00397         friend class b2FrictionJoint;
00398         friend class b2RopeJoint;
00399 
00400         // m_flags
00401         enum
00402         {
00403                 e_islandFlag            = 0x0001,
00404                 e_awakeFlag                     = 0x0002,
00405                 e_autoSleepFlag         = 0x0004,
00406                 e_bulletFlag            = 0x0008,
00407                 e_fixedRotationFlag     = 0x0010,
00408                 e_activeFlag            = 0x0020,
00409                 e_toiFlag                       = 0x0040
00410         };
00411 
00412         b2Body(const b2BodyDef* bd, b2World* world);
00413         ~b2Body();
00414 
00415         void SynchronizeFixtures();
00416         void SynchronizeTransform();
00417 
00418         // This is used to prevent connected bodies from colliding.
00419         // It may lie, depending on the collideConnected flag.
00420         bool ShouldCollide(const b2Body* other) const;
00421 
00422         void Advance(float32 t);
00423 
00424         b2BodyType m_type;
00425 
00426         uint16 m_flags;
00427 
00428         int32 m_islandIndex;
00429 
00430         b2Transform m_xf;               // the body origin transform
00431         b2Sweep m_sweep;                // the swept motion for CCD
00432 
00433         b2Vec2 m_linearVelocity;
00434         float32 m_angularVelocity;
00435 
00436         b2Vec2 m_force;
00437         float32 m_torque;
00438 
00439         b2World* m_world;
00440         b2Body* m_prev;
00441         b2Body* m_next;
00442 
00443         b2Fixture* m_fixtureList;
00444         int32 m_fixtureCount;
00445 
00446         b2JointEdge* m_jointList;
00447         b2ContactEdge* m_contactList;
00448 
00449         float32 m_mass, m_invMass;
00450 
00451         // Rotational inertia about the center of mass.
00452         float32 m_I, m_invI;
00453 
00454         float32 m_linearDamping;
00455         float32 m_angularDamping;
00456         float32 m_gravityScale;
00457 
00458         float32 m_sleepTime;
00459 
00460         void* m_userData;
00461 };
00462 
00463 inline b2BodyType b2Body::GetType() const
00464 {
00465         return m_type;
00466 }
00467 
00468 inline const b2Transform& b2Body::GetTransform() const
00469 {
00470         return m_xf;
00471 }
00472 
00473 inline const b2Vec2& b2Body::GetPosition() const
00474 {
00475         return m_xf.p;
00476 }
00477 
00478 inline float32 b2Body::GetAngle() const
00479 {
00480         return m_sweep.a;
00481 }
00482 
00483 inline const b2Vec2& b2Body::GetWorldCenter() const
00484 {
00485         return m_sweep.c;
00486 }
00487 
00488 inline const b2Vec2& b2Body::GetLocalCenter() const
00489 {
00490         return m_sweep.localCenter;
00491 }
00492 
00493 inline void b2Body::SetLinearVelocity(const b2Vec2& v)
00494 {
00495         if (m_type == b2_staticBody)
00496         {
00497                 return;
00498         }
00499 
00500         if (b2Dot(v,v) > 0.0f)
00501         {
00502                 SetAwake(true);
00503         }
00504 
00505         m_linearVelocity = v;
00506 }
00507 
00508 inline b2Vec2 b2Body::GetLinearVelocity() const
00509 {
00510         return m_linearVelocity;
00511 }
00512 
00513 inline void b2Body::SetAngularVelocity(float32 w)
00514 {
00515         if (m_type == b2_staticBody)
00516         {
00517                 return;
00518         }
00519 
00520         if (w * w > 0.0f)
00521         {
00522                 SetAwake(true);
00523         }
00524 
00525         m_angularVelocity = w;
00526 }
00527 
00528 inline float32 b2Body::GetAngularVelocity() const
00529 {
00530         return m_angularVelocity;
00531 }
00532 
00533 inline float32 b2Body::GetMass() const
00534 {
00535         return m_mass;
00536 }
00537 
00538 inline float32 b2Body::GetInertia() const
00539 {
00540         return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
00541 }
00542 
00543 inline void b2Body::GetMassData(b2MassData* data) const
00544 {
00545         data->mass = m_mass;
00546         data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
00547         data->center = m_sweep.localCenter;
00548 }
00549 
00550 inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const
00551 {
00552         return b2Mul(m_xf, localPoint);
00553 }
00554 
00555 inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const
00556 {
00557         return b2Mul(m_xf.q, localVector);
00558 }
00559 
00560 inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const
00561 {
00562         return b2MulT(m_xf, worldPoint);
00563 }
00564 
00565 inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const
00566 {
00567         return b2MulT(m_xf.q, worldVector);
00568 }
00569 
00570 inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const
00571 {
00572         return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
00573 }
00574 
00575 inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const
00576 {
00577         return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
00578 }
00579 
00580 inline float32 b2Body::GetLinearDamping() const
00581 {
00582         return m_linearDamping;
00583 }
00584 
00585 inline void b2Body::SetLinearDamping(float32 linearDamping)
00586 {
00587         m_linearDamping = linearDamping;
00588 }
00589 
00590 inline float32 b2Body::GetAngularDamping() const
00591 {
00592         return m_angularDamping;
00593 }
00594 
00595 inline void b2Body::SetAngularDamping(float32 angularDamping)
00596 {
00597         m_angularDamping = angularDamping;
00598 }
00599 
00600 inline float32 b2Body::GetGravityScale() const
00601 {
00602         return m_gravityScale;
00603 }
00604 
00605 inline void b2Body::SetGravityScale(float32 scale)
00606 {
00607         m_gravityScale = scale;
00608 }
00609 
00610 inline void b2Body::SetBullet(bool flag)
00611 {
00612         if (flag)
00613         {
00614                 m_flags |= e_bulletFlag;
00615         }
00616         else
00617         {
00618                 m_flags &= ~e_bulletFlag;
00619         }
00620 }
00621 
00622 inline bool b2Body::IsBullet() const
00623 {
00624         return (m_flags & e_bulletFlag) == e_bulletFlag;
00625 }
00626 
00627 inline void b2Body::SetAwake(bool flag)
00628 {
00629         if (flag)
00630         {
00631                 if ((m_flags & e_awakeFlag) == 0)
00632                 {
00633                         m_flags |= e_awakeFlag;
00634                         m_sleepTime = 0.0f;
00635                 }
00636         }
00637         else
00638         {
00639                 m_flags &= ~e_awakeFlag;
00640                 m_sleepTime = 0.0f;
00641                 m_linearVelocity.SetZero();
00642                 m_angularVelocity = 0.0f;
00643                 m_force.SetZero();
00644                 m_torque = 0.0f;
00645         }
00646 }
00647 
00648 inline bool b2Body::IsAwake() const
00649 {
00650         return (m_flags & e_awakeFlag) == e_awakeFlag;
00651 }
00652 
00653 inline bool b2Body::IsActive() const
00654 {
00655         return (m_flags & e_activeFlag) == e_activeFlag;
00656 }
00657 
00658 inline void b2Body::SetFixedRotation(bool flag)
00659 {
00660         if (flag)
00661         {
00662                 m_flags |= e_fixedRotationFlag;
00663         }
00664         else
00665         {
00666                 m_flags &= ~e_fixedRotationFlag;
00667         }
00668 
00669         ResetMassData();
00670 }
00671 
00672 inline bool b2Body::IsFixedRotation() const
00673 {
00674         return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag;
00675 }
00676 
00677 inline void b2Body::SetSleepingAllowed(bool flag)
00678 {
00679         if (flag)
00680         {
00681                 m_flags |= e_autoSleepFlag;
00682         }
00683         else
00684         {
00685                 m_flags &= ~e_autoSleepFlag;
00686                 SetAwake(true);
00687         }
00688 }
00689 
00690 inline bool b2Body::IsSleepingAllowed() const
00691 {
00692         return (m_flags & e_autoSleepFlag) == e_autoSleepFlag;
00693 }
00694 
00695 inline b2Fixture* b2Body::GetFixtureList()
00696 {
00697         return m_fixtureList;
00698 }
00699 
00700 inline const b2Fixture* b2Body::GetFixtureList() const
00701 {
00702         return m_fixtureList;
00703 }
00704 
00705 inline b2JointEdge* b2Body::GetJointList()
00706 {
00707         return m_jointList;
00708 }
00709 
00710 inline const b2JointEdge* b2Body::GetJointList() const
00711 {
00712         return m_jointList;
00713 }
00714 
00715 inline b2ContactEdge* b2Body::GetContactList()
00716 {
00717         return m_contactList;
00718 }
00719 
00720 inline const b2ContactEdge* b2Body::GetContactList() const
00721 {
00722         return m_contactList;
00723 }
00724 
00725 inline b2Body* b2Body::GetNext()
00726 {
00727         return m_next;
00728 }
00729 
00730 inline const b2Body* b2Body::GetNext() const
00731 {
00732         return m_next;
00733 }
00734 
00735 inline void b2Body::SetUserData(void* data)
00736 {
00737         m_userData = data;
00738 }
00739 
00740 inline void* b2Body::GetUserData() const
00741 {
00742         return m_userData;
00743 }
00744 
00745 inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point)
00746 {
00747         if (m_type != b2_dynamicBody)
00748         {
00749                 return;
00750         }
00751 
00752         if (IsAwake() == false)
00753         {
00754                 SetAwake(true);
00755         }
00756 
00757         m_force += force;
00758         m_torque += b2Cross(point - m_sweep.c, force);
00759 }
00760 
00761 inline void b2Body::ApplyForceToCenter(const b2Vec2& force)
00762 {
00763         if (m_type != b2_dynamicBody)
00764         {
00765                 return;
00766         }
00767 
00768         if (IsAwake() == false)
00769         {
00770                 SetAwake(true);
00771         }
00772 
00773         m_force += force;
00774 }
00775 
00776 inline void b2Body::ApplyTorque(float32 torque)
00777 {
00778         if (m_type != b2_dynamicBody)
00779         {
00780                 return;
00781         }
00782 
00783         if (IsAwake() == false)
00784         {
00785                 SetAwake(true);
00786         }
00787 
00788         m_torque += torque;
00789 }
00790 
00791 inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point)
00792 {
00793         if (m_type != b2_dynamicBody)
00794         {
00795                 return;
00796         }
00797 
00798         if (IsAwake() == false)
00799         {
00800                 SetAwake(true);
00801         }
00802         m_linearVelocity += m_invMass * impulse;
00803         m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse);
00804 }
00805 
00806 inline void b2Body::ApplyAngularImpulse(float32 impulse)
00807 {
00808         if (m_type != b2_dynamicBody)
00809         {
00810                 return;
00811         }
00812 
00813         if (IsAwake() == false)
00814         {
00815                 SetAwake(true);
00816         }
00817         m_angularVelocity += m_invI * impulse;
00818 }
00819 
00820 inline void b2Body::SynchronizeTransform()
00821 {
00822         m_xf.q.Set(m_sweep.a);
00823         m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter);
00824 }
00825 
00826 inline void b2Body::Advance(float32 alpha)
00827 {
00828         // Advance to the new safe time. This doesn't sync the broad-phase.
00829         m_sweep.Advance(alpha);
00830         m_sweep.c = m_sweep.c0;
00831         m_sweep.a = m_sweep.a0;
00832         m_xf.q.Set(m_sweep.a);
00833         m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter);
00834 }
00835 
00836 inline b2World* b2Body::GetWorld()
00837 {
00838         return m_world;
00839 }
00840 
00841 inline const b2World* b2Body::GetWorld() const
00842 {
00843         return m_world;
00844 }
00845 
00846 #endif
 All Classes Files Functions Variables Enumerations Enumerator Defines