PhysX学习记录 七 冲突检测

64 篇文章 0 订阅
16 篇文章 2 订阅

冲突碰撞是针对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;				// mesh的定点描述序列。
	stm.triangles = triangles;			// 三角形定点序列
	stm.flags |= NX_MF_FLIPNORMALS;
	return pPhysxSDK->createCCDSkeleton(stm);
}

由于 NxCCDSkeleton是一个Skeleton描述。所以不同的shape可以使用一个skeleton描述。不用每次创建shape都需要重新new新的
NxCCDSkeleton。
 
 

杂记

速度并非高过某一值就必定发生穿墙。穿墙的速度是离散分布的。
比如29会碰撞,30穿墙,31碰撞,32穿墙。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值