查询
Chipmunk空间支持4种空间查询包括最近点查询、线段查询、形状查询和快速包围盒查询。任何一种类型都可在空间里有效运行,并且点和线段查询可以针对单个形状来进行。所有类型的查询需要一个碰撞组和层,并使用和过滤形状间碰撞一样的规则来过滤出匹配。如果你不希望过滤掉任何匹配,使用CP_ALL_LAYERS
作为层,CP_NO_GROUP
作为组。
最近点查询
点查询对于像鼠标拾取和简单的感应器来说非常有用。它允许你检查离给定点一定距离内是否存在着形状,找到形状上离给定点最近的点或者找到离给定点最近的形状。
typedef struct cpNearestPointQueryInfo {
/// 最近的形状,如果在范围内没有形状返回NULL
cpShape *shape;
/// 形状表面上最近点(世界坐标系)
cpVect p;
/// 离给定点的距离。如果点在形状内部距离则为负值
cpFloat d;
/// 距离函数的梯度
/// 和info.p/info.d相同,但是即使当info.d是非常小的值来时仍然精确
cpVect g;
} cpNearestPointQueryInfo;
线段查询
线段查询就像射线投射一样,但由于并非所有的空间索引都允许处理无限长的射线查询所以它仅限于线段。在实践中这仍然非常快速,你不用过多的担心过长的线段查询会影响到性能。
typedef struct cpSegmentQueryInfo {
//碰撞的形状,如果没有碰撞发生则为NULL
cpShape *shape;
// 线段查询的归一化距离,在[0,1]范围内
cpFloat t;
// 表面命中点的法向量
cpVect n;
} cpSegmentQueryInfo;
线段查询辅助函数:
cpVect cpSegmentQueryHitPoint(cpVect start, cpVect end, cpSegmentQueryInfo info)
返回在世界坐标系内线段与形状相交的第一个相交点。
cpFloat cpSegmentQueryHitDist(cpVect start, cpVect end, cpSegmentQueryInfo info)
返回线段与形状第一个相交点的绝对距离。
AABB查询
形状查询
形状查询允许你检测空间中的形状是否和一个指定的区域发生了重叠。你可以通过这个来检测物物体是否已经在一个位置存在如果你想在该位置添加另外一个形状的话,又或者在AI中使用它进行感应查询。
在查询前,你可以创建一个刚体对或者形状对,或者你创建一个shape值传为NULL
的刚体,通过调用cpShapeUpdate()
函数来设置形状的位置和旋转角度。
typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data);
cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);
关于上面代码:查询space
来找到和shape
重叠的形状。使用层和群组来过滤掉shape
最后得到匹配。
闭包
如果你的编译器支持闭包(如Clang), 还有另外一组函数可以调用,如cpSpaceNearestPointQuery_b()
等。详情请参考chipmunk.h
。
例子
更多信息见查询例子