PhysX 3.3 基础

概述

PhysX目前是由 NVIDIA 开源的一个3D物理引擎,由于其功能强大,目前已经继承在了各大商业游戏引擎中,例如 Unreal, Unity等。

基本概念

PxScene

场景对象,同一个场景中的物体才有可能进行物理碰撞等,因此场景是一个场景物体的管理者。

PxRigidActor

刚体对象(Rigidbody)的封装

PxShape

几何体的封装, 每个 PxRigidActor 可以绑定多个 PxShape 对象,一般是通过 PxRigidActor 来创建 PxShape.

PxControllerManager

CharacterControllerManager,用于创建 CharacterController。

CharactorController

上层封装,其实就是一个 PxRigidStatic 和 一个 PxShape 的组合体。

碰撞过滤器 ReportFilterShader

ReportFilterShader用于指定哪些 intersection pairs 需要被处理,因为这个在物理引擎底层需要被频繁调用,因此性能至关重要,因此提出了 FilterShader 这样的概念,这 filter 的工作在 GPU 上也能运行,即使在 CPU 上运行也能并行。例子如下:

PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, 
    PxFilterData filterData0, 
    PxFilterObjectAttributes attributes1, 
    PxFilterData filterData1,
    PxPairFlags& pairFlags, 
    const void* constantBlock, 
    PxU32 constantBlockSize)
{

    if(PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
    {
        pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
        return PxFilterFlag::eDEFAULT;
    }

    pairFlags = PxPairFlag::eCONTACT_DEFAULT;

    // trigger the contact callback for pairs (A,B) where
    // the filtermask of A contains the ID of B and vice versa.
    // PX_INFO("contactReportFilterShader|%x|%x|%x|%x", filterData0.word0, filterData1.word1, filterData1.word0, filterData0.word1); 
    if((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
    {
        pairFlags |= PxPairFlag::eNOTIFY_TOUCH_FOUND;
        return PxFilterFlag::eDEFAULT;
    }

    return PxFilterFlag::eDEFAULT;
}

我们需要了解 ReportFilterShader 函数的参数含义以及返回值的含义:
先看看文档是怎么描述的:

The arguments of SampleSubmarineFilterShader() include PxFilterObjectAttributes and PxFilterData for the two objects, and a constant block of memory. Note that the pointers to the two objects are NOT passed, because those pointers refer to the computer's main memory, and that may, as we said, not be available to the shader, so the pointers would not be very useful, as dereferencing them would likely cause a crash. PxFilterObjectAttributes and PxFilterData are intended to contain all the useful information that one could quickly glean from the pointers. PxFilterObjectAttributes are 32 bits of data, that encode the type of object: For examplePxFilterObjectType::eRIGID_STATIC, ::eRIGID_DYNAMIC, or even ::ePARTICLE_SYSTEM. Additionally, it lets you find out if the object is kinematic, or a trigger.
Each PxShape and PxParticleBase object in PhysX has a member variable of type PxFilterData. This is 128 bits of user defined data that can be used to store application specific information related to collision filtering. This is the other variable that is passed to SampleSubmarineFilterShader() for each object.
There is also the constant block. This is a chunk of per-scene global information that the application can give to the shader to operate on. You will want to use this to encode rules about what to filter and what not.
Finally, SampleSubmarineFilterShader() also has a PxPairFlags parameter. This is an output, like the return value PxFilterFlags, though used slightly differently. PxFilterFlags tells the SDK if it should ignore the pair for good (eKILL), ignore the pair while it is overlapping, but ask again, when filtering related data changes for one of the objects (eSUPPRESS), or call the low performance but more flexible CPU callback if the shader cannot decide (eCALLBACK).
PxPairFlags specifies additional flags that stand for actions that the simulation should take in the future for this pair. For example,eNOTIFY_TOUCH_FOUND means notify the user when the pair really starts to touch, not just potentially.

简单解释一下:

  • attributes0 和 filterData0 是 intersection pair 中 第一个 PxShape 的数据,前者表示 PxShape 的 Type(PxFilterObjectType::eRIGID_STATIC, ::eRIGID_DYNAMIC, or ::ePARTICLE_SYSTEM, 是否是 kinematic 或者是一个 trigger),后者是 PxShape 的 UserData,在创建 PxShape 的时候可以通过 PxShape::setSimulationFilterData 函数指定;
  • attribute1 和 filterData1 是 intersection pair 中另一个 PxShape 的数据,含义类似;
  • PxFilterFlags 返回值是告诉SDK,如何处理这一对物体的碰撞,是放弃这一次碰撞的处理(eKILL),还是暂不处理除非这一次碰撞中filterData被改变(eSUPRESS),还是报告需要回调函数(eCALLBACK,eNOTIFY)等。而pairFlags则是定义,如果需要回调函数的话,在什么情况下,报告回调函数,如碰撞被发现(eNOTIFY_TOUCH_FOUND), 碰撞结束两个物体已分离(eNOTIFY_TOUCH_LOST)等。
  • constantBlock 和 constantBlockSize (This is a chunk of per-scene global information that the application can give to the shader to operate on. You will want to use this to encode rules about what to filter and what not.)

在创建场景的时候需要指定一个 FilterShader 用于解决后面的碰撞检测,这是在 PxSceneDesc 中指定的;然后在创建 PxShape 的时候需要指定 filterData,通过 PxShape::setSimulationFilterData 函数指定,其中的 word0 字段一般指定 layer,word1 字段指定和哪些 layer 之间会发生碰撞。

碰撞回调 PxSimulationEventCallback

场景中所有的碰撞都需要 developer 自己来进行处理,用于实现一个类继承 PxSimulationEventCallback,基类如下:

class PxSimulationEventCallback {
public:
    void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) ;
    void onWake(PxActor** actors, PxU32 count);
    void onSleep(PxActor** actors, PxU32 count) ;
    virtual void onTrigger(PxTriggerPair* pairs, PxU32 count);
   void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs) ;
};

一般而言只需要处理 OnTrigger 和 OnContact 方法。

CharacterController 碰撞回调

需要设置 PxCapsuleControllerDesc.reportCallback,其中需要实现:

void onShapeHit(const PxControllerShapeHit& hit);
void onControllerHit(const PxControllersHit& hit);

前者表示和其他 PxShape 的碰撞,后者表示和其他 CharacterController 的碰撞。

一般使用流程

  1. PxCreateFoundation 创建 PxFoundaPxPhysicsion 对象,全局唯一;
  2. PxCreatePhysics 创建 Physics对象,全局唯一;
  3. PxCreateCooking 创建 PxCooking 对象,全局唯一;
  4. PxSerialization::createSerializationRegistry 创建 PxSerializationRegistry 对象,全局唯一;
  5. 需要打开一个场景的时候,使用 Physics::CreateScene 创建一个场景,打开多个场景则需要创建多个 Scene 对象,设置好 FilterShader 和 SimulationCallback;
  6. 创建 Static 或者 Dynamic Actor 或者 CharacterController;
  7. Tick 中获取 Dynamin Actor 和 CharacterController的位置同步给逻辑层使用,同时在 SimulationCallback 中将碰撞信息通知逻辑层。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容