1 /* 2 * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org 3 * 4 * This software is provided 'as-is', without any express or implied 5 * warranty. In no event will the authors be held liable for any damages 6 * arising from the use of this software. 7 * Permission is granted to anyone to use this software for any purpose, 8 * including commercial applications, and to alter it and redistribute it 9 * freely, subject to the following restrictions: 10 * 1. The origin of this software must not be misrepresented; you must not 11 * claim that you wrote the original software. If you use this software 12 * in a product, an acknowledgment in the product documentation would be 13 * appreciated but is not required. 14 * 2. Altered source versions must be plainly marked as such, and must not be 15 * misrepresented as being the original software. 16 * 3. This notice may not be removed or altered from any source distribution. 17 */ 18 19 #ifndef B2_BODY_H 20 #define B2_BODY_H 21 22 #include <Box2D/Common/b2Math.h> 23 #include <Box2D/Collision/Shapes/b2Shape.h> 24 #include <new> 25 26 class b2Fixture; 27 class b2Joint; 28 class b2Contact; 29 class b2Controller; 30 class b2World; 31 struct b2FixtureDef; 32 struct b2JointEdge; 33 struct b2ContactEdge; 34 35 /// The body type. 36 /// static: zero mass, zero velocity, may be manually moved 37 /// kinematic: zero mass, non-zero velocity set by user, moved by solver 38 /// dynamic: positive mass, non-zero velocity determined by forces, moved by solver 39 enum b2BodyType 40 { 41 b2_staticBody = 0, 42 b2_kinematicBody, 43 b2_dynamicBody 44 45 // TODO_ERIN 46 //b2_bulletBody, 47 }; 48 49 /// A body definition holds all the data needed to construct a rigid body. 50 /// You can safely re-use body definitions. Shapes are added to a body after construction. 51 struct b2BodyDef 52 { 53 /// This constructor sets the body definition default values. 54 b2BodyDef() 55 { 56 userData = NULL; 57 position.Set(0.0f, 0.0f); 58 angle = 0.0f; 59 linearVelocity.Set(0.0f, 0.0f); 60 angularVelocity = 0.0f; 61 linearDamping = 0.0f; 62 angularDamping = 0.0f; 63 allowSleep = true; 64 awake = true; 65 fixedRotation = false; 66 bullet = false; 67 type = b2_staticBody; 68 active = true; 69 gravityScale = 1.0f; 70 } 71 72 /// The body type: static, kinematic, or dynamic. 73 /// Note: if a dynamic body would have zero mass, the mass is set to one. 74 b2BodyType type; 75 76 /// The world position of the body. Avoid creating bodies at the origin 77 /// since this can lead to many overlapping shapes. 78 b2Vec2 position; 79 80 /// The world angle of the body in radians. 81 float32 angle; 82 83 /// The linear velocity of the body's origin in world co-ordinates. 84 b2Vec2 linearVelocity; 85 86 /// The angular velocity of the body. 87 float32 angularVelocity; 88 89 /// Linear damping is use to reduce the linear velocity. The damping parameter 90 /// can be larger than 1.0f but the damping effect becomes sensitive to the 91 /// time step when the damping parameter is large. 92 float32 linearDamping; 93 94 /// Angular damping is use to reduce the angular velocity. The damping parameter 95 /// can be larger than 1.0f but the damping effect becomes sensitive to the 96 /// time step when the damping parameter is large. 97 float32 angularDamping; 98 99 /// Set this flag to false if this body should never fall asleep. Note that 100 /// this increases CPU usage. 101 bool allowSleep; 102 103 /// Is this body initially awake or sleeping? 104 bool awake; 105 106 /// Should this body be prevented from rotating? Useful for characters. 107 bool fixedRotation; 108 109 /// Is this a fast moving body that should be prevented from tunneling through 110 /// other moving bodies? Note that all bodies are prevented from tunneling through 111 /// kinematic and static bodies. This setting is only considered on dynamic bodies. 112 /// @warning You should use this flag sparingly since it increases processing time. 113 bool bullet; 114 115 /// Does this body start out active? 116 bool active; 117 118 /// Use this to store application specific body data. 119 void* userData; 120 121 /// Scale the gravity applied to this body. 122 float32 gravityScale; 123 }; 124 125 /// A rigid body. These are created via b2World::CreateBody. 126 class b2Body 127 { 128 public: 129 /// Creates a fixture and attach it to this body. Use this function if you need 130 /// to set some fixture parameters, like friction. Otherwise you can create the 131 /// fixture directly from a shape. 132 /// If the density is non-zero, this function automatically updates the mass of the body. 133 /// Contacts are not created until the next time step. 134 /// @param def the fixture definition. 135 /// @warning This function is locked during callbacks. 136 b2Fixture* CreateFixture(const b2FixtureDef* def); 137 138 /// Creates a fixture from a shape and attach it to this body. 139 /// This is a convenience function. Use b2FixtureDef if you need to set parameters 140 /// like friction, restitution, user data, or filtering. 141 /// If the density is non-zero, this function automatically updates the mass of the body. 142 /// @param shape the shape to be cloned. 143 /// @param density the shape density (set to zero for static bodies). 144 /// @warning This function is locked during callbacks. 145 b2Fixture* CreateFixture(const b2Shape* shape, float32 density); 146 147 /// Destroy a fixture. This removes the fixture from the broad-phase and 148 /// destroys all contacts associated with this fixture. This will 149 /// automatically adjust the mass of the body if the body is dynamic and the 150 /// fixture has positive density. 151 /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. 152 /// @param fixture the fixture to be removed. 153 /// @warning This function is locked during callbacks. 154 void DestroyFixture(b2Fixture* fixture); 155 156 /// Set the position of the body's origin and rotation. 157 /// Manipulating a body's transform may cause non-physical behavior. 158 /// Note: contacts are updated on the next call to b2World::Step. 159 /// @param position the world position of the body's local origin. 160 /// @param angle the world rotation in radians. 161 void SetTransform(const b2Vec2& position, float32 angle); 162 163 /// Get the body transform for the body's origin. 164 /// @return the world transform of the body's origin. 165 const b2Transform& GetTransform() const; 166 167 /// Get the world body origin position. 168 /// @return the world position of the body's origin. 169 const b2Vec2& GetPosition() const; 170 171 /// Get the angle in radians. 172 /// @return the current world rotation angle in radians. 173 float32 GetAngle() const; 174 175 /// Get the world position of the center of mass. 176 const b2Vec2& GetWorldCenter() const; 177 178 /// Get the local position of the center of mass. 179 const b2Vec2& GetLocalCenter() const; 180 181 /// Set the linear velocity of the center of mass. 182 /// @param v the new linear velocity of the center of mass. 183 void SetLinearVelocity(const b2Vec2& v); 184 185 /// Get the linear velocity of the center of mass. 186 /// @return the linear velocity of the center of mass. 187 const b2Vec2& GetLinearVelocity() const; 188 189 /// Set the angular velocity. 190 /// @param omega the new angular velocity in radians/second. 191 void SetAngularVelocity(float32 omega); 192 193 /// Get the angular velocity. 194 /// @return the angular velocity in radians/second. 195 float32 GetAngularVelocity() const; 196 197 /// Apply a force at a world point. If the force is not 198 /// applied at the center of mass, it will generate a torque and 199 /// affect the angular velocity. This wakes up the body. 200 /// @param force the world force vector, usually in Newtons (N). 201 /// @param point the world position of the point of application. 202 /// @param wake also wake up the body 203 void ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake); 204 205 /// Apply a force to the center of mass. This wakes up the body. 206 /// @param force the world force vector, usually in Newtons (N). 207 /// @param wake also wake up the body 208 void ApplyForceToCenter(const b2Vec2& force, bool wake); 209 210 /// Apply a torque. This affects the angular velocity 211 /// without affecting the linear velocity of the center of mass. 212 /// This wakes up the body. 213 /// @param torque about the z-axis (out of the screen), usually in N-m. 214 /// @param wake also wake up the body 215 void ApplyTorque(float32 torque, bool wake); 216 217 /// Apply an impulse at a point. This immediately modifies the velocity. 218 /// It also modifies the angular velocity if the point of application 219 /// is not at the center of mass. This wakes up the body. 220 /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. 221 /// @param point the world position of the point of application. 222 /// @param wake also wake up the body 223 void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point, bool wake); 224 225 /// Apply an angular impulse. 226 /// @param impulse the angular impulse in units of kg*m*m/s 227 /// @param wake also wake up the body 228 void ApplyAngularImpulse(float32 impulse, bool wake); 229 230 /// Get the total mass of the body. 231 /// @return the mass, usually in kilograms (kg). 232 float32 GetMass() const; 233 234 /// Get the rotational inertia of the body about the local origin. 235 /// @return the rotational inertia, usually in kg-m^2. 236 float32 GetInertia() const; 237 238 /// Get the mass data of the body. 239 /// @return a struct containing the mass, inertia and center of the body. 240 void GetMassData(b2MassData* data) const; 241 242 /// Set the mass properties to override the mass properties of the fixtures. 243 /// Note that this changes the center of mass position. 244 /// Note that creating or destroying fixtures can also alter the mass. 245 /// This function has no effect if the body isn't dynamic. 246 /// @param massData the mass properties. 247 void SetMassData(const b2MassData* data); 248 249 /// This resets the mass properties to the sum of the mass properties of the fixtures. 250 /// This normally does not need to be called unless you called SetMassData to override 251 /// the mass and you later want to reset the mass. 252 void ResetMassData(); 253 254 /// Get the world coordinates of a point given the local coordinates. 255 /// @param localPoint a point on the body measured relative the the body's origin. 256 /// @return the same point expressed in world coordinates. 257 b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const; 258 259 /// Get the world coordinates of a vector given the local coordinates. 260 /// @param localVector a vector fixed in the body. 261 /// @return the same vector expressed in world coordinates. 262 b2Vec2 GetWorldVector(const b2Vec2& localVector) const; 263 264 /// Gets a local point relative to the body's origin given a world point. 265 /// @param a point in world coordinates. 266 /// @return the corresponding local point relative to the body's origin. 267 b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const; 268 269 /// Gets a local vector given a world vector. 270 /// @param a vector in world coordinates. 271 /// @return the corresponding local vector. 272 b2Vec2 GetLocalVector(const b2Vec2& worldVector) const; 273 274 /// Get the world linear velocity of a world point attached to this body. 275 /// @param a point in world coordinates. 276 /// @return the world velocity of a point. 277 b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const; 278 279 /// Get the world velocity of a local point. 280 /// @param a point in local coordinates. 281 /// @return the world velocity of a point. 282 b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const; 283 284 /// Get the linear damping of the body. 285 float32 GetLinearDamping() const; 286 287 /// Set the linear damping of the body. 288 void SetLinearDamping(float32 linearDamping); 289 290 /// Get the angular damping of the body. 291 float32 GetAngularDamping() const; 292 293 /// Set the angular damping of the body. 294 void SetAngularDamping(float32 angularDamping); 295 296 /// Get the gravity scale of the body. 297 float32 GetGravityScale() const; 298 299 /// Set the gravity scale of the body. 300 void SetGravityScale(float32 scale); 301 302 /// Set the type of this body. This may alter the mass and velocity. 303 void SetType(b2BodyType type); 304 305 /// Get the type of this body. 306 b2BodyType GetType() const; 307 308 /// Should this body be treated like a bullet for continuous collision detection? 309 void SetBullet(bool flag); 310 311 /// Is this body treated like a bullet for continuous collision detection? 312 bool IsBullet() const; 313 314 /// You can disable sleeping on this body. If you disable sleeping, the 315 /// body will be woken. 316 void SetSleepingAllowed(bool flag); 317 318 /// Is this body allowed to sleep 319 bool IsSleepingAllowed() const; 320 321 /// Set the sleep state of the body. A sleeping body has very 322 /// low CPU cost. 323 /// @param flag set to true to wake the body, false to put it to sleep. 324 void SetAwake(bool flag); 325 326 /// Get the sleeping state of this body. 327 /// @return true if the body is awake. 328 bool IsAwake() const; 329 330 /// Set the active state of the body. An inactive body is not 331 /// simulated and cannot be collided with or woken up. 332 /// If you pass a flag of true, all fixtures will be added to the 333 /// broad-phase. 334 /// If you pass a flag of false, all fixtures will be removed from 335 /// the broad-phase and all contacts will be destroyed. 336 /// Fixtures and joints are otherwise unaffected. You may continue 337 /// to create/destroy fixtures and joints on inactive bodies. 338 /// Fixtures on an inactive body are implicitly inactive and will 339 /// not participate in collisions, ray-casts, or queries. 340 /// Joints connected to an inactive body are implicitly inactive. 341 /// An inactive body is still owned by a b2World object and remains 342 /// in the body list. 343 void SetActive(bool flag); 344 345 /// Get the active state of the body. 346 bool IsActive() const; 347 348 /// Set this body to have fixed rotation. This causes the mass 349 /// to be reset. 350 void SetFixedRotation(bool flag); 351 352 /// Does this body have fixed rotation? 353 bool IsFixedRotation() const; 354 355 /// Get the list of all fixtures attached to this body. 356 b2Fixture* GetFixtureList(); 357 const b2Fixture* GetFixtureList() const; 358 359 /// Get the list of all joints attached to this body. 360 b2JointEdge* GetJointList(); 361 const b2JointEdge* GetJointList() const; 362 363 /// Get the list of all contacts attached to this body. 364 /// @warning this list changes during the time step and you may 365 /// miss some collisions if you don't use b2ContactListener. 366 b2ContactEdge* GetContactList(); 367 const b2ContactEdge* GetContactList() const; 368 369 /// Get the next body in the world's body list. 370 b2Body* GetNext(); 371 const b2Body* GetNext() const; 372 373 /// Get the user data pointer that was provided in the body definition. 374 void* GetUserData() const; 375 376 /// Set the user data. Use this to store your application specific data. 377 void SetUserData(void* data); 378 379 /// Get the parent world of this body. 380 b2World* GetWorld(); 381 const b2World* GetWorld() const; 382 383 /// Dump this body to a log file 384 void Dump(); 385 386 private: 387 388 friend class b2World; 389 friend class b2Island; 390 friend class b2ContactManager; 391 friend class b2ContactSolver; 392 friend class b2Contact; 393 394 friend class b2DistanceJoint; 395 friend class b2FrictionJoint; 396 friend class b2GearJoint; 397 friend class b2MotorJoint; 398 friend class b2MouseJoint; 399 friend class b2PrismaticJoint; 400 friend class b2PulleyJoint; 401 friend class b2RevoluteJoint; 402 friend class b2RopeJoint; 403 friend class b2WeldJoint; 404 friend class b2WheelJoint; 405 406 // m_flags 407 enum 408 { 409 e_islandFlag = 0x0001, 410 e_awakeFlag = 0x0002, 411 e_autoSleepFlag = 0x0004, 412 e_bulletFlag = 0x0008, 413 e_fixedRotationFlag = 0x0010, 414 e_activeFlag = 0x0020, 415 e_toiFlag = 0x0040 416 }; 417 418 b2Body(const b2BodyDef* bd, b2World* world); 419 ~b2Body(); 420 421 void SynchronizeFixtures(); 422 void SynchronizeTransform(); 423 424 // This is used to prevent connected bodies from colliding. 425 // It may lie, depending on the collideConnected flag. 426 bool ShouldCollide(const b2Body* other) const; 427 428 void Advance(float32 t); 429 430 b2BodyType m_type; 431 432 uint16 m_flags; 433 434 int32 m_islandIndex; 435 436 b2Transform m_xf; // the body origin transform 437 b2Sweep m_sweep; // the swept motion for CCD 438 439 b2Vec2 m_linearVelocity; 440 float32 m_angularVelocity; 441 442 b2Vec2 m_force; 443 float32 m_torque; 444 445 b2World* m_world; 446 b2Body* m_prev; 447 b2Body* m_next; 448 449 b2Fixture* m_fixtureList; 450 int32 m_fixtureCount; 451 452 b2JointEdge* m_jointList; 453 b2ContactEdge* m_contactList; 454 455 float32 m_mass, m_invMass; 456 457 // Rotational inertia about the center of mass. 458 float32 m_I, m_invI; 459 460 float32 m_linearDamping; 461 float32 m_angularDamping; 462 float32 m_gravityScale; 463 464 float32 m_sleepTime; 465 466 void* m_userData; 467 }; 468 469 inline b2BodyType b2Body::GetType() const 470 { 471 return m_type; 472 } 473 474 inline const b2Transform& b2Body::GetTransform() const 475 { 476 return m_xf; 477 } 478 479 inline const b2Vec2& b2Body::GetPosition() const 480 { 481 return m_xf.p; 482 } 483 484 inline float32 b2Body::GetAngle() const 485 { 486 return m_sweep.a; 487 } 488 489 inline const b2Vec2& b2Body::GetWorldCenter() const 490 { 491 return m_sweep.c; 492 } 493 494 inline const b2Vec2& b2Body::GetLocalCenter() const 495 { 496 return m_sweep.localCenter; 497 } 498 499 inline void b2Body::SetLinearVelocity(const b2Vec2& v) 500 { 501 if (m_type == b2_staticBody) 502 { 503 return; 504 } 505 506 if (b2Dot(v,v) > 0.0f) 507 { 508 SetAwake(true); 509 } 510 511 m_linearVelocity = v; 512 } 513 514 inline const b2Vec2& b2Body::GetLinearVelocity() const 515 { 516 return m_linearVelocity; 517 } 518 519 inline void b2Body::SetAngularVelocity(float32 w) 520 { 521 if (m_type == b2_staticBody) 522 { 523 return; 524 } 525 526 if (w * w > 0.0f) 527 { 528 SetAwake(true); 529 } 530 531 m_angularVelocity = w; 532 } 533 534 inline float32 b2Body::GetAngularVelocity() const 535 { 536 return m_angularVelocity; 537 } 538 539 inline float32 b2Body::GetMass() const 540 { 541 return m_mass; 542 } 543 544 inline float32 b2Body::GetInertia() const 545 { 546 return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); 547 } 548 549 inline void b2Body::GetMassData(b2MassData* data) const 550 { 551 data->mass = m_mass; 552 data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); 553 data->center = m_sweep.localCenter; 554 } 555 556 inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const 557 { 558 return b2Mul(m_xf, localPoint); 559 } 560 561 inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const 562 { 563 return b2Mul(m_xf.q, localVector); 564 } 565 566 inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const 567 { 568 return b2MulT(m_xf, worldPoint); 569 } 570 571 inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const 572 { 573 return b2MulT(m_xf.q, worldVector); 574 } 575 576 inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const 577 { 578 return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c); 579 } 580 581 inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const 582 { 583 return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint)); 584 } 585 586 inline float32 b2Body::GetLinearDamping() const 587 { 588 return m_linearDamping; 589 } 590 591 inline void b2Body::SetLinearDamping(float32 linearDamping) 592 { 593 m_linearDamping = linearDamping; 594 } 595 596 inline float32 b2Body::GetAngularDamping() const 597 { 598 return m_angularDamping; 599 } 600 601 inline void b2Body::SetAngularDamping(float32 angularDamping) 602 { 603 m_angularDamping = angularDamping; 604 } 605 606 inline float32 b2Body::GetGravityScale() const 607 { 608 return m_gravityScale; 609 } 610 611 inline void b2Body::SetGravityScale(float32 scale) 612 { 613 m_gravityScale = scale; 614 } 615 616 inline void b2Body::SetBullet(bool flag) 617 { 618 if (flag) 619 { 620 m_flags |= e_bulletFlag; 621 } 622 else 623 { 624 m_flags &= ~e_bulletFlag; 625 } 626 } 627 628 inline bool b2Body::IsBullet() const 629 { 630 return (m_flags & e_bulletFlag) == e_bulletFlag; 631 } 632 633 inline void b2Body::SetAwake(bool flag) 634 { 635 if (flag) 636 { 637 if ((m_flags & e_awakeFlag) == 0) 638 { 639 m_flags |= e_awakeFlag; 640 m_sleepTime = 0.0f; 641 } 642 } 643 else 644 { 645 m_flags &= ~e_awakeFlag; 646 m_sleepTime = 0.0f; 647 m_linearVelocity.SetZero(); 648 m_angularVelocity = 0.0f; 649 m_force.SetZero(); 650 m_torque = 0.0f; 651 } 652 } 653 654 inline bool b2Body::IsAwake() const 655 { 656 return (m_flags & e_awakeFlag) == e_awakeFlag; 657 } 658 659 inline bool b2Body::IsActive() const 660 { 661 return (m_flags & e_activeFlag) == e_activeFlag; 662 } 663 664 inline bool b2Body::IsFixedRotation() const 665 { 666 return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; 667 } 668 669 inline void b2Body::SetSleepingAllowed(bool flag) 670 { 671 if (flag) 672 { 673 m_flags |= e_autoSleepFlag; 674 } 675 else 676 { 677 m_flags &= ~e_autoSleepFlag; 678 SetAwake(true); 679 } 680 } 681 682 inline bool b2Body::IsSleepingAllowed() const 683 { 684 return (m_flags & e_autoSleepFlag) == e_autoSleepFlag; 685 } 686 687 inline b2Fixture* b2Body::GetFixtureList() 688 { 689 return m_fixtureList; 690 } 691 692 inline const b2Fixture* b2Body::GetFixtureList() const 693 { 694 return m_fixtureList; 695 } 696 697 inline b2JointEdge* b2Body::GetJointList() 698 { 699 return m_jointList; 700 } 701 702 inline const b2JointEdge* b2Body::GetJointList() const 703 { 704 return m_jointList; 705 } 706 707 inline b2ContactEdge* b2Body::GetContactList() 708 { 709 return m_contactList; 710 } 711 712 inline const b2ContactEdge* b2Body::GetContactList() const 713 { 714 return m_contactList; 715 } 716 717 inline b2Body* b2Body::GetNext() 718 { 719 return m_next; 720 } 721 722 inline const b2Body* b2Body::GetNext() const 723 { 724 return m_next; 725 } 726 727 inline void b2Body::SetUserData(void* data) 728 { 729 m_userData = data; 730 } 731 732 inline void* b2Body::GetUserData() const 733 { 734 return m_userData; 735 } 736 737 inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point, bool wake) 738 { 739 if (m_type != b2_dynamicBody) 740 { 741 return; 742 } 743 744 if (wake && (m_flags & e_awakeFlag) == 0) 745 { 746 SetAwake(true); 747 } 748 749 // Don't accumulate a force if the body is sleeping. 750 if (m_flags & e_awakeFlag) 751 { 752 m_force += force; 753 m_torque += b2Cross(point - m_sweep.c, force); 754 } 755 } 756 757 inline void b2Body::ApplyForceToCenter(const b2Vec2& force, bool wake) 758 { 759 if (m_type != b2_dynamicBody) 760 { 761 return; 762 } 763 764 if (wake && (m_flags & e_awakeFlag) == 0) 765 { 766 SetAwake(true); 767 } 768 769 // Don't accumulate a force if the body is sleeping 770 if (m_flags & e_awakeFlag) 771 { 772 m_force += force; 773 } 774 } 775 776 inline void b2Body::ApplyTorque(float32 torque, bool wake) 777 { 778 if (m_type != b2_dynamicBody) 779 { 780 return; 781 } 782 783 if (wake && (m_flags & e_awakeFlag) == 0) 784 { 785 SetAwake(true); 786 } 787 788 // Don't accumulate a force if the body is sleeping 789 if (m_flags & e_awakeFlag) 790 { 791 m_torque += torque; 792 } 793 } 794 795 inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point, bool wake) 796 { 797 if (m_type != b2_dynamicBody) 798 { 799 return; 800 } 801 802 if (wake && (m_flags & e_awakeFlag) == 0) 803 { 804 SetAwake(true); 805 } 806 807 // Don't accumulate velocity if the body is sleeping 808 if (m_flags & e_awakeFlag) 809 { 810 m_linearVelocity += m_invMass * impulse; 811 m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse); 812 } 813 } 814 815 inline void b2Body::ApplyAngularImpulse(float32 impulse, bool wake) 816 { 817 if (m_type != b2_dynamicBody) 818 { 819 return; 820 } 821 822 if (wake && (m_flags & e_awakeFlag) == 0) 823 { 824 SetAwake(true); 825 } 826 827 // Don't accumulate velocity if the body is sleeping 828 if (m_flags & e_awakeFlag) 829 { 830 m_angularVelocity += m_invI * impulse; 831 } 832 } 833 834 inline void b2Body::SynchronizeTransform() 835 { 836 m_xf.q.Set(m_sweep.a); 837 m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); 838 } 839 840 inline void b2Body::Advance(float32 alpha) 841 { 842 // Advance to the new safe time. This doesn't sync the broad-phase. 843 m_sweep.Advance(alpha); 844 m_sweep.c = m_sweep.c0; 845 m_sweep.a = m_sweep.a0; 846 m_xf.q.Set(m_sweep.a); 847 m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); 848 } 849 850 inline b2World* b2Body::GetWorld() 851 { 852 return m_world; 853 } 854 855 inline const b2World* b2Body::GetWorld() const 856 { 857 return m_world; 858 } 859 860 #endif 861