00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00048 struct b2BodyDef
00049 {
00051 b2BodyDef()
00052 {
00053 userData = NULL;
00054 position.Set(0.0f, 0.0f);
00055 angle = 0.0f;
00056 linearVelocity.Set(0.0f, 0.0f);
00057 angularVelocity = 0.0f;
00058 linearDamping = 0.0f;
00059 angularDamping = 0.0f;
00060 allowSleep = true;
00061 awake = true;
00062 fixedRotation = false;
00063 bullet = false;
00064 type = b2_staticBody;
00065 active = true;
00066 inertiaScale = 1.0f;
00067 }
00068
00071 b2BodyType type;
00072
00075 b2Vec2 position;
00076
00078 float32 angle;
00079
00081 b2Vec2 linearVelocity;
00082
00084 float32 angularVelocity;
00085
00089 float32 linearDamping;
00090
00094 float32 angularDamping;
00095
00098 bool allowSleep;
00099
00101 bool awake;
00102
00104 bool fixedRotation;
00105
00110 bool bullet;
00111
00113 bool active;
00114
00116 void* userData;
00117
00119 float32 inertiaScale;
00120 };
00121
00123 class b2Body
00124 {
00125 public:
00133 b2Fixture* CreateFixture(const b2FixtureDef* def);
00134
00142 b2Fixture* CreateFixture(const b2Shape* shape, float32 density);
00143
00151 void DestroyFixture(b2Fixture* fixture);
00152
00158 void SetTransform(const b2Vec2& position, float32 angle);
00159
00162 const b2Transform& GetTransform() const;
00163
00166 const b2Vec2& GetPosition() const;
00167
00170 float32 GetAngle() const;
00171
00173 const b2Vec2& GetWorldCenter() const;
00174
00176 const b2Vec2& GetLocalCenter() const;
00177
00180 void SetLinearVelocity(const b2Vec2& v);
00181
00184 b2Vec2 GetLinearVelocity() const;
00185
00188 void SetAngularVelocity(float32 omega);
00189
00192 float32 GetAngularVelocity() const;
00193
00199 void ApplyForce(const b2Vec2& force, const b2Vec2& point);
00200
00205 void ApplyTorque(float32 torque);
00206
00212 void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point);
00213
00216 void ApplyAngularImpulse(float32 impulse);
00217
00220 float32 GetMass() const;
00221
00224 float32 GetInertia() const;
00225
00228 void GetMassData(b2MassData* data) const;
00229
00235 void SetMassData(const b2MassData* data);
00236
00240 void ResetMassData();
00241
00245 b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const;
00246
00250 b2Vec2 GetWorldVector(const b2Vec2& localVector) const;
00251
00255 b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const;
00256
00260 b2Vec2 GetLocalVector(const b2Vec2& worldVector) const;
00261
00265 b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;
00266
00270 b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const;
00271
00273 float32 GetLinearDamping() const;
00274
00276 void SetLinearDamping(float32 linearDamping);
00277
00279 float32 GetAngularDamping() const;
00280
00282 void SetAngularDamping(float32 angularDamping);
00283
00285 void SetType(b2BodyType type);
00286
00288 b2BodyType GetType() const;
00289
00291 void SetBullet(bool flag);
00292
00294 bool IsBullet() const;
00295
00298 void SetSleepingAllowed(bool flag);
00299
00301 bool IsSleepingAllowed() const;
00302
00306 void SetAwake(bool flag);
00307
00310 bool IsAwake() const;
00311
00325 void SetActive(bool flag);
00326
00328 bool IsActive() const;
00329
00332 void SetFixedRotation(bool flag);
00333
00335 bool IsFixedRotation() const;
00336
00338 b2Fixture* GetFixtureList();
00339 const b2Fixture* GetFixtureList() const;
00340
00342 b2JointEdge* GetJointList();
00343 const b2JointEdge* GetJointList() const;
00344
00348 b2ContactEdge* GetContactList();
00349 const b2ContactEdge* GetContactList() const;
00350
00352 b2Body* GetNext();
00353 const b2Body* GetNext() const;
00354
00356 void* GetUserData() const;
00357
00359 void SetUserData(void* data);
00360
00362 b2World* GetWorld();
00363 const b2World* GetWorld() const;
00364
00365 private:
00366
00367 friend class b2World;
00368 friend class b2Island;
00369 friend class b2ContactManager;
00370 friend class b2ContactSolver;
00371 friend class b2TOISolver;
00372
00373 friend class b2DistanceJoint;
00374 friend class b2GearJoint;
00375 friend class b2LineJoint;
00376 friend class b2MouseJoint;
00377 friend class b2PrismaticJoint;
00378 friend class b2PulleyJoint;
00379 friend class b2RevoluteJoint;
00380 friend class b2WeldJoint;
00381 friend class b2FrictionJoint;
00382
00383
00384 enum
00385 {
00386 e_islandFlag = 0x0001,
00387 e_awakeFlag = 0x0002,
00388 e_autoSleepFlag = 0x0004,
00389 e_bulletFlag = 0x0008,
00390 e_fixedRotationFlag = 0x0010,
00391 e_activeFlag = 0x0020,
00392 e_toiFlag = 0x0040,
00393 };
00394
00395 b2Body(const b2BodyDef* bd, b2World* world);
00396 ~b2Body();
00397
00398 void SynchronizeFixtures();
00399 void SynchronizeTransform();
00400
00401
00402
00403 bool ShouldCollide(const b2Body* other) const;
00404
00405 void Advance(float32 t);
00406
00407 b2BodyType m_type;
00408
00409 uint16 m_flags;
00410
00411 int32 m_islandIndex;
00412
00413 b2Transform m_xf;
00414 b2Sweep m_sweep;
00415
00416 b2Vec2 m_linearVelocity;
00417 float32 m_angularVelocity;
00418
00419 b2Vec2 m_force;
00420 float32 m_torque;
00421
00422 b2World* m_world;
00423 b2Body* m_prev;
00424 b2Body* m_next;
00425
00426 b2Fixture* m_fixtureList;
00427 int32 m_fixtureCount;
00428
00429 b2JointEdge* m_jointList;
00430 b2ContactEdge* m_contactList;
00431
00432 float32 m_mass, m_invMass;
00433
00434
00435 float32 m_I, m_invI;
00436
00437 float32 m_linearDamping;
00438 float32 m_angularDamping;
00439
00440 float32 m_sleepTime;
00441
00442 void* m_userData;
00443 };
00444
00445 inline b2BodyType b2Body::GetType() const
00446 {
00447 return m_type;
00448 }
00449
00450 inline const b2Transform& b2Body::GetTransform() const
00451 {
00452 return m_xf;
00453 }
00454
00455 inline const b2Vec2& b2Body::GetPosition() const
00456 {
00457 return m_xf.position;
00458 }
00459
00460 inline float32 b2Body::GetAngle() const
00461 {
00462 return m_sweep.a;
00463 }
00464
00465 inline const b2Vec2& b2Body::GetWorldCenter() const
00466 {
00467 return m_sweep.c;
00468 }
00469
00470 inline const b2Vec2& b2Body::GetLocalCenter() const
00471 {
00472 return m_sweep.localCenter;
00473 }
00474
00475 inline void b2Body::SetLinearVelocity(const b2Vec2& v)
00476 {
00477 if (m_type == b2_staticBody)
00478 {
00479 return;
00480 }
00481
00482 if (b2Dot(v,v) > 0.0f)
00483 {
00484 SetAwake(true);
00485 }
00486
00487 m_linearVelocity = v;
00488 }
00489
00490 inline b2Vec2 b2Body::GetLinearVelocity() const
00491 {
00492 return m_linearVelocity;
00493 }
00494
00495 inline void b2Body::SetAngularVelocity(float32 w)
00496 {
00497 if (m_type == b2_staticBody)
00498 {
00499 return;
00500 }
00501
00502 if (w * w > 0.0f)
00503 {
00504 SetAwake(true);
00505 }
00506
00507 m_angularVelocity = w;
00508 }
00509
00510 inline float32 b2Body::GetAngularVelocity() const
00511 {
00512 return m_angularVelocity;
00513 }
00514
00515 inline float32 b2Body::GetMass() const
00516 {
00517 return m_mass;
00518 }
00519
00520 inline float32 b2Body::GetInertia() const
00521 {
00522 return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
00523 }
00524
00525 inline void b2Body::GetMassData(b2MassData* data) const
00526 {
00527 data->mass = m_mass;
00528 data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter);
00529 data->center = m_sweep.localCenter;
00530 }
00531
00532 inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const
00533 {
00534 return b2Mul(m_xf, localPoint);
00535 }
00536
00537 inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const
00538 {
00539 return b2Mul(m_xf.R, localVector);
00540 }
00541
00542 inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const
00543 {
00544 return b2MulT(m_xf, worldPoint);
00545 }
00546
00547 inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const
00548 {
00549 return b2MulT(m_xf.R, worldVector);
00550 }
00551
00552 inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const
00553 {
00554 return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
00555 }
00556
00557 inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const
00558 {
00559 return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
00560 }
00561
00562 inline float32 b2Body::GetLinearDamping() const
00563 {
00564 return m_linearDamping;
00565 }
00566
00567 inline void b2Body::SetLinearDamping(float32 linearDamping)
00568 {
00569 m_linearDamping = linearDamping;
00570 }
00571
00572 inline float32 b2Body::GetAngularDamping() const
00573 {
00574 return m_angularDamping;
00575 }
00576
00577 inline void b2Body::SetAngularDamping(float32 angularDamping)
00578 {
00579 m_angularDamping = angularDamping;
00580 }
00581
00582 inline void b2Body::SetBullet(bool flag)
00583 {
00584 if (flag)
00585 {
00586 m_flags |= e_bulletFlag;
00587 }
00588 else
00589 {
00590 m_flags &= ~e_bulletFlag;
00591 }
00592 }
00593
00594 inline bool b2Body::IsBullet() const
00595 {
00596 return (m_flags & e_bulletFlag) == e_bulletFlag;
00597 }
00598
00599 inline void b2Body::SetAwake(bool flag)
00600 {
00601 if (flag)
00602 {
00603 if ((m_flags & e_awakeFlag) == 0)
00604 {
00605 m_flags |= e_awakeFlag;
00606 m_sleepTime = 0.0f;
00607 }
00608 }
00609 else
00610 {
00611 m_flags &= ~e_awakeFlag;
00612 m_sleepTime = 0.0f;
00613 m_linearVelocity.SetZero();
00614 m_angularVelocity = 0.0f;
00615 m_force.SetZero();
00616 m_torque = 0.0f;
00617 }
00618 }
00619
00620 inline bool b2Body::IsAwake() const
00621 {
00622 return (m_flags & e_awakeFlag) == e_awakeFlag;
00623 }
00624
00625 inline bool b2Body::IsActive() const
00626 {
00627 return (m_flags & e_activeFlag) == e_activeFlag;
00628 }
00629
00630 inline void b2Body::SetFixedRotation(bool flag)
00631 {
00632 if (flag)
00633 {
00634 m_flags |= e_fixedRotationFlag;
00635 }
00636 else
00637 {
00638 m_flags &= ~e_fixedRotationFlag;
00639 }
00640
00641 ResetMassData();
00642 }
00643
00644 inline bool b2Body::IsFixedRotation() const
00645 {
00646 return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag;
00647 }
00648
00649 inline void b2Body::SetSleepingAllowed(bool flag)
00650 {
00651 if (flag)
00652 {
00653 m_flags |= e_autoSleepFlag;
00654 }
00655 else
00656 {
00657 m_flags &= ~e_autoSleepFlag;
00658 SetAwake(true);
00659 }
00660 }
00661
00662 inline bool b2Body::IsSleepingAllowed() const
00663 {
00664 return (m_flags & e_autoSleepFlag) == e_autoSleepFlag;
00665 }
00666
00667 inline b2Fixture* b2Body::GetFixtureList()
00668 {
00669 return m_fixtureList;
00670 }
00671
00672 inline const b2Fixture* b2Body::GetFixtureList() const
00673 {
00674 return m_fixtureList;
00675 }
00676
00677 inline b2JointEdge* b2Body::GetJointList()
00678 {
00679 return m_jointList;
00680 }
00681
00682 inline const b2JointEdge* b2Body::GetJointList() const
00683 {
00684 return m_jointList;
00685 }
00686
00687 inline b2ContactEdge* b2Body::GetContactList()
00688 {
00689 return m_contactList;
00690 }
00691
00692 inline const b2ContactEdge* b2Body::GetContactList() const
00693 {
00694 return m_contactList;
00695 }
00696
00697 inline b2Body* b2Body::GetNext()
00698 {
00699 return m_next;
00700 }
00701
00702 inline const b2Body* b2Body::GetNext() const
00703 {
00704 return m_next;
00705 }
00706
00707 inline void b2Body::SetUserData(void* data)
00708 {
00709 m_userData = data;
00710 }
00711
00712 inline void* b2Body::GetUserData() const
00713 {
00714 return m_userData;
00715 }
00716
00717 inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point)
00718 {
00719 if (m_type != b2_dynamicBody)
00720 {
00721 return;
00722 }
00723
00724 if (IsAwake() == false)
00725 {
00726 SetAwake(true);
00727 }
00728
00729 m_force += force;
00730 m_torque += b2Cross(point - m_sweep.c, force);
00731 }
00732
00733 inline void b2Body::ApplyTorque(float32 torque)
00734 {
00735 if (m_type != b2_dynamicBody)
00736 {
00737 return;
00738 }
00739
00740 if (IsAwake() == false)
00741 {
00742 SetAwake(true);
00743 }
00744
00745 m_torque += torque;
00746 }
00747
00748 inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point)
00749 {
00750 if (m_type != b2_dynamicBody)
00751 {
00752 return;
00753 }
00754
00755 if (IsAwake() == false)
00756 {
00757 SetAwake(true);
00758 }
00759 m_linearVelocity += m_invMass * impulse;
00760 m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse);
00761 }
00762
00763 inline void b2Body::ApplyAngularImpulse(float32 impulse)
00764 {
00765 if (m_type != b2_dynamicBody)
00766 {
00767 return;
00768 }
00769
00770 if (IsAwake() == false)
00771 {
00772 SetAwake(true);
00773 }
00774 m_angularVelocity += m_invI * impulse;
00775 }
00776
00777 inline void b2Body::SynchronizeTransform()
00778 {
00779 m_xf.R.Set(m_sweep.a);
00780 m_xf.position = m_sweep.c - b2Mul(m_xf.R, m_sweep.localCenter);
00781 }
00782
00783 inline void b2Body::Advance(float32 t)
00784 {
00785
00786 m_sweep.Advance(t);
00787 m_sweep.c = m_sweep.c0;
00788 m_sweep.a = m_sweep.a0;
00789 SynchronizeTransform();
00790 }
00791
00792 inline b2World* b2Body::GetWorld()
00793 {
00794 return m_world;
00795 }
00796
00797 inline const b2World* b2Body::GetWorld() const
00798 {
00799 return m_world;
00800 }
00801
00802 #endif