//----------------------------------------------------------
扫掠API
//----------------------------------------------------------
PhysX扫掠API允许你使用一个shape,并且在空间中将其沿着一条直线发射,用以检测一个或者一些和其他场景中的shape相交的地方。
它的原理和射线查询类似,不同的地方在于射线查询在空间中只发射一个点,形成一条直线,尽管扫掠API允许你使用更复杂的形状。
为了更加形象的描述这个过程,以球形为例子,当一个球形在空间中沿着一条直线进行扫掠,它会形成一个胶囊。
When performing a sweep the user specifies a motion vector, this specifies the direction and magnitude of the path the objects is swept over.
The API will in turn return a "time of impact" for the sweep, this is the fraction of the motion vector that the object can sweep until it touches another object.
Along with this a contact point and normal are provided, the contact point is the point(or one of the points) where the objects touch at the time of impact.
为了执行一次扫掠,用户需要指定一个运动矢量,它指出了方向和将要用于扫掠的路径长度。
扫掠API在进行扫掠时将会依次返回一些“碰撞的时刻”,
"这是 分数 运动矢量 "能进行扫掠的对象直到他接触到其他对象。
通过这个,将会给出一个接触点和矢量,这个(或一些中的某个)接触点来自于在“碰撞的时刻”发生接触的对象。
(译者:我不明白这段在说什么,所以保留原文,主要就是 time of impact , 这到底在说什么样的行为呢?
因为下文中对于返回结果的描述中并没有接触时间相关的文字,或许只是指简单的one by one 的返回?)
一次扫掠可以使用以下实体进行:
Box
Capsule(胶囊)
Actor
注意:一个球形扫掠可以用一个高度为0的胶囊来表示。
可被使用的扫掠检测结果都将通过 NxSweepQueryHit 结构体返回。
struct NxSweepQueryHit
{
NxF32t;//!< 距离
NxShape*hitShape;//!< 接触的Shape
NxShape*sweepShape;//!< 只有在使用NxActor::linearSweep.(线性扫掠)的时候才非空
//!< 用于扫掠的Shape中那些和目标Shape发生接触的Shape
void*userData;//!< 用户自定义数据
NxU32internalFaceID;//!< 发生接触的三角面的ID号(内部的)
NxU32faceID;//!< 发生接触的三角面的ID号(外部的)
NxVec3point;//!< 世界空间中的接触点
NxVec3normal;//!< 世界空间中的接触点法线
};
注意:三角面的内部ID和外部ID分别对应于未经过处理的网格数据和经过处理的网格数据(译者:参考 Meshes 的 Cooking 章节)。
扫掠缓存
一个扫掠缓存何以被用来加速大量相似的查询。举个例子,比如沿着NPC视线进行多次射线查询。
扫掠缓存的工作方式是储存一个离扫掠发起点很近的对象列表。因此当进行下一次扫掠的时候,那些离的最近的物体就会首先被检测,从而过滤掉大量的对象。
注意扫掠缓存可能会被保存成多种格式,这些格式是可选的(对于扫掠检测来说)。
static NxSweepCache* cache = gScene->createSweepCache();
NxU32 nb = BoxActor->linearSweep(dir*dist, flags, NULL, 100, results, NULL, cache);
注意,扫掠缓存可以限制成一个具有精确边界体积的空间范围。( 因此只有和这个体积相交的对象才会被保存 )
void NxSweepCache::setVolume(const NxBox& box);
注意: 在多场景共存的时候执行扫掠测试,扫掠缓存将不会被共享,因为访问缓存的时候不连续。换句话说,你需要每场景指定扫掠缓存的使用策略。
警告:
扫掠检测不支持“轮型Shape”
触发器形状将不会被扫掠
目前所有的扫掠检测都是同步的.
以下行为的结果是未定义的:在进行扫掠之前,用于扫掠的Shape就已经和某些对象相交了。( 是不是说需要避免这样的情况呢? )
//----------------------------------------------------------
Box扫掠
//----------------------------------------------------------
你可以通过使用NxScene::linearOBBSweep()方法来执行一次Box形状的扫掠. 结果将通过一个 NxSweepQueryHit 结构体进行返回。
NxU32 linearOBBSweep( const NxBox& worldBox,
const NxVec3& motion,
NxU32 flags,
void* userData,
NxU32 nbShapes,
NxSweepQueryHit*shapes,
NxUserEntityReport<NxSweepQueryHit>*callback,
NxU32 activeGroups=0xffffffff,
const NxGroupsMask*groupsMask=NULL
);
worldBox - 一个Box结构体,描述了被扫掠使用的Box,在世界坐标系中进行那个的描述。
motion - 扫掠的运动矢量。
flags
NX_SF_STATICS: 扫掠针对静态Shape
NX_SF_DYNAMICS: 扫掠针对动态Shape
NX_SF_ALL_HITS: 扫掠返回全部结果,而不是仅仅返回最近的对象。
userData - 用户自定义的数据,通过用户指定的回调函数进行传递。
nbShapes - 用于保存Shape对象的缓存的大小,用Shape对象的数量进行描述。
shapes - 一个用户提供的用于保存接触的Shape的对象的缓存
callback - 回调函数指针,在返回结果的时候调用
activeGroups - 使用对象组进行Shape的过滤,GroupID 可以通过 NxShape::setGroup()方法进行设置
groupsMask - 组的位掩码,用于按位过滤系统.
例子:
NxBox testBox;
testBox.center= NxVec3(0.0f, 100.0f, 0.0f);
testBox.extents= NxVec3(10.0f, 10.0f, 10.0f);
float dist = 100.0f;
NxVec3 dir(0.0f, -1.0f, 0.0f);
NxU32 flags = NX_SF_STATICS|NX_SF_DYNAMICS;
NxSweepQueryHit result;
gScene->linearOBBSweep(testBox, dir*dist, flags, NULL, 1, &result, NULL);
NxShape *hitShape = result.hitShape;
NxVec3 impactPoint = result.point;
//----------------------------------------------------------
胶囊扫掠
//----------------------------------------------------------
你可以通过使用NxScene::linearCapsuleSweep()方法来执行一次Capsule形状的扫掠. 结果将通过一个 NxSweepQueryHit 结构体进行返回。
NxU32 linearCapsuleSweep(const NxCapsule& worldCapsule,
const NxVec3& motion, NxU32 flags,
void* userData,
NxU32 nbShapes,
NxSweepQueryHit* shapes,
NxUserEntityReport<NxSweepQueryHit>* callback,
NxU32 activeGroups=0xffffffff,
const NxGroupsMask* groupsMask=NULL
);
worldCapsule - 一个Capsule结构体,描述了被扫掠使用的Capsule,在世界坐标系中进行那个的描述。
motion - 扫掠的运动矢量。
flags
NX_SF_STATICS: 扫掠针对静态Shape
NX_SF_DYNAMICS: 扫掠针对动态Shape
NX_SF_ALL_HITS: 扫掠返回全部结果,而不是仅仅返回最近的对象。
userData - 用户自定义的数据,通过用户指定的回调函数进行传递。
nbShapes - 用于保存Shape对象的缓存的大小,用Shape对象的数量进行描述。
shapes - 一个用户提供的用于保存接触的Shape的对象的缓存
callback - 回调函数指针,在返回结果的时候调用
activeGroups - 使用对象组进行Shape的过滤,GroupID 可以通过 NxShape::setGroup()方法进行设置
groupsMask - 组的位掩码,用于按位过滤系统.
例子:
NxCapsule testCapsule;
testCapsule.radius= 5.0f;
testCapsule.p0= NxVec3(0.0f, 100.0f, 0.0f);
testCapsule.p1= NxVec3(10.0f, 70.0f, 0.0f);
float dist = 100.0f;
NxVec3 dir(0.0f, -1.0f, 0.0f);
NxU32 flags = NX_SF_STATICS|NX_SF_DYNAMICS;
NxSweepQueryHit result;
gScene->linearCapsuleSweep(testCapsule, dir*dist, flags, NULL, 1, &result, NULL);
NxShape *hitShape = result.hitShape;
NxVec3 impactPoint = result.point;
//----------------------------------------------------------
Actor扫掠
//----------------------------------------------------------
You can perform a sweep with an entire actor, including all its constituent shapes, by using the NxActor::linearSweep() method. The results are returned via an NxSweepQueryHit structure.
你可以通过使用 NxActor::linearSweep()方法来使用一个完整的Actor进行扫掠,包括它所有的Shape元素。结果将通过一个 NxSweepQueryHit 结构体进行返回。
(译者: 注意这里是NxActor的方法,之前都是NxScene的方法)
In the current implementation actor sweep tests are only conducted using the actor shapes which are:
Capsules
Spheres
Boxes
目前实现的 Actor扫掠只支持以下几种形状:
胶囊
球
盒子
If a sweep is performed with an actor which contains, for example a convex shape,
then the convex shape will be ignored and no hits for this shape reported.
Also note that trigger shapes in the actor will be excluded from the test.
如果一个用于执行扫掠的Actor包含一些类似曲面的Shape,那么这些Shape将会被会略掉。
同样也需要注意,触发器Shape不会被检测。
NxU32 linearSweep(const NxVec3& motion,
NxU32 flags,
void* userData,
NxU32 nbShapes,
NxSweepQueryHit* shapes,
NxUserEntityReport<NxSweepQueryHit>* callback,
const NxSweepCache* sweepCache=NULL
);
motion - 扫掠的运动矢量。
flags
NX_SF_STATICS: 扫掠针对静态Shape
NX_SF_DYNAMICS: 扫掠针对动态Shape
NX_SF_ALL_HITS: 扫掠返回全部结果,而不是仅仅返回最近的对象。
userData - 用户自定义的数据,通过用户指定的回调函数进行传递。
nbShapes - 用于保存Shape对象的缓存的大小,用Shape对象的数量进行描述。
shapes - 一个用户提供的用于保存接触的Shape的对象的缓存
callback - 回调函数指针,在返回结果的时候调用
sweepCache - 一个缓存对象用于加速查询,参考 Sweep API 章节
例子:
NxActor *testactor; ...
float dist = 100.0f;
NxVec3 dir(0.0f, -1.0f, 0.0f);
NxU32 flags = NX_SF_STATICS|NX_SF_DYNAMICS;
NxSweepQueryHit result;
testActor->linearSweep(dir*dist, flags, NULL, 1, &result, NULL);
NxShape *hitShape = result.hitShape; // Shape in scene
NxVec3 impactPoint = result.point;
NxShape *sweepShape = result.sweepShape; // Shape in actor