本文来自http://blog.csdn.net/runaying ,引用必须注明出处!
温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 Cocos2d-X权威指南笔记
//这个类管理两个形状之间的接触。
/// broad-phase (除了filtered(过滤))里面每个AABB存在的接触重叠.
/// 因此,接触的对象可能存在,有没有接触点的情况。
////cocos2d-x-3.0alpha0/external/Box2D/Dynamics/Contacts //这个类管理两个形状之间的接触。 /// broad-phase (除了filtered(过滤)) 里面每个AABB 存在的接触重叠. /// 因此,接触的对象可能存在,有没有接触点的情况。 #ifndef B2_CONTACT_H #define B2_CONTACT_H #include <Box2D/Common/b2Math.h> #include <Box2D/Collision/b2Collision.h> #include <Box2D/Collision/Shapes/b2Shape.h> #include <Box2D/Dynamics/b2Fixture.h> class b2Body; class b2Contact; class b2Fixture; class b2World; class b2BlockAllocator; class b2StackAllocator; class b2ContactListener; /// 混合摩擦力依据. 这个方法允许其它的 fixture(定制器)重置为 0 /// 例如, 任何物体再 ice 上面滑行. inline float32 b2MixFriction(float32 friction1, float32 friction2) { return std::sqrt(friction1 * friction2); } /// 混合重置依据. 这个方法允许你弹开任何无弹性的 surface(面). /// 例如, superball(超级 球)从任何物体上弹开 inline float32 b2MixRestitution(float32 restitution1, float32 restitution2) { return restitution1 > restitution2 ? restitution1 : restitution2; } typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator); struct b2ContactRegister { b2ContactCreateFcn* createFcn; b2ContactDestroyFcn* destroyFcn; bool primary; }; /// 连接body 的接触范围,接触图里面包含每个 body 的接触范围 //接触范围,属于一个连接到 body 的双向链表 ///每一个接触都有两个接触点,一个连接到它们的 body struct b2ContactEdge { b2Body* other; ///< 提供其它 body 快速联系 b2Contact* contact; ///< the contact b2ContactEdge* prev; ///< 在 body 接触列表里面上一个接触的范围 b2ContactEdge* next; ///< 在 body 接触列表里面下一个接触的范围 }; ///这个类管理两个形状之间的接触。 /// broad-phase (除了filtered(过滤)) 里面每个AABB 存在的接触重叠. /// 因此,接触的对象可能存在,有没有接触点的情况。 class b2Contact { public: /// Get the contact(接触)manifold(多方面). 不要修改 manifold(分歧)除非你理解 Box2D 的 内部结构 b2Manifold* GetManifold(); const b2Manifold* GetManifold() const; /// Get the world manifold(多方面). void GetWorldManifold(b2WorldManifold* worldManifold) const; /// 是否正在触摸这个接触 bool IsTouching() const; /// Enable/disable 这个接触. This can be used inside the pre-solve /// contact listener. The contact is only disabled for the current /// time step (or sub-step in continuous collisions). void SetEnabled(bool flag); /// 这个接触是否一直保持禁止 bool IsEnabled() const; /// 获取 world's 接触 列表里面的下一个 接触 b2Contact* GetNext(); const b2Contact* GetNext() const; /// 获取这个接触的 fixture(定制器)A b2Fixture* GetFixtureA(); const b2Fixture* GetFixtureA() const; /// 为 fixture(定制器)A 原始的 child index int32 GetChildIndexA() const; /// 获取这个接触的 fixture(定制器)B b2Fixture* GetFixtureB(); const b2Fixture* GetFixtureB() const; // 为 fixture(定制器)B 原始的 child index int32 GetChildIndexB() const; /// 覆盖默认的摩擦参数. 你可以在 b2ContactListener::PreSolve 里面调用它. ///值一直存在,知道你 set/reset void SetFriction(float32 friction); /// Get 摩擦参数. float32 GetFriction() const; /// 使用默认值重置摩擦参数 void ResetFriction(); /// 覆盖默认的 重置参数. 你可以在 b2ContactListener::PreSolve 里面调用它. ///值一直存在,知道你 set/reset void SetRestitution(float32 restitution); /// Get the restitution(重置). float32 GetRestitution() const; /// 使用默认值重置 void ResetRestitution(); // 你可以使用你自己的 manifold(分歧)、transforms 计算这个 接触 virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0; protected: friend class b2ContactManager; friend class b2World; friend class b2ContactSolver; friend class b2Body; friend class b2Fixture; // Flags 存储在 m_flags enum { // 当 islands 形成 crawling 接触图表时使用 e_islandFlag = 0x0001, // shapes 正在触摸时设置. e_touchingFlag = 0x0002, // 这个接触可以由用户禁用 e_enabledFlag = 0x0004, // 这个接触需要过滤,因为 fixture(定制器)过滤已经改变 e_filterFlag = 0x0008, // 这个子弹接触有一个 TOI 事件 e_bulletHitFlag = 0x0010, // 这个接触在 m_toi 里面有一个 TOI e_toiFlag = 0x0020 }; /// 用用于过滤的 contact 的 flag. 过滤在下一个时间步长里生效 void FlagForFiltering(); static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn, b2Shape::Type typeA, b2Shape::Type typeB); static void InitializeRegisters(); static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator); static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {} b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); virtual ~b2Contact() {} void Update(b2ContactListener* listener); static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; static bool s_initialized; uint32 m_flags; // World 的指针列表池. b2Contact* m_prev; b2Contact* m_next; // 连接 bodies 的节点. b2ContactEdge m_nodeA; b2ContactEdge m_nodeB; b2Fixture* m_fixtureA; b2Fixture* m_fixtureB; int32 m_indexA; int32 m_indexB; b2Manifold m_manifold; int32 m_toiCount; float32 m_toi; float32 m_friction; float32 m_restitution; }; inline b2Manifold* b2Contact::GetManifold() { return &m_manifold; } inline const b2Manifold* b2Contact::GetManifold() const { return &m_manifold; } inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const { const b2Body* bodyA = m_fixtureA->GetBody(); const b2Body* bodyB = m_fixtureB->GetBody(); const b2Shape* shapeA = m_fixtureA->GetShape(); const b2Shape* shapeB = m_fixtureB->GetShape(); worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius); } inline void b2Contact::SetEnabled(bool flag) { if (flag) { m_flags |= e_enabledFlag; } else { m_flags &= ~e_enabledFlag; } } inline bool b2Contact::IsEnabled() const { return (m_flags & e_enabledFlag) == e_enabledFlag; } inline bool b2Contact::IsTouching() const { return (m_flags & e_touchingFlag) == e_touchingFlag; } inline b2Contact* b2Contact::GetNext() { return m_next; } inline const b2Contact* b2Contact::GetNext() const { return m_next; } inline b2Fixture* b2Contact::GetFixtureA() { return m_fixtureA; } inline const b2Fixture* b2Contact::GetFixtureA() const { return m_fixtureA; } inline b2Fixture* b2Contact::GetFixtureB() { return m_fixtureB; } inline int32 b2Contact::GetChildIndexA() const { return m_indexA; } inline const b2Fixture* b2Contact::GetFixtureB() const { return m_fixtureB; } inline int32 b2Contact::GetChildIndexB() const { return m_indexB; } inline void b2Contact::FlagForFiltering() { m_flags |= e_filterFlag; } inline void b2Contact::SetFriction(float32 friction) { m_friction = friction; } inline float32 b2Contact::GetFriction() const { return m_friction; } inline void b2Contact::ResetFriction() { m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction); } inline void b2Contact::SetRestitution(float32 restitution) { m_restitution = restitution; } inline float32 b2Contact::GetRestitution() const { return m_restitution; } inline void b2Contact::ResetRestitution() { m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution); } #endif