• Bullet Basic Example 示例


    代码参见:bullet3/examples/BasicDemo


    在 Bullet 自带的例程中,仿真主要包括以下三步:

    (1)example->initPhysics();
    首先,初始化仿真相关的环境。建立仿真相关对象,添加场景中的物体,等等。

    (2)example->stepSimulation(1.f / 60.f);
    执行仿真步骤。

    (3)example->exitPhysics();
    最后,清理仿真相关的对象。


    (0)仿真场景相关的类极其组成

    在仿真场景中,主要涉及到的类有:

    btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
    btBroadphaseInterface* m_broadphase;
    btCollisionDispatcher* m_dispatcher;
    btConstraintSolver* m_solver;
    btDefaultCollisionConfiguration* m_collisionConfiguration;
    btDiscreteDynamicsWorld* m_dynamicsWorld;
    

    (1)初始化仿真环境
    所谓初始化仿真环境,一方面需要建立仿真场景相关的类,另一方面需要向仿真场景中添加所需要的物体。比如,在 BasicExample::initPhysics() 中,首先需要建立空的 EmptyDynamicWord ,即:

    ///collision configuration contains default setup for memory, collision setup
    m_collisionConfiguration = new btDefaultCollisionConfiguration();
    //m_collisionConfiguration->setConvexConvexMultipointIterations();
    
    ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
    m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
    
    m_broadphase = new btDbvtBroadphase();
    
    ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
    btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
    m_solver = sol;
    
    m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
    
    m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
    

    接下来,需要这个 EmptyDynamicWord 中添加物体,即

    ///create a few basic rigid bodies
    btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
    
    //groundShape->initializePolyhedralFeatures();
    //btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
    
    m_collisionShapes.push_back(groundShape);
    
    btTransform groundTransform;
    groundTransform.setIdentity();
    groundTransform.setOrigin(btVector3(0, -50, 0));
    
    {
    	btScalar mass(0.);
    	createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1));
    }
    

    其中, createRigidBody(...) 的内容为:

    btVector3 localInertia(0, 0, 0);
    if (isDynamic)
    	shape->calculateLocalInertia(mass, localInertia);
    
    //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
    
    btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
    
    btRigidBody::btRigidBodyConstructionInfo cInfo(mass, myMotionState, shape, localInertia);
    
    btRigidBody* body = new btRigidBody(cInfo);
    //body->setContactProcessingThreshold(m_defaultContactProcessingThreshold);
    
    
    body->setUserIndex(-1);
    m_dynamicsWorld->addRigidBody(body);
    

    (2)执行仿真步骤

    这个就比较清晰了,可以认为是一个大的步骤 m_dynamicsWorld->stepSimulation(deltaTime);

    (3)结束仿真并清理仿真场景

    大致就是清理各种 new 出来的对象,这里就不再赘述了。


    通过这个简单的示例,Bullet 总的框架就比较清晰了。可以认为,通过 btDiscreteDynamicsWorld 类创建了一个空的仿真场景。向场景中添加物体、以及物体之间的约束(比如关节等),再由 btDiscreteDynamicsWorld::stepSimulation(t) 进行仿真计算。

    那么,这里就需要进一步弄清楚两个问题,(1)仿真场景中相关的类是什么样的构成,比如物体类 btBoxShape 、碰撞对象类 btCollisionShape 、以及碰撞检测类 btCollisionDispatcher btBroadphaseInterface btDefaultCollisionConfiguration 、约束类 btTypedConstraint btConstraintSolver、等等是怎样构成的;(2)仿真步骤是如何一步一步执行的,即 btDiscreteDynamicsWorld::stepSimulation(t) 里面包含了怎样一步一步的小步骤。

  • 相关阅读:
    Stm32高级定时器(三)
    Stm32高级定时器(二)
    Java网络编程
    Java锁详解
    Linux Shell入门
    Mysql锁详解
    Redis入门——Java接口
    Redis入门——安装与基本命令
    Eclipse创建maven工程后没有build path解决方案
    Jersey入门——对Json的支持
  • 原文地址:https://www.cnblogs.com/wghou09/p/12811841.html
Copyright © 2020-2023  润新知