原文地址:http://blog.csdn.net/heartrude/article/details/7790650
冲突碰撞是针对Shape的碰撞。Shape之间可能存在默认不碰撞检测的情况。相互碰撞检测方式如下图:
Shape免冲突设置
只要设置ShapeDesc.shapeFlags |= NX_TRIGGER_ENABLE就可以使得该Shape免予冲突检测。
冲突检测优化
冲突检测是很耗性能的。每次的遍历是很难实现的。所以有一些性能上的优化。首先能够冲突检测的pair是在一定的距离内的。另外还要满足下面的冲突检测前的判断。
(a->getActor()->isDynamic() || b->getActor()->isDynamic()) && NxScene::getGroupCollisionFlag(a->getGroup(), b->getGroup()) && (!(NxScene::getShapePairFlags(a,b) & NX_IGNORE_PAIR))
1.pair的两个actor必须有一个是dynamic的
2.Shape分组过滤器
可以手工把Shape分到组里面。系统维护了一个32*32的矩阵碰撞检测标志,也就是一共可用32个组。默认所有的Shape都在0组。如果两个组不碰撞,则不进行碰撞检测。下面函数可以修改矩阵标志位。
NxScene::setGroupCollisionFlag(CollisionGroup g1, CollisionGroup g2, bool enable);
3.Actor分组过滤器
Actor分组与Shape分组功能类似。不过Actor分组需要设置有效的碰撞标志位,而不能完全屏蔽碰撞。默认都在0组。如果希望默认能够冲突检测,就需要设置 0组合0组制件能够冲突碰撞。
gScene->setActorGroupPairFlags(333,334, NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_END_TOUCH);
标志位包括:NX_NOTIFY_ON_START_TOUCH, NX_NOTIFY_ON_END_TOUCH, NX_NOTIFY_ON_TOUCH.
4.Pair专门标志过滤器
可以只设置对应的两个actor或者shape的碰撞过滤。
NxScene::setActorPairFlags(NxActor&, NxActor&, NxU32 flags); NxScene::setShapePairFlags(NxShape&, NxShape&, NxU32 flags);
5.Shape Conact过滤器
针对shape的128bit组、操作符、标志位判定过滤器。
6.专门的用户定义过滤器
设置了用户自定义过滤器后,其他的过滤器都失效了(2,3,4)。
CCD Continuous Collision Detection
这个我一开始是理解为连续冲突检测,就是一个simulate里面可以多次碰撞。看了文档后才发现原来是针对Discrete Collision Detection而来的。主要是针对高速移动actor的碰撞检测,如果使用discrete collision detect可能出现穿墙而过的情况而出现的一个算法。原理是就是DCD顾名思义就是离散冲突检测。检测只在各个step点上,所以可能导致穿墙。而CCD是step的路线框出一个矩形和另一个actor进行碰撞检测。所以可以避免穿墙的问题。
对于慢速移动、多碰撞物体模拟效果会步入DCD。比如在凹面上面滚动的球。
CCD有效的必要条件
1.NX_COUTINUOUS_CD设置为true,该设置可以在运行时修改:
gPhysicsSDK->setParameter(NX_COUTINUOUS_CD, true)
或者NX_CF_INHERIT_SETTING标志位清除,NX_CF_CONTINUOUS_CD设置true
dynamic vs static
2.dynamic Actor对象必须有 CCD skeleton
3.dynamic Actor的线速度必须高于CCDMotionThreshold.默认是0
4.static Actor的shape必须是NxConvexMeshShape、NxTriangleMeshShape的组合
dynamic vs dyname
2.2个Actor至少包含一个设置了NX_SF_DYNAMIC_CCD的Shape
3.两个Actor都必须包含CCD Skeleton
4.至少一个Actor的线速度必须超过CCDMotionThreshold
5.两个Actor的相对速度必须超过CCDMotionThreshold
ccd skeleton创建
这里记录一下ccd skeleton的创建相关内容。
主要是mesh的问题,上代码:
- NxCCDSkeleton* CreateCCDSkeleton (NxPhysicsSDK* pPhysxSDK, float size)
- {
- NxU32 triangles[3 * 12] = {
- 0,1,3,
- 0,3,2,
- 3,7,6,
- 3,6,2,
- 1,5,7,
- 1,7,3,
- 4,6,7,
- 4,7,5,
- 1,0,4,
- 5,1,4,
- 4,0,2,
- 4,2,6
- };// 三角形定点序列。一个三角形3个点。这里写的是定点的index.对应后续的stm.points数组里面的定点序列。1就是stm.points[1]
- NxVec3 points[8];
- //static mesh
- points[0].set( size, -size, -size);
- points[1].set( size, -size, size);
- points[2].set( size, size, -size);
- points[3].set( size, size, size);
- points[4].set(-size, -size, -size);
- points[5].set(-size, -size, size);
- points[6].set(-size, size, -size);
- points[7].set(-size, size, size);
- NxSimpleTriangleMesh stm;
- stm.numVertices = 8;
- stm.numTriangles = 6*2;
- stm.pointStrideBytes = sizeof(NxVec3);
- stm.triangleStrideBytes = sizeof(NxU32)*3;
- stm.points = points;<span style="white-space:pre"> </span>// mesh的定点描述序列。
- stm.triangles = triangles;<span style="white-space:pre"> </span>// 三角形定点序列
- stm.flags |= NX_MF_FLIPNORMALS;
- return pPhysxSDK->createCCDSkeleton(stm);
- NxCCDSkeleton。
杂记
速度并非高过某一值就必定发生穿墙。穿墙的速度是离散分布的。
比如29会碰撞,30穿墙,31碰撞,32穿墙。