图形赋予游戏一种视觉的吸引力,但是能够让游戏的世界鲜活起来的还应该是内部的物理引擎。物理引擎是游戏引擎中的子模块,是一种软件组件,可仿真物理系统。它根据牛顿力学定律,计算游戏中物体的合理的物理位置,并将计算结果提供给渲染引擎,从而展示出真实的渲染效果。物理引擎的仿真包括柔性体和刚体力学、流体力学以及碰撞检测。以游戏为中心的物理引擎侧重于实时近似,而科学仿真中的物理引擎则更多地侧重于精确计算以获得高准确性。科学物理引擎依赖于超级计算机的处理能力,而游戏物理引擎则可运行于资源受限的平台(比如手持型游戏设备和移动手机)。

Bullet物理引擎的安装与使用

图 1. 游戏应用中的物理引擎

  Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc. 

  •  Build bullet

  下载Bullet的源代码 https://github.com/bulletphysics/bullet3/releases/latest,然后将其解压到合适的路径下。可以选择运行批处理文件生成VisualStudio工程,这里运行build_visual_studio.bat生成VS2010工程。

Bullet物理引擎的安装与使用

  在Debug模式下生成解决方案,解压后的bullet3-2.86.1目录中会出现bin文件夹,其中包含了生成的静态库文件和可执行文件。

Bullet物理引擎的安装与使用

  •  HelloWorld example

   新建一个空的控制台程序,然后在源文件目录中加入HelloWorld.cpp文件:

#include <btBulletDynamicsCommon.h>  
#include <stdio.h>
#include <iostream>
#include <fstream> 
using namespace std;

/// This is a Hello World program for running a basic Bullet physics simulation

int main(int argc, char** argv)
{

    btBroadphaseInterface* broadphase = new btDbvtBroadphase();

    ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
    
    ///use the default collision dispatcher. For parallel processing you can use a differnt dispatcher
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

    ///the default constraint solver. For parallel processing you can use a different solver
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

    ///instantiate the dynamics world
    btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

    ///sets the gravity. We have chosen the Y axis to be "up".
    dynamicsWorld->setGravity(btVector3(0,-10,0));



    btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 1);
    btCollisionShape* fallShape = new btSphereShape(1);

    //The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
    btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, -1, 0)));

    ///instantiate the ground. Its orientation is the identity, Bullet quaternions are specified in x,y,z,w form.
    btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0, 0, 0));
    
    ///Bullet considers passing a mass of zero equivalent to making a body with infinite mass - it is immovable
    btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);

    ///add the ground to the world
    dynamicsWorld->addRigidBody(groundRigidBody);


    //The btTransform class supports rigid transforms with only translation and rotation 
    btDefaultMotionState* fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50, 0)));

    btScalar mass = 1;
    btVector3 fallInertia(0, 0, 0);
    fallShape->calculateLocalInertia(mass, fallInertia);

    ///when bodies are constructed, they are passed certain parameters. This is done through a special structure Bullet provides for this.
    ///rigid body is dynamic if and only if mass is non zero, otherwise static  
    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, fallInertia);
    btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
    dynamicsWorld->addRigidBody(fallRigidBody);

    ofstream outfile("C:\\Users\\KC\\Desktop\\height.csv", ios::out);
    for (int i = 0 ; i < 300 ; i++) {

        /*  prototype:
        btDynamicsWorld::stepSimulation(btScalar timeStep, int maxSubSteps=1,
                                            btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
        */

        //It's important that timeStep is always less than maxSubSteps*fixedTimeStep
        //The first and third parameters to stepSimulation are measured in seconds
        //By decreasing the size of fixedTimeStep, you are increasing the "resolution" of the simulation.
        //When you pass Bullet maxSubSteps > 1, it will interpolate movement for you
        dynamicsWorld->stepSimulation(1 / 60.f, 10);

        btTransform trans;
        fallRigidBody->getMotionState()->getWorldTransform(trans);

        std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
        outfile<<trans.getOrigin().getY()<<endl;
    }

    outfile.close();

    delete fallShape;
    delete groundShape;

    
    delete dynamicsWorld;
    delete solver;
    delete dispatcher;
    delete collisionConfiguration;
    delete broadphase;

    printf("Press a key to exit\n");
    getchar();
}
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-28
  • 2021-11-05
  • 2022-12-23
  • 2021-06-21
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-18
  • 2022-12-23
  • 2021-10-05
  • 2021-10-30
相关资源
相似解决方案