How to apply Bullet physics to drawn Opengl 3d shapes

9.4k views Asked by At

I was just wondering whether there is a way to apply bullet physics to opengl drawn objects (created using glVertex3f or triangle mesh with glVertexAttribPointer). I am currently using jogl and jbullet to apply physics to my 3D objects. Specifically if I give a buffer of vertices for a triangle mesh shape for the 3d object. I need Bullet to create a CollisionShape based on the triangle mesh shape, and apply the physics to it, which at the same time apply physics to the drawn opengl objects. At the moment, the physical collision shape may move (in bullet), but the drawn opengl shape is not.

Otherwise, can I create a collision shape, get the vertices of the collision shape after the physics has been applied after each simulation step, and then draw the object based on the location of the vertices. I have looked at the Hello world example for bullet but it only help me apply physics on the position of the opengl object (based on the z,y,x axis_ and not cool things like for example a corner of the cube hitting a plane starts rolling and spinning.

It would be great if someone can give me some code or demo that can do this. Or give me some hints as to how I can make this work. I already looked at this tutorial on bullet: http://www.raywenderlich.com/53077/bullet-physics-tutorial-getting-started. But I can't seem to find the information to how bullet is applied to opengl objects.

4

There are 4 answers

5
Irrmich On BEST ANSWER

After you downloaded Bullet Physics SDK, look the file GL_ShapeDrawer.cpp,you will find some interresting functions such like drawSphere, drawCylinder,drawOpenGl.. the last one i mentionned lets you draw any type of suported shape :

  • CUSTOM_CONVEX_SHAPE_TYPE
  • BOX_SHAPE_PROXYTYPE
  • UNIFORM_SCALING_SHAPE_PROXYTYPE
  • COMPOUND_SHAPE_PROXYTYPE
  • BOX_SHAPE_PROXYTYPE
  • SPHERE_SHAPE_PROXYTYPE

Each type of shape from shape->getShapeType() has its own dedicated function for rendering with opengl

But my method involves to

  • 1 - Load the 3D model with a mesh loader
  • 2 - Create the graphics shape with opengl functions using the previous mesh loader
  • 3 - Create bullet shapes from the vertices used by the mesh loader
  • 4 - Implement the Bullet Motion State (when a shape is going to be rotated or translated or just "transformed", you syncronize the "btTransform" of your bullet shape with the transformation matrix of the graphic shape, then update the graphics vertices)

Personnaly, i'm using Irrlicht because Irrlicht is the "write less,do more" solution of opengl :p

5
Serpardum On

Without studying the specifics of Bullet or OpenGL (I've coded in OpenGL a little) it seems you wish to apply Bullet to an object twice, once for the CollisionShape (whatever that is) and then for the drawn opengl object.

It seems it would be a matter of creating your OpenGL object in a memory object, applying the Bullet method to get your CollisionShape (whatever that is), saving this data in memory, then applying the Bullet method to this new triangle list for world positioning (if my understanding of your question is right).

It would be similar to applying 2 different transforms on an object separately without the benefit of matrix math. You would calculate the new positions of the vectors based on rotation, then after you have these points move them in the world based on translation. You would have an intermediate step that is used in memory to apply your second translation. That is the way I had done it in my first 3d rendered I made without learning how it was done to see if I could come up with it on my own.

Maybe this will help you, maybe it won't. If it doesn't, perhaps you can explain where you are having troubles and I (or others) can look into the specifics of OpenGL and Bullet to come up with the actual algorithm for you (although I'm sure it probably exists somewhere). If you search enough you'll probably find code on the Interwebs that does something similar that you can modify, or you can try to do it on your own.

It could be my method wouldn't work, but I see no reason why it wouldn't if I understand your question correctly (which I may not, not knowing what a "CollisionShape" is in the first place).

7
gouessej On

Bullet is independent of OpenGL, it's up to you to apply the transformation to your geometry.

You can store your transforms into separate objects instead of modifying your vertices. It's what do Vehicle Dynamics Engine Demo (JOGL + JBullet) and JMonkeyEngine 3 which has its own Bullet binding and a renderer based on JOGL 2 (and some other renderers that I don't use).

Please look at our demos using JOGL and JBullet here: https://github.com/sgothel/jogl-demos/tree/master/src/jbullet

0
Ciro Santilli OurBigBook.com On

Bullet Example Browser

The in-tree example browser has some OpenGL-physics bindings so you can easily visualize simulations.

To see it working, you can compile and run it with:

sudo apt build-dep libbullet-dev
git clone https://github.com/bulletphysics/bullet3
cd bullet3
git checkout 2.89
./build_cmake_pybullet_double.sh
./build_cmake/examples/ExampleBrowser/App_ExampleBrowser

Screenshot:

enter image description here

Tested on Ubuntu 20.04.

Example browser 2.83 code analysis

The Bullet example browser has moved away from the examples/ExampleBrowser/GL_ShapeDrawer.cpp by default, which uses outdated immediate OpenGL 2 methods. It can still be turned on depending on the value of the NO_OPENGL3 macro and command line arguments.

OpenGLWindow/GLInstancingRenderer.cpp is the new OpenGL 3 rendering centerpiece, and contains the glBindVertexArray call in GLInstancingRenderer::registerShape.

This method is indirectly called from OpenGLGuiHelper::autogenerateGraphicsObjects, which loops over the objects in the btDiscreteDynamicsWorld and generates a graphic version of those shapes.

The central part of the conversion seems to be OpenGLGuiHelper::createCollisionShapeGraphicsObjectInternal.

The color of the objects simply loops over 4 possible colors from OpenGLGuiHelper::sColors.

autogenerateGraphicsObjects is called from the initPhysics of several examples.

There are also some explicitly encoded cubes and spheres at: SimpleOpenGL3App.cpp, which can serve as a starting point if you want the possibility of graphics that differ from physics, as should be the case for every serious project: graphics should be more detailed, as they are less computationally expensive. Those are used only in a few examples.

If you are going to study the example browser, I recommend using an IDE with a debugger: it is too much indirection from my brain's static analysis. I've done this analysis with KDevelop4.