您的位置:首页 > 运维架构

Open Inventor实现碰撞检测

2017-12-28 18:55 615 查看

0.准备工作

本文开发环境:VS2008+Qt4.8.6+Coin3D 3.1.3

功能:实现碰撞检测

文件:model.iv

1.介绍 SoIntersectionDetectionAction

本文利用SoIntersectionDetectionAction类实现碰撞检测。

来看看SoIntersectionDetectionAction类:

主要用到以下函数:

① virtual void addIntersectionCallback(SoIntersectionCB * cb, void * closure = NULL);

添加碰撞发生时的回调函数cb

② virtual void setFilterCallback(SoIntersectionFilterCB * cb, void * closure = NULL);

这个函数可以设置过滤条件,比如当某物体和指定物体发生碰撞时,用户设定为碰撞发生,当别的碰撞即便发生,但不是用户所关心的,则忽略该碰撞。即用户可以通过该函数订制碰撞发生的条件。

③apply:这个可以将该碰撞检测Action“应用”到某个指定节点、某条指定路径或者某些路径等。

virtual void apply(SoNode * node);

virtual void apply(SoPath * path);

virtual void apply(const SoPathList & paths, SbBool obeysRules = FALSE);

④ typedef Resp SoIntersectionCB(void * closure, const SoIntersectingPrimitive * p1, const SoIntersectingPrimitive * p2);

该函数是碰撞发生时,(一次碰撞时两个物体碰撞,多个物体碰撞都可以分解为两两碰撞),相互碰撞的两个物体的路径。

本示例程序中仅用到上述函数,当然了,这个类的函数还很丰富的,更多的函数以后再慢慢介绍!

2.使用示例

IDAction = new SoIntersectionDetectionAction;
//回调函数
IDAction->addIntersectionCallback(onIntersection, NULL);
//过滤函数
IDAction->setFilterCallback(filterCB,NULL);
//应用到根节点
IDAction->apply(pRootSeparator);

接下来是声明和定义发生碰撞时的回调函数


SoIntersectionDetectionAction::Resp CollisionTest::onIntersection(void *userdata,

const SoIntersectingPrimitive *primitive1, const SoIntersectingPrimitive *primitive2)

{

// These two primitive have an intersection.

qDebug()<<”Intersection hit!/n”;

SoPath* primitivePath1 = primitive1->path;
for(int i=0;i<primitivePath1->getLength();i++)
{
SoNode* tmpNode = primitivePath1->getNode(i);
QString tmpName = tmpNode->getName().getString();
QString tmpType = tmpNode->getTypeId().getName().getString();
//qDebug()<<i<<"  Name:"<<tmpName<<"\tType:"<<tmpType;
}
SoPath* primitivePath2 = primitive2->path;
for(int i=0;i<primitivePath2->getLength();i++)
{
SoNode* tmpNode = primitivePath2->getNode(i);
QString tmpName = tmpNode->getName().getString();
QString tmpType = tmpNode->getTypeId().getName().getString();
//qDebug()<<i<<"  Name:"<<tmpName<<"\tType:"<<tmpType;
}
// This callback will be called for the two next colliding shapes
return SoIntersectionDetectionAction::NEXT_SHAPE;


}

上面的代码中,CollisionTest是我自己定义的类。在该处理函数中,并没有实际意义的处理,只是把发生碰撞的两个物体及其路径上的节点类型、节点名字打印出来,便于大家理解。
接下来是定义过滤函数:


SbBool CollisionTest::filterCB(void * userdata, const SoPath * p1, const SoPath * p2)

{

qDebug()<<”filterCB”;

return true;

}

在该函数里我也并没有写什么代码,只是给大家示范一下。如果返回为false,则所有碰撞都会被忽略,所以用户可以根据自己的需求订制碰撞类型、碰撞条件等。

核心代码即是这样,之后我会在CSDN上上传相关资源,有需要的可以去下载!

原创,禁止转载!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: