本文来自http://blog.csdn.net/runaying ,引用必须注明出处!
温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 Cocos2d-X权威指南笔记
用于计算接触点,距离查询和TOI查询的结构和功能
///cocos2d-x-3.0alpha0/external/Box2D/Collision //用于计算接触点,距离查询和TOI查询的结构和功能 #ifndef B2_COLLISION_H #define B2_COLLISION_H #include <Box2D/Common/b2Math.h> #include <climits> /// @file ///用于计算接触点,距离查询和TOI查询的结构和功能 //声明类 class b2Shape; class b2CircleShape; class b2EdgeShape; class b2PolygonShape; //定义特征的无效值 const uint8 b2_nullFeature = UCHAR_MAX; //特征,交叉形成的接触点 // 必须是4字节或者更少 struct b2ContactFeature { enum Type { e_vertex = 0, e_face = 1 }; uint8 indexA; // shapeA的特征索引 uint8 indexB; // shapeB的特征索引 uint8 typeA; // shapeA的特征类型 uint8 typeB; // shapeB的特征类型 }; /// 接触ID,以方便热启动 union b2ContactID { b2ContactFeature cf; //特征对象变量 uint32 key; ///< 特征id,用于快速比较 }; //流形点属于接触流形的一个接触点。它具有的细节涉及到接触点的几何学和力学 // 局部点的求解依赖于流形的类型: // e_circles:circleB的局部中心 // e_faceA :circleB的局部中心 或者polygonB的夹点 // e_faceB :polygonA的夹点 // 这个结构存储在时间步内,所以我们保持它小一些。 // 注意:这个冲量用来作为内部缓冲,很可能无法提供可靠的接触的力,尤其在高速碰撞的时候 struct b2ManifoldPoint { b2Vec2 localPoint; //局部点,求解依赖于流形类型 float32 normalImpulse; ///< 法向冲量,用于防止形状的穿透 float32 tangentImpulse; //切向冲量,用于模拟摩擦 b2ContactID id; //唯一地标识一个在两个形状之间的接触点 }; // 流形(注:也有人译为‘取样’,在物理和数学中均使用‘流形’,参照http://zh.wikipedia.org/wiki/流形 ) // 流形是两个凸形状的接触部分。 // Box2D支持多种类型的接触: // 夹点与平面半径 // 点与点半径(圆) // 局部的点求解取决于流形的类型: // e_circles:circleA的中心 // e_faceA : faceA的中心 // e_faceB :faceB的重心 // 同样局部法向量的求解: // e_circles:不用 // e_faceA : faceA的法向量 // e_faceB :faceB的法向量 // 我们用这种方式存储联系,以便移动时位置被更正。 //所有接触场景必须表述为这些类型中的一个。 //这个结构存储在时间步内,所以我们保持它小一些。 struct b2Manifold { //流形的类型 enum Type { e_circles, //圆 e_faceA, //面A e_faceB //面B }; b2ManifoldPoint points[b2_maxManifoldPoints]; // // 接触点数组 b2Vec2 localNormal; ///< 局部法向量,对Type::e_points没用 b2Vec2 localPoint; // 求解依赖流形类型 Type type; //类型 int32 pointCount; // 流形的点的总数 }; //// 这是用于求解当前状态下的接触流形 struct b2WorldManifold { // 根据流形和提供的变换初始化此结构体。假设适度移动从原始状态开始的。 // 这不能改变点的数量、冲量等等。半径必须来着与产生流形的形状。 // * 参数说明: manifold:流形的指针,用于初始化结构体 // xfA :变换A的引用 // radiusA :形状A的半径 // xfB :变化B的引用 // radiusB :形状B的半径 void Initialize(const b2Manifold* manifold, const b2Transform& xfA, float32 radiusA, const b2Transform& xfB, float32 radiusB); b2Vec2 normal; //世界向量方向从A到B b2Vec2 points[b2_maxManifoldPoints]; //世界接触点(交点) }; ////接触点的状态 enum b2PointState { b2_nullState, //点不存在 b2_addState, //在update中添加点 b2_persistState, //点在update中持续存在 b2_removeState //点移除update }; //通过两个流形计算点的状态。这些状态与从manifold1到maniflod2的过渡有关 //所以state1要么是持续更新要么就是删除 //state2要么是添加要么是持续更新 //* 参数说明: state1 :状态1,用于保存mainfold1中接触点的状态 //state2 :状态2,用于保存mainfold2中接触点的状态 //manifold1:流形1 //manifold2:流形2 void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], const b2Manifold* manifold1, const b2Manifold* manifold2); /// //裁剪顶点结构体,用于接触流形的求解 struct b2ClipVertex { b2Vec2 v; //接触点 b2ContactID id; //接触id }; //光线输入数据。光线从p1扩展到到p1 + maxFraction * (p2 - p1) struct b2RayCastInput { b2Vec2 p1, p2; //光线(或射线)上的两个点,其中p1是起始点 float32 maxFraction; //需要检测的光线范围 }; //光线输出数据。光线达到p1 + fraction * (p2 - p1),其中p1和 p2来自b2RayCastInput struct b2RayCastOutput { b2Vec2 normal; //法向量 float32 fraction; //碰撞点位置的参数值 }; ///轴对齐包围盒 struct b2AABB { /// 验证边界排序是否有效 bool IsValid() const; /// 获取AABB的中心点 b2Vec2 GetCenter() const { return 0.5f * (lowerBound + upperBound); } /// 获取AABB的区段(宽高的一半) 返 回 值: aabb的区段 b2Vec2 GetExtents() const { return 0.5f * (upperBound - lowerBound); } /// 获取AABB的周长 float32 GetPerimeter() const { float32 wx = upperBound.x - lowerBound.x; float32 wy = upperBound.y - lowerBound.y; return 2.0f * (wx + wy); } ///合并AABB void Combine(const b2AABB& aabb) { lowerBound = b2Min(lowerBound, aabb.lowerBound); upperBound = b2Max(upperBound, aabb.upperBound); } ///合并两个AABB,为对象的aabb赋值 // * 参数说明: aabb1:一个AABB的引用 // aabb2:一个AABB的引用 void Combine(const b2AABB& aabb1, const b2AABB& aabb2) { lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound); upperBound = b2Max(aabb1.upperBound, aabb2.upperBound); } ///当前aabb是否包含提供的AABB // * 参数说明: aabb1:提供的AABB的引用 // * 返 回 值: true :包含 // false:不包含 bool Contains(const b2AABB& aabb) const { bool result = true; result = result && lowerBound.x <= aabb.lowerBound.x; result = result && lowerBound.y <= aabb.lowerBound.y; result = result && aabb.upperBound.x <= upperBound.x; result = result && aabb.upperBound.y <= upperBound.y; return result; } // 光线投射 // * 参数说明: output:光线输出数据引用 // input :光线输入数据引用 // * 返 回 值: true :碰撞 // false:不碰撞 bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; // b2Vec2 lowerBound; ///< //lower顶点 b2Vec2 upperBound; ///< //upper顶点 }; /// 求两个圆形成的碰撞流形 //* 参数说明: manifold :流形对象的指针 //circleA :圆形A对象指针 //xfA :变换A对象引用 //circleB :圆形B对象指针 //xfB :变换B对象引用 void b2CollideCircles(b2Manifold* manifold, const b2CircleShape* circleA, const b2Transform& xfA, const b2CircleShape* circleB, const b2Transform& xfB); /// 求一个多边形和一个圆形成的碰撞流形 //* 参数说明: manifold :流形对象的指针 //polygonA :多边形A对象指针 //xfA :变换A对象引用 //circleB :圆形B对象指针 //xfB :变换B对象引用 void b2CollidePolygonAndCircle(b2Manifold* manifold, const b2PolygonShape* polygonA, const b2Transform& xfA, const b2CircleShape* circleB, const b2Transform& xfB); /// 求解两个多边形碰撞产生的流形 //* 参数说明: manifold:碰撞流形指针,用于保存两个圆产生的流形 //polygonA:多边形A指针 //xfA :变换A //polygonB:多边形B指针 //xfB :变换B void b2CollidePolygons(b2Manifold* manifold, const b2PolygonShape* polygonA, const b2Transform& xfA, const b2PolygonShape* polygonB, const b2Transform& xfB); /// 求解一个边缘形状和一个圆碰撞产生的流形 //* 参数说明: manifold:碰撞流形指针,用于保存两个圆产生的流形 //polygonA:多边形A指针 //xfA :变换A //polygonB:多边形B指针 //xfB :变换B void b2CollideEdgeAndCircle(b2Manifold* manifold, const b2EdgeShape* polygonA, const b2Transform& xfA, const b2CircleShape* circleB, const b2Transform& xfB); /// 求解一个边缘形状和一个多边形碰撞产生的流形 //* 参数说明: manifold:碰撞流形指针,用于保存两个圆产生的流形 //edgeA :边缘形状A指针 //xfA :变换A //polygonB:多边形B指针 //xfB :变换B void b2CollideEdgeAndPolygon(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA, const b2PolygonShape* circleB, const b2Transform& xfB); /// 裁剪碰撞流形 //* 参数说明: vOut :裁剪顶点输出数组 //vIn :裁剪顶点输入数组 //normal :法向量 //offset :偏移量 //vertexIndexA:顶点索引 //* 返 回 值: 输出顶点的个数 int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], const b2Vec2& normal, float32 offset, int32 vertexIndexA); /// 测试两个通用的形状是否重叠。 //通过距离【Distance】判断是否重叠 //* 参数说明: shapeA :形状A //indexA :索引A //shapeB :形状B //indexB :索引B //xfA :变换A //xfB : 变换B //* 返 回 值:true :重叠 //false :不重叠 bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, const b2Shape* shapeB, int32 indexB, const b2Transform& xfA, const b2Transform& xfB); // ---------------- Inline Functions ------------------------------------------//内联函数 //验证边界排序是否有效 inline bool b2AABB::IsValid() const { b2Vec2 d = upperBound - lowerBound; bool valid = d.x >= 0.0f && d.y >= 0.0f; valid = valid && lowerBound.IsValid() && upperBound.IsValid(); return valid; } //测试两个通用的形状是否重叠。 //通过aabb判断是否重叠 //* 参数说明: a :AABB对象的引用 //b :AABB对象的引用 //* 返 回 值: true :重叠 //false:不重叠 inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b) { b2Vec2 d1, d2; d1 = b.lowerBound - a.upperBound; d2 = a.lowerBound - b.upperBound; if (d1.x > 0.0f || d1.y > 0.0f) return false; if (d2.x > 0.0f || d2.y > 0.0f) return false; return true; } #endif