admin管理员组

文章数量:1516870

OpenInventor实现碰撞检测

0.准备工作

本文开发环境:VS2008+Qt4.8.6+Coin3D 3.1.3
功能:实现碰撞检测
文件:model.iv

1.介绍 SoIntersectionDetectionAction##

本文利用SoIntersectionDetectionAction类实现碰撞检测。
来看看SoIntersectionDetectionAction类:
主要用到以下函数:

  • 添加碰撞发生时的回调函数cb
virtual void addIntersectionCallback(SoIntersectionCB * cb, void * closure  = NULL);
  • 设置过滤条件函数
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 shapesreturn SoIntersectionDetectionAction::NEXT_SHAPE;
}

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

SbBool CollisionTest::filterCB(void * userdata, const SoPath * p1, const SoPath * p2)
{qDebug()<<"filterCB";return true;
}

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

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

本文标签: OpenInventor实现碰撞检测