![]() |
Box2D
2.2.1
A 2D Physics Engine for Games
|
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