• Bullet 学习笔记之 btCollisionWorld


    对于 Bullet 物理引擎中的碰撞检测部分,并不太关心它的实现细节,更想知道的是物体的存储方式/数据存放、碰撞结果在哪儿,大致的步骤等


    1、碰撞场景类 btCollisionWorld 的结构

    btCollisionWorld 是 Bullet 物理引擎中的碰撞场景类,并由此派生出了 btDynamicsWorld 以及进一步派生出 btDiscreteDynamicsWorld btSoftRigidDynamicsWorld 等。

    先从 btCollisionWorld 的成员变量/函数分析它的碰撞算法/数据存储:

    btAlignedObjectArray<btCollisionObject*> m_collisionObjects;
    
    btDispatcher* m_dispatcher1;
    
    btDispatcherInfo m_dispatchInfo;
    
    btBroadphaseInterface* m_broadphasePairCache;
    

    主要成员变量有这么四个。其中,m_collisionObjects 是存放场景中的物体。m_dispatcher1 是用于 narrowphase collision detection 的,即,用于精确碰撞检测,(其中,通过 btDispatcher 类可知,最终的碰撞检测结果,也是存放在 dispatcher 中的 btPersistentManifold 或者 user callbacks。)另,m_dispatchInfo 是精确碰撞检测的一些配置信息。m_broadphasePairCache 则应该是用于 broadphase collision detection 的,最终形成可能的碰撞对 overlappinng pairs 。


    2、碰撞场景 btCollisionWorld 的初始化/搭建

    接下来看,btCollisionWorld 类的初始化过程,以及在 Basic Example 中,都是怎么配置 btCollisionWorld 的。

    在构造函数中,分别对 m_dispatcher1m_broadphasePairCache 进行了初始化。参见 BasicDemo 中的例子,初始化阶段:

    m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);    // --> m_dispatcher1
    
    m_broadphase = new btDbvtBroadphase();    // --> m_broadphasePairCache
    

    那么,broad phase 是由 btDbvtBroadphase 类完成的,并将所检测到的 overlapping pairs 存储在其当中; narrow phase 则是由 btCollisionDispatcher 类完成的,并将最终检测到的碰撞点信息存放在 btPersistentManifold 中。

    此外,对于场景中的碰撞对象的添加、删除、访问,可以通过以下函数实现:

    virtual void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter);
    
    virtual void removeCollisionObject(btCollisionObject* collisionObject);
    
    btCollisionObjectArray& getCollisionObjectArray()
    {
    	return m_collisionObjects;
    }
    
    const btCollisionObjectArray& getCollisionObjectArray() const
    {
    	return m_collisionObjects;
    }
    

    3、碰撞检测方式/过程

    接下来,大致看一下碰撞检测过程,以及碰撞的到的结果(),是存放在什么地方,又是如何被进一步调用的。

    在文章 Ron Ngai:[Bullet3]三种碰撞检测及实现 中提到,Bullet 物理引擎可以实现三种方式的碰撞检测:(1)btCollisionWorld::contactTest 检测指定对象是否与场景发生碰撞;(2)btCollisionWorld::performDiscreteCollisionDetection 检测场景中所有物体的碰撞;(3)btCollisionWorld::rayTest 对场景中的所有物体进行射线碰撞检测。

    也可以这么说,btCollisionWorld 类可以实现以下几种碰撞检测方式:

    • 3.1、对场景中所有物体进行碰撞
      具体来说,是通过调用函数 btCollisionWorld::performDiscreteCollisionDetection() 实现。

    • 3.2、对场景中所有物体进行射线碰撞检测
      调用函数 btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) 完成。对于检测到的结果,可以分为 first hit, all hits, any hit 等,通过调用 resultCallback 可以对结果进行处理。(其实还有一个,可以对一个给定的射线、给定的对像,进行碰撞检测。)具体函数为:

    /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
    /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
    virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
    
    /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
    /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
    /// This allows more customization.
    static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
    			btCollisionObject* collisionObject,
    			const btCollisionShape* collisionShape,
    			const btTransform& colObjWorldTransform,
    			RayResultCallback& resultCallback);
    
    • 3.3、给定对象与场景中所有对象的碰撞检测
      包括了两个函数,具体为:
    ///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback.
    ///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
    void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
    
    ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
    ///it reports one or more contact points (including the one with deepest penetration)
    void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback);
    
    
    • 3.4、Convex Sweep Test
      感觉应该是,给定一个 convex 对象,在场景中从 from 运动至 to ,该过程中会发生哪些碰撞,结果包括 first hit, all hits, any hit。碰撞结果可以由 resultCallback 访问并处理。具体函数为:
    /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
    /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
    void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const;
    

    4、碰撞结果存储及处理

    对于 btCollisionWorld 中不同的碰撞检测方式(如3.1 - 3.4所述),其结果的存放/处理也不尽相同。就逐个分析一下吧

    • 4.1 对场景中所有物体进行碰撞 - 碰撞结果存放及处理

    • 4.2 对场景中所有物体进行射线碰撞检测 - 碰撞检测结果存放及处理

    • 4.3、给定对象与场景中所有对象的碰撞检测 - 碰撞结果存放及处理

    • 4.4、Convex Sweep Test - 碰撞结果存放及处理


    5、结语

    xxx。

  • 相关阅读:
    iis相关概念和操作
    论文阅读笔记(十七)【ICCV2017】:Dynamic Label Graph Matching for Unsupervised Video Re-Identification
    论文阅读笔记(十六)【AAAI2018】:Region-Based Quality Estimation Network for Large-Scale Person Re-Identification
    论文阅读笔记(十五)【CVPR2016】:Top-push Video-based Person Re-identification
    论文阅读笔记(十四)【AAAI2020】:Appearance and Motion Enhancement for Video-based Person Re-identification
    论文阅读笔记(十三)【arxiv2018】:Revisiting Temporal Modeling for Video-based Person ReID
    论文阅读笔记(十二)【CVPR2018】:Exploit the Unknown Gradually: One-Shot Video-Based Person Re-Identification by Stepwise Learning
    论文阅读笔记(十一)【ICCV2017】:Jointly Attentive Spatial-Temporal Pooling Networks for Video-based Person Re-Identification
    论文阅读笔记(十)【CVPR2016】:Recurrent Convolutional Network for Video-based Person Re-Identification
    论文阅读笔记(九)【TIFS2020】:True-Color and Grayscale Video Person Re-Identification
  • 原文地址:https://www.cnblogs.com/wghou09/p/12819204.html
Copyright © 2020-2023  润新知