PhysX 3.2中的场景查询(3)-使用

前面的两篇中,我们介绍了 PhysX 3.2中场景查询的一些基本概念,以及查询中如何设置过滤。有了前两节做的准备,到这一节中,我们就具体看看各种场景查询该如何使用。

 

首先看单次执行的查询。之前我们提到过,单次执行的查询,有查询有无的*Any方式,还有查询最近的*Single方式,和查询所有的*Multiple方式。

所有的这些查询方式,从根本上讲,可以抽象为从一个位置投射一个或者一组形体一定的距离, 查询跟物理场景中物体的交互情况;对于Raycast,可以理解为投射的形体就是一个点;对于Overlap,可以理解为投射的距离是0;同时,只有Sweep支持多个形体组成一组来查询的方式。

以上面加粗的字体为关键字作为基本的查询条件,再加上过滤和返回值选择的参数,以及其他加快查询的便利设计,我们可以很方便的理解各种查询的API。以raycastSingle,sweepMultiple和OverlapAny为例来说明:

bool raycastSingle(
	const PxVec3& origin, const PxVec3& unitDir, const PxReal distance, //基本查询条件
	PxSceneQueryFlags outputFlags, //定义返回的数据
	PxRaycastHit& hit, //返回查询结果,*single类,返回一个结果
	const PxSceneQueryFilterData& filterData = PxSceneQueryFilterData(), //过滤条件
	PxSceneQueryFilterCallback* filterCall = NULL, //过滤条件
	const PxSceneQueryCache* cache = NULL, //快查Cache
	PxClientID queryClient = PX_DEFAULT_CLIENT) const; //SDK的一个实验特性,可暂不考虑

PxI32 sweepMultiple(	const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance,
	PxSceneQueryFlags outputFlags,
	PxSweepHit* hitBuffer, //查询结果返回缓冲区,*multiple类,返回多个结果
	PxU32 hitBufferSize, //查询结果缓冲区的大小
	bool& blockingHit,  //返回结果中是否有Blocking Hit
	const PxSceneQueryFilterData& filterData = PxSceneQueryFilterData(),
	PxSceneQueryFilterCallback* filterCall = NULL,
	const PxSceneQueryCache* cache = NULL,
	PxClientID queryClient = PX_DEFAULT_CLIENT,
	const PxReal inflation = 0.f) const; //如果需要,将geometry增肥一点

PxI32 sweepMultiple(const PxGeometry** geometryList, const PxTransform* poseList, //Sweep查询支持多个geometry组成一个整体来查询
	const PxFilterData* filterDataList, PxU32 geometryCount, 
	const PxVec3& unitDir, const PxReal distance,
	PxSceneQueryFlags outputFlags,
	PxSweepHit* hitBuffer,
	PxU32 hitBufferSize,
	bool& blockingHit,
	PxSceneQueryFilterFlags filterFlags = PxSceneQueryFilterFlag::eDYNAMIC | PxSceneQueryFilterFlag::eSTATIC,
	PxSceneQueryFilterCallback* filterCall = NULL,
	const PxSceneQueryCache* cache = NULL,
	PxClientID queryClient = PX_DEFAULT_CLIENT,
	const PxReal inflation = 0.f) const;

bool overlapAny(const PxGeometry& geometry, const PxTransform& pose,
	PxShape*& hit, //*Any类查询,最快的速度返回跟谁碰上了,返回的数据是默认的
	const PxSceneQueryFilterData& filterData = PxSceneQueryFilterData(),
	PxSceneQueryFilterCallback* filterCall = NULL,
	PxClientID queryClient = PX_DEFAULT_CLIENT) const;


下面,就用raySingle为例来简单看该如何调用查询函数:

PxScene* scene;
PxVec3 origin = ...;                 // [in] 射线起点
PxVec3 unitDir = ...;                // [in] 标准化的射线方向
PxReal maxDistance = ...;            // [in] 投射的距离
PxRaycastHit hit;                    // [out] 检测结果

// [in] 定义我们需要的返回数据
const PxSceneQueryFlags outputFlags = PxSceneQueryFlag::eDISTANCE | PxSceneQueryFlag::eIMPACT | PxSceneQueryFlag::eNORMAL;

// 采用默认的过滤,即不过滤,返回结果保存到hit中返回
bool status = scene->raycastSingle(origin, unitDir, maxDistance, outputFlags, hit);


------------------------------------------------------------------

上面,我们介绍的是单次查询的API和使用,下面,我们说说SDK提供的另一种查询方式,批处理查询,PxBatchQuery。

批处理查询的方式,简单来说,可以这么理解:批处理的组织、执行以及结果的处理,都通过PxBatchQuery对象来进行;具体执行的过程,则是先定义好收结果的空间,然后按需将需要的查询增加到Batch中,在收集需求完毕后,调用PxBatchQuery的execute执行所有的查询。

我们可以从下面从PhysX SDK 3.2 Sample中抽取出来的代码中更清楚的了解该如何使用:

	// 准备接收结果的缓冲区,创建PxBatchQuery
	PxBatchQueryDesc batchQueryDesc;
	batchQueryDesc.userRaycastResultBuffer = mRayCastResults;
	batchQueryDesc.userRaycastHitBuffer = mRayCastHits;
	batchQueryDesc.raycastHitBufferSize = mHitSize;

	mBatchQuery = mSampleSubmarine.getActiveScene().createBatchQuery(batchQueryDesc);

	// 收集查询请求
	mSqRayBuffer->mBatchQuery->raycastSingle(rayStart, crabToSub.getNormalized(), rayDist, PxSceneQueryFilterFlag::eSTATIC|PxSceneQueryFilterFlag::eDYNAMIC);
	//...
	mSqRayBuffer->mBatchQuery->raycastSingle(rayStart[j], rayDir, rayDist, PxSceneQueryFilterFlag::eSTATIC|PxSceneQueryFilterFlag::eDYNAMIC);
	//...

	// 执行查询
	mSqRayBuffer->mBatchQuery->execute();

	// 处理查询结果
	for(PxU32 i = 0; i < mSqRayBuffer->mQueryResultSize; i++)
	{
		PxRaycastQueryResult& result = mSqRayBuffer->mRayCastResults[i];
		if(result.queryStatus == PxBatchQueryStatus::eSUCCESS && result.nbHits == 1)
		{
			PxRaycastHit& hit = result.hits[0];
			mDistances[i] = hit.distance;
			
			// ... 
		}
		
		// ...
	}


好了,到这里,PhysX SDK 3.2中的场景查询该如何使用,就介绍完了。最好的使用参考还是代码,大家可以多在PhysX SDK提供的Sample中做一些测试,更快的熟悉该如何使用这些查询功能。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值