您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x节点(b2Collision.h)API

2013-11-29 10:42 316 查看
本文来自http://blog.csdn.net/runaying ,引用必须注明出处!


cocos2d-x节点(b2Collision.h)API

温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: