本文来自http://blog.csdn.net/runaying ,引用必须注明出处!
温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 Cocos2d-X权威指南笔记
//模拟现实世界中的静态物体,动态物体,匀速直线运动的物体,并返回它们的各种状态
///cocos2d-x-3.0alpha0/external/Box2D/Dynamics //模拟现实世界中的静态物体,动态物体,匀速直线运动的物体,并返回它们的各种状态 #ifndef B2_BODY_H #define B2_BODY_H #include <Box2D/Common/b2Math.h> #include <Box2D/Collision/Shapes/b2Shape.h> #include <memory> class b2Fixture; class b2Joint; class b2Contact; class b2Controller; class b2World; struct b2FixtureDef; struct b2JointEdge; struct b2ContactEdge; /// body 类型. /// static: zero mass, zero velocity(速度), 可以手动移动 //速度一定,位置可以手动设置 /// kinematic(运动学): zero mass, 由用户设置 non-zero velocity(速度), moved by solver(运算器) //用户可以设置速度位置由系统计算 /// dynamic(动态): positive(真实的) mass,由力决定 non-zero velocity(速度), moved by solver(运算器) //类似与现实世界中的物体,mass 是时时的,因为物体的速度,状态会影响 mass ,速度由力来决定 // enum b2BodyType { b2_staticBody = 0, b2_kinematicBody, b2_dynamicBody // TODO_ERIN //b2_bulletBody, }; /// 定义 body 所需要的所有数据构建一个正确的 body //您可以安全地 re-use 定义的 body //构建后把 shapes 添加到 body struct b2BodyDef { ///此构造函数设置定义的 body (使用默认值). b2BodyDef() { userData = NULL; position.Set(0.0f, 0.0f); angle = 0.0f; linearVelocity.Set(0.0f, 0.0f); angularVelocity = 0.0f; linearDamping = 0.0f; angularDamping = 0.0f; allowSleep = true; awake = true; fixedRotation = false; bullet = false; type = b2_staticBody; active = true; gravityScale = 1.0f; } /// The body type: static, kinematic(动力学), or dynamic(动态). /// Note: 如果动态的 body 质量是 0, 质量将被设置成 1. b2BodyType type; /// body 在世界坐标中的位置. 避免在 origin(原点) 处创建 body /// 因为这可能会导致许多重叠的 shapes b2Vec2 position; /// body 在 world 中的角度 ,以弧度为单位 float32 angle; /// body's origin(原点)在世界坐标系中的线速度 b2Vec2 linearVelocity; /// body 的角速度. float32 angularVelocity; // 使用线性阻尼,以降低线速度。阻尼参数 // 可以大于1.0F ,但阻尼作用会变得非常敏感 // 阻尼参数越大同步时间越长 float32 linearDamping; /// 使用阻尼角,以减少角速度。阻尼参数 // 可以大于1.0F ,但阻尼作用会变得非常敏感 // 阻尼参数越大同步时间越长 float32 angularDamping; /// 把这个标志设置为 false 如果这个 body 不应该进入睡眠. 需要注意的是 //这会增加CPU的使用率。 bool allowSleep; /// 这个 body 初始化时是 awake / sleeping? bool awake; ///如果这个 body 不应该旋转,这个字符串就非常有用了 bool fixedRotation; ///这是一个快速移动的 body,应该防止它快速穿过其它 body // 请注意所有的 body 都无法从 kinematic/static body 之内穿过 /// @warning 你应该尽量减少使用这个 flag,因为它会增加处理时间 bool bullet; /// body 是否开始激活? bool active; /// 使用这个存储应用程序特定的 body 数据 void* userData; ///应用到这个 body 的中立比例. float32 gravityScale; }; /// A rigid(精密) body. 这些是通过 b2World::CreateBody 创建的. class b2Body { public: /// 创建一个 fixture(定制器) 把它附加到这个 body. 使用此功能,如果你需要的 ///设置一些固定参数,如摩擦。其它情况,你可以使用shape 创建 fixture(定制器) // 如果密度不为零时,此功能会自动更新物体的质量。 /// 联系一直存在,不会创建直到下一个步骤 /// @param def 定义的 fixture(定制器) /// @warning 这个功能锁定在 回调函数里面 b2Fixture* CreateFixture(const b2FixtureDef* def); /// 创建一个固定形状,将它附加到这个身体 /// 这是一个方便的功能. 如果你需要使用 b2FixtureDef 设置参数 /// 如 friction(摩擦), restitution(恢复), user data, or filtering(过滤). /// 如果密度不为零时,此功能会自动更新物体的质量 /// @param shape 要克隆的形状. /// @param density shape 的密度 (静态物体设置为零). /// @warning 这个功能锁定在 回调函数里面 b2Fixture* CreateFixture(const b2Shape* shape, float32 density); /// 销毁一个 fixture. 从 broad-phase 里面移除这个 fixture,破坏与这个 fixture 关联的所有联系这将 // /如果身体是动态的,这个 fixture 具有一定的密度,它会自动调整物体的质量, /// 当 body 被销毁时,关联到 body 的所有 fixtures 都会直接被删除 /// @param fixture the fixture to be removed. /// @warning 这个功能锁定在 回调函数里面. void DestroyFixture(b2Fixture* fixture); /// 为这个 body 设置位置和旋转角 /// 这打破了任何联系,唤醒其它 body /// 操作一个 body 转换,可能会 导致其它 non-physical 行为. /// @param position body 在世界坐标系的位置 /// @param angle 世界坐标系的角度以弧度为单位 void SetTransform(const b2Vec2& position, float32 angle); /// 获取这个 body 的转换. /// @return 这个 body 在世界坐标系中的转换. const b2Transform& GetTransform() const; /// 获取 body 在世界坐标系中的位置. /// @return body 在世界坐标系中的位置.. const b2Vec2& GetPosition() const; /// 获取角度以弧度为单位. /// @return 当前世界坐标系的角度以弧度为单位 float32 GetAngle() const; /// 获取的质量中心 在世界坐标系中的位置. const b2Vec2& GetWorldCenter() const; /// 获取本地的质量中心的位置。. const b2Vec2& GetLocalCenter() const; /// 设定的质心的线速度. /// @param v 新的质心的线速度。. void SetLinearVelocity(const b2Vec2& v); /// Get 质心的线速度.. /// @return 质心的线速度. b2Vec2 GetLinearVelocity() const; /// Set 角速度. /// @param omega 新的角速度 radians/second. void SetAngularVelocity(float32 omega); /// Get 角速度. /// @return 新的角速度 radians/second. float32 GetAngularVelocity() const; /// 这世界坐标点应用力,如果力不作用在质量中心,他会发生旋转,影响角速度,唤醒这个 body /// @param force world 力矢量,通常以牛顿(N)为单位 /// @param point 应用里面的某个点的 world 位置 void ApplyForce(const b2Vec2& force, const b2Vec2& point); /// 在质量中心施加一个力,这将唤醒这个 body /// @param force world 力矢量,通常以牛顿(N)为单位 void ApplyForceToCenter(const b2Vec2& force); /// 应用力矩,这会影响到角速度 /// 不影响质量的中心的线速度,唤醒 body /// @param torque 围绕z轴(移出屏幕), 通常 N-m(N/米). void ApplyTorque(float32 torque); /// 应用一个冲量到一个点上,这将立即改变速度。(这句话的意思是突然在一个点上作用一个力) /// 如果这个点不再应用程序的质心上,它还会修改角速度. 唤醒 body. /// @param impulse world 的矢量冲量, 通常 N-seconds or kg-m/s. /// @param point 应用里面的某个点的 world 位置 void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point); /// 应用一个有角度的冲量 /// @param impulse 角度冲量的单位是 kg*m*m/s void ApplyAngularImpulse(float32 impulse); /// 获取 body 的总质量 /// @return the mass, 通常是以 kilograms (kg) 为单位. float32 GetMass() const; /// 获取 body 的转动惯量,(本地点) /// @return 旋转惯性, 通常是以 kg-m^2.为单位 float32 GetInertia() const; /// 获取这个身体的质量数据 /// @return 一个包含 质量,惯性和body的中心 void GetMassData(b2MassData* data) const; ///设置质量属性,覆盖 fixtures 的质量属性 /// Note 这改变了质心的位置. /// Note t创建或销毁 fixtures 可以改变质量. /// 如果 body 不是动态的这个函数没有效果. /// @param massData mass 属性. void SetMassData(const b2MassData* data); // 计算 fixtures 的质量,这将重置质量属性 /// 通常不需要调用这个,除非你调用了 SetMassData 覆盖了质量随后你需要复位质量. void ResetMassData(); /// 获取给定坐标点,在世界坐标系中的位置 /// @param localPoint 相对于 body's 原点的测量点. /// @return 相同的点用 world 坐标系表示. b2Vec2 GetWorldPoint(const b2Vec2& localPoint) const; ///用世界坐标系表示给定的本地坐标 /// @param localVector 固定在 body 上的矢量. /// @return 相同的向量用 world 坐标系表示 b2Vec2 GetWorldVector(const b2Vec2& localVector) const; /// 使用给定世界坐标系的点获取一个相对于 body 原点的本地点 /// @param 一个 world 坐标系中的点. /// @return 相对于 body 原点的本地坐标点 b2Vec2 GetLocalPoint(const b2Vec2& worldPoint) const; /// 把指定的世界坐标系中的向量转换为一个本地向量 /// @param world 坐标系中的向量. /// @return 对应的本地向量 b2Vec2 GetLocalVector(const b2Vec2& worldVector) const; ///获取关联到这个 body 的 world point 在 world 中的线性速度 /// @param 一个 world 坐标系中的点 /// @return 一个点的 world 速度 b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const; /// 获取 local 点的 world 速度 /// @param 一个本地坐标系中的点 /// @return 一个点的 world 速度 b2Vec2 GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const; ///获取这个 body 的线性阻尼 float32 GetLinearDamping() const; /// Set 这个 body 的线性阻尼 void SetLinearDamping(float32 linearDamping); /// Get body 的阻尼角度 float32 GetAngularDamping() const; /// Set body 的阻尼角度 void SetAngularDamping(float32 angularDamping); /// Get 这个 body 的重力比例 float32 GetGravityScale() const; /// Set 这个 body 的重力比例 void SetGravityScale(float32 scale); /// Set body 的类型。这可能会改变的质量和速度。 void SetType(b2BodyType type); /// Get 这个 body 的类型 b2BodyType GetType() const; // 这个 body 是否应该像子弹那样有连续碰撞检测 void SetBullet(bool flag); // 这个 body 是否像子弹那样有连续碰撞检测 bool IsBullet() const; /// 你可以禁止这个 body 睡眠,如果你禁止睡眠,这个 body 将一直醒着 void SetSleepingAllowed(bool flag); ///是否允许这个 body 睡眠 bool IsSleepingAllowed() const; /// 设置这个 body 的睡眠状态,一个睡眠的 body 有一个较低的 CPU 占用 /// @param flag set to true to put body to sleep, false to wake it. void SetAwake(bool flag); /// 获取这个 body 的睡眠状态 /// @return true if the body is sleeping. bool IsAwake() const; /// 设置 body 的 active 状态,一个无效的body 不可以被 模拟、碰撞、唤醒 /// 如果这个 flag 的值是 true,所有的 fixtures 都会添加到 broad-phase. /// 如果这个 flag 的值是 false,所有的 fixtures 都会从到 broad-phase 里面移除,所有的联系都会被销毁 /// Fixtures 必须被添加了,其它情况不受影响。你可以继续 添加/消除 fixtures 到一个不活跃的 body /// fixtures 在一个不活跃的 body 上,他就不会参与 碰撞,射线投射,或查询。 /// 添加 fixtures 到一个不活跃的 body 上,它也会不活跃 /// 不活跃的 body 仍然保持它的 b2Word 对象 void SetActive(bool flag); /// 获取 body 的 active 状态 bool IsActive() const; /// 设置 body 有固定的旋转。这会导致质量被重置。 void SetFixedRotation(bool flag); /// body 是否有固定的旋转 bool IsFixedRotation() const; /// 获取联系到这个 body 的所有 fixtures 列表 b2Fixture* GetFixtureList(); const b2Fixture* GetFixtureList() const; /// Get the list of all joints attached to this body. b2JointEdge* GetJointList(); const b2JointEdge* GetJointList() const; ///获取添加到这个 body 的所有联系 /// @warning this list changes during the time step and you may /// miss some collisions if you don't use b2ContactListener. b2ContactEdge* GetContactList(); const b2ContactEdge* GetContactList() const; /// 获取 world's body 列表里面的下一个 body. b2Body* GetNext(); const b2Body* GetNext() const; /// 获取 body 里面提供的用户指针数据 void* GetUserData() const; /// Set body 里面提供的用户指针数据 void SetUserData(void* data); /// Get the parent world of this body. b2World* GetWorld(); const b2World* GetWorld() const; // 把 body 的阻尼输出到一个日志文件 void Dump(); private: friend class b2World; friend class b2Island; friend class b2ContactManager; friend class b2ContactSolver; friend class b2Contact; friend class b2DistanceJoint; friend class b2GearJoint; friend class b2WheelJoint; friend class b2MouseJoint; friend class b2PrismaticJoint; friend class b2PulleyJoint; friend class b2RevoluteJoint; friend class b2WeldJoint; friend class b2FrictionJoint; friend class b2RopeJoint; // m_flags enum { e_islandFlag = 0x0001, e_awakeFlag = 0x0002, e_autoSleepFlag = 0x0004, e_bulletFlag = 0x0008, e_fixedRotationFlag = 0x0010, e_activeFlag = 0x0020, e_toiFlag = 0x0040 }; b2Body(const b2BodyDef* bd, b2World* world); ~b2Body(); void SynchronizeFixtures(); void SynchronizeTransform(); // 这个用来防止连接机构碰撞 // 它可能 lie(不一样),这取决于collideConnected标志 bool ShouldCollide(const b2Body* other) const; void Advance(float32 t); b2BodyType m_type; uint16 m_flags; int32 m_islandIndex; b2Transform m_xf; // body 的转换原点 b2Sweep m_sweep; // the swept motion for CCD //CCD 的打扫运动 b2Vec2 m_linearVelocity; float32 m_angularVelocity; b2Vec2 m_force; float32 m_torque; b2World* m_world; b2Body* m_prev; b2Body* m_next; b2Fixture* m_fixtureList; int32 m_fixtureCount; b2JointEdge* m_jointList; b2ContactEdge* m_contactList; float32 m_mass, m_invMass; // 质心的转动惯量 float32 m_I, m_invI; float32 m_linearDamping; float32 m_angularDamping; float32 m_gravityScale; float32 m_sleepTime; void* m_userData; }; inline b2BodyType b2Body::GetType() const { return m_type; } inline const b2Transform& b2Body::GetTransform() const { return m_xf; } inline const b2Vec2& b2Body::GetPosition() const { return m_xf.p; } inline float32 b2Body::GetAngle() const { return m_sweep.a; } inline const b2Vec2& b2Body::GetWorldCenter() const { return m_sweep.c; } inline const b2Vec2& b2Body::GetLocalCenter() const { return m_sweep.localCenter; } inline void b2Body::SetLinearVelocity(const b2Vec2& v) { if (m_type == b2_staticBody) { return; } if (b2Dot(v,v) > 0.0f) { SetAwake(true); } m_linearVelocity = v; } inline b2Vec2 b2Body::GetLinearVelocity() const { return m_linearVelocity; } inline void b2Body::SetAngularVelocity(float32 w) { if (m_type == b2_staticBody) { return; } if (w * w > 0.0f) { SetAwake(true); } m_angularVelocity = w; } inline float32 b2Body::GetAngularVelocity() const { return m_angularVelocity; } inline float32 b2Body::GetMass() const { return m_mass; } inline float32 b2Body::GetInertia() const { return m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); } inline void b2Body::GetMassData(b2MassData* data) const { data->mass = m_mass; data->I = m_I + m_mass * b2Dot(m_sweep.localCenter, m_sweep.localCenter); data->center = m_sweep.localCenter; } inline b2Vec2 b2Body::GetWorldPoint(const b2Vec2& localPoint) const { return b2Mul(m_xf, localPoint); } inline b2Vec2 b2Body::GetWorldVector(const b2Vec2& localVector) const { return b2Mul(m_xf.q, localVector); } inline b2Vec2 b2Body::GetLocalPoint(const b2Vec2& worldPoint) const { return b2MulT(m_xf, worldPoint); } inline b2Vec2 b2Body::GetLocalVector(const b2Vec2& worldVector) const { return b2MulT(m_xf.q, worldVector); } inline b2Vec2 b2Body::GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const { return m_linearVelocity + b2Cross(m_angularVelocity, worldPoint - m_sweep.c); } inline b2Vec2 b2Body::GetLinearVelocityFromLocalPoint(const b2Vec2& localPoint) const { return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint)); } inline float32 b2Body::GetLinearDamping() const { return m_linearDamping; } inline void b2Body::SetLinearDamping(float32 linearDamping) { m_linearDamping = linearDamping; } inline float32 b2Body::GetAngularDamping() const { return m_angularDamping; } inline void b2Body::SetAngularDamping(float32 angularDamping) { m_angularDamping = angularDamping; } inline float32 b2Body::GetGravityScale() const { return m_gravityScale; } inline void b2Body::SetGravityScale(float32 scale) { m_gravityScale = scale; } inline void b2Body::SetBullet(bool flag) { if (flag) { m_flags |= e_bulletFlag; } else { m_flags &= ~e_bulletFlag; } } inline bool b2Body::IsBullet() const { return (m_flags & e_bulletFlag) == e_bulletFlag; } inline void b2Body::SetAwake(bool flag) { if (flag) { if ((m_flags & e_awakeFlag) == 0) { m_flags |= e_awakeFlag; m_sleepTime = 0.0f; } } else { m_flags &= ~e_awakeFlag; m_sleepTime = 0.0f; m_linearVelocity.SetZero(); m_angularVelocity = 0.0f; m_force.SetZero(); m_torque = 0.0f; } } inline bool b2Body::IsAwake() const { return (m_flags & e_awakeFlag) == e_awakeFlag; } inline bool b2Body::IsActive() const { return (m_flags & e_activeFlag) == e_activeFlag; } inline void b2Body::SetFixedRotation(bool flag) { if (flag) { m_flags |= e_fixedRotationFlag; } else { m_flags &= ~e_fixedRotationFlag; } ResetMassData(); } inline bool b2Body::IsFixedRotation() const { return (m_flags & e_fixedRotationFlag) == e_fixedRotationFlag; } inline void b2Body::SetSleepingAllowed(bool flag) { if (flag) { m_flags |= e_autoSleepFlag; } else { m_flags &= ~e_autoSleepFlag; SetAwake(true); } } inline bool b2Body::IsSleepingAllowed() const { return (m_flags & e_autoSleepFlag) == e_autoSleepFlag; } inline b2Fixture* b2Body::GetFixtureList() { return m_fixtureList; } inline const b2Fixture* b2Body::GetFixtureList() const { return m_fixtureList; } inline b2JointEdge* b2Body::GetJointList() { return m_jointList; } inline const b2JointEdge* b2Body::GetJointList() const { return m_jointList; } inline b2ContactEdge* b2Body::GetContactList() { return m_contactList; } inline const b2ContactEdge* b2Body::GetContactList() const { return m_contactList; } inline b2Body* b2Body::GetNext() { return m_next; } inline const b2Body* b2Body::GetNext() const { return m_next; } inline void b2Body::SetUserData(void* data) { m_userData = data; } inline void* b2Body::GetUserData() const { return m_userData; } inline void b2Body::ApplyForce(const b2Vec2& force, const b2Vec2& point) { if (m_type != b2_dynamicBody) { return; } if (IsAwake() == false) { SetAwake(true); } m_force += force; m_torque += b2Cross(point - m_sweep.c, force); } inline void b2Body::ApplyForceToCenter(const b2Vec2& force) { if (m_type != b2_dynamicBody) { return; } if (IsAwake() == false) { SetAwake(true); } m_force += force; } inline void b2Body::ApplyTorque(float32 torque) { if (m_type != b2_dynamicBody) { return; } if (IsAwake() == false) { SetAwake(true); } m_torque += torque; } inline void b2Body::ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point) { if (m_type != b2_dynamicBody) { return; } if (IsAwake() == false) { SetAwake(true); } m_linearVelocity += m_invMass * impulse; m_angularVelocity += m_invI * b2Cross(point - m_sweep.c, impulse); } inline void b2Body::ApplyAngularImpulse(float32 impulse) { if (m_type != b2_dynamicBody) { return; } if (IsAwake() == false) { SetAwake(true); } m_angularVelocity += m_invI * impulse; } inline void b2Body::SynchronizeTransform() { m_xf.q.Set(m_sweep.a); m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); } inline void b2Body::Advance(float32 alpha) { // 提前新的安全时间. 这个不同步 broad-phase. m_sweep.Advance(alpha); m_sweep.c = m_sweep.c0; m_sweep.a = m_sweep.a0; m_xf.q.Set(m_sweep.a); m_xf.p = m_sweep.c - b2Mul(m_xf.q, m_sweep.localCenter); } inline b2World* b2Body::GetWorld() { return m_world; } inline const b2World* b2Body::GetWorld() const { return m_world; } #endif