Ogre + Bullet – Beginner’s Tutorial

Lately, I have been testing my skills with Ogre3D, a 3D rendering engine written in C++, and Bullet physics, which is used in many commercial games to give realistic movement and feel to movable objects in the world. I was amazed to see that there is actually not a comprehensive tutorial on how to use Bullet with Ogre3D.

There is a library, called OgreBullet, but I didn’t want to use that, because I have had some problems compiling it for OS X. Moreover, frameworks such as these link against Ogre, and many times things get messy if you try to compile the latest version of Ogre3D from their mercurial repository, since the latest version may differ from the stable one, and OgreBullet functions may not find what they expect in both frameworks.

Anyway, without priding myself of being an expert in Bullet or Ogre3D, I would like to give to others my findings on the matter, and help them implement basic Bullet functionality to their Ogre projects, while explaining how Bullet physics works in general.

What is “Bullet physics”? Bullet Physics is a cross-platform framework for implementing realistic physics and collision detection into games and simulation applications. It is written in C++, and it is compatible with many game engines, Ogre3D being one of them. Prerequisites First of all, let me clarify that the method of installation is depended on your platform, and I will not talk about installing the library in this post. This post assumes that you have the following:

  • A compiled and working Ogre3D installation in your system. The headers should be in the correct header search path
  • A compiled and working Bullet Physics installation in your system. The headers should be already in the correct path
  • A new project, ready to write code, in the tool of your choice. I used Xcode on OS X for this post, but I will stay as cross-platform as possible.
  • A basic understanding of Ogre3D concepts.
  • C++ knowledge (duh!)

How does it work? Bullet physics works as an intermediate layer between your rendering process and your game logic. The process of actually implementing physics into actual actors in your Ogre3D application is the following:

  1. Define a world in Bullet physics. The gravity, global physics object properties, etc.
  2. Create an Ogre::Entity. The height and width of the entity should be known.
  3. Attach the entity to a Node, as you would normally.
  4. Create a bullet physics entity, and assign it the initial properties, in terms of physics, and location/rotation. You must also define its shape (cube, triangle, custom object, etc) and its initial inertia.
  5. Create the physics entity to the Ogre Node you just create it. How you do this to associate them is up to you. Bullet has a “setUserPointer()” method to the rigid body, for your convenience, but you can place the associations in an std::map if you want. For this example, we use the first approach, for the sake of clarity.
  6. Add the new physics entity to the world you created in step 1.
  7. When the items are all added to the Ogre’s scene graph, and associated with Bullet’s objects, we can call the btDynamicsWorld::stepSimulation() function, with a delta number. This will move the simulation according to the physics and the collision properties. For Ogre, the best location for that to happen is the function that is implemented by the “Ogre::FrameListener” class (your class).
  8. Now, iterate through all btRigidBodies of the btDynamicsWorld you created in step 1, get their new position and rotation, and apply these to the Ogre::Nodes that you have added to the scene.

Time to code the things!

I will only give sample code. It is up to you to adapt it to your needs, and replace the meshes and materials mentioned in this post with your own. I would give my actual code, if I could, but the architecture of an application such as this is so subjective and uniquely tied to each implementation, that I don’t want to point anyone in a direction that would cause him/her problems afterwards. So, we have the following properties, inside a class called “Physics”. A “Physics” instance is included by my Ogre::Framelistener subclass (which also implements my game logic)

We initialise the objects in a function of our choice. That could be a constructor or a function called elsewhere.

That has created a dynamic world ready to accept our objects in it.

For most applications, the first thing they have to do is to create a floor, where objects and characters will step on. For this example, we will create a basic plane.

Notice that I set the origin of the bullet physics ground to be at -50.0f, which is different than the one used for the Ogre plane. This “magic number” came out a lot of experimentation and trial and error. Until this day, I still cannot understand why this has to be different. I just hope that someone smarter than me will be able to explain to me, when he reads this tutorial. For now on, let’s accept it as it is. EDIT “metaltomato” was kind enough to share his solution to this problem. Look at the comments below the article. Thanks a lot to ‘metaltomato’ for providing feedback on this.

Now, at any part of our application, we want to create a simple cube, and add it to out world.

Last but not least, comes the code that has to be inserted into the “FrameStarted()” function. We iterate through each rigid body of the scene, we get the associated note, and we update its rotation and position according to the rotation and position of the rigid body.

 

Following this method, I have been able to produce the following result:

Of course, in the above video, there is an scripting system, and I have created a script using this system that creates cubes in random places. But the logic is the same as the one I am presenting here.

If you have any comments or questions, feel free to share them in the comment section below.

Happy coding!

LINKS: