![]() |
Box2D
2.2.0
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 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