The application of bullet physics engine in OpenGL

Source: Internet
Author: User
Tags gety

The application of bullet physics engine in OpenGL

When developing OpenGL applications, it is inevitable to encounter the use of physics to simulate the scene content in OpenGL. Since OpenGL is only a development interface for graphics, it is necessary to use a third-party library to implement the physical simulation of the scene. At present I choose Bullet Physics engine, its official website is Bullet, the development library is on GitHub.

1. OpenGL Environment

First we need to build the framework, OpenGL's basic framework is not detailed here, I am personally in the geometry shader implementation of lighting, this is because I realized the face normal. Other third-party libraries have GLFW and GLM libraries that help manage OpenGL windows, which eliminates the process of learning mathematical formulas. In addition, the cube model and the sphere are created to meet the needs of learning Bullet.

2. Initialization of the physical environment

For the Bullet physical library, it is also very simple to build, in the context of the initialization of OpenGL, you can also initialize our physical environment, referring to the physical library's own HelloWorld can be, the relevant code is:

    ///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));
3. Destruction of the physical environment

Accordingly, there is the cleanup code

    std::vector<ModelInfo>::iterator it = m_models.begin();    while(it != m_models.end())    {        ModelInfo info = *it;        delete info.model;        m_dynamicsWorld->removeRigidBody(info.obj);        it++;    }    m_models.clear();    for (int j=0;j<m_collisionShapes.size();j++)    {        btCollisionShape* shape = m_collisionShapes[j];        m_collisionShapes[j] = 0;        delete shape;    }    //delete dynamics world    delete m_dynamicsWorld;    //delete solver    delete m_solver;    delete m_broadphase;    delete m_dispatcher;    delete m_collisionConfiguration;    //next line is optional: it will be cleared by the destructor when the array goes out of scope    m_collisionShapes.clear();

Within my implementation, the struct modelinfo is a custom struct (struct), and I have stored the physical model of all objects and their corresponding OpenGL models through the container of the struct, so that when the physical library updates the position and direction of an object, we can The position and orientation of the object within the update.

4. Rendering of the physical world

Here is the code that I render all the models in the physical world, calculate the transformation matrices for all the models, and then notify their associated code to render.

 void Physicsbaseworld::render () {Std::vector<modelinfo>::iterator it = M_models.begin (); while (It! = M_models.end ()) {Modelinfo info = *it; btrigidbody* obj = info.obj; btrigidbody* BODY = btrigidbody::upcast (obj); Bttransform Trans; if (Body && body->getmotionstate ()) {body->getmotionstate ()->getworldtransform (trans); } else {trans = Obj->getworldtransform (); } GLM::VEC3 Position = GLM::VEC3 (float (Trans.getorigin (). GetX ()), Float (Trans.getorigin (). GetY ()), float (trans.getor Igin (). GetZ ()); Btquaternion rot = Trans.getrotation (); Glm::quat q = Glm::quat (ROT.GETW (), Rot.getx (), Rot.gety (), Rot.getz ()); Glm::mat4 rot4 = GLM::TOMAT4 (q); Glm::mat4 m = glm::translate (GLM::MAT4 (1.0), position) * ROT4; model* model = Info.model; Model->setmodelmat (m); Model->render (); it++; }}
5. Draw a Static object

In the process of creating the physical world, the physical library primarily uses the function createrigidbody () to create a rigid body model, which has three parameters, representing the mass, transformation, and shape, respectively. Objects with a mass of 0 are stationary objects that can be used to create object models such as ground or roadside stones. Code to create a still cube model

    ///create a few basic rigid bodies    btCollisionShape* shape = new btBoxShape(btVector3(halfsize[0],halfsize[1],halfsize[2]));    m_collisionShapes.push_back(shape);    btTransform transform;    transform.setIdentity();    transform.setOrigin(btVector3(pos[0], pos[1], pos[2]));    {        btScalar mass(0.);        btRigidBody* body = createRigidBody(mass,transform,shape);        Cube* cube = new Cube(halfsize[0],halfsize[1],halfsize[2]);        cube->setColor(col);        ModelInfo info = {body, cube};        m_models.push_back(info);    }

In the process of creating the code above, I also created a corresponding OpenGL cube.

6. Draw an object that can be active

You need to set related motion state information when creating an active model

    btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));    //rigidbody is dynamic if and only if mass is non zero, otherwise static    bool isDynamic = (mass != 0.f);    btVector3 localInertia(0, 0, 0);    if (isDynamic)        shape->calculateLocalInertia(mass, localInertia);    btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);    btRigidBody::btRigidBodyConstructionInfo cInfo(mass, myMotionState, shape, localInertia);    btRigidBody* body = new btRigidBody(cInfo);    body->setUserIndex(-1);    m_dynamicsWorld->addRigidBody(body);    btBoxShape* s = dynamic_cast<btBoxShape*>(shape);    if(s != 0)    {        btVector3 size = s->getHalfExtentsWithMargin();        Cube* cube = new Cube(size.getX(), size.getY(), size.getZ());        cube->setColor(col);        ModelInfo info = {body, cube};        m_models.push_back(info);    }    return body;
7. Updating the physical world

Finally, we need to always update the location and orientation of the model in the physical world.

m_dynamicsWorld->stepSimulation(elpasedTime, 0);

The application of bullet physics engine in OpenGL

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.