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:

16 Comments Ogre + Bullet – Beginner’s Tutorial

  1. icoolriff

    Any chance that you would upload the code somewhere?
    And how did you config the Ogre and Bullet in Windows?
    Thanks!

    Reply
  2. csotiriou

    Hello, icoolriff,

    First of all, I did not set it up on Windows, I used OS X for that. But it should be relatively straightforward, since in all cases, you should use CMake to produce a project file of your favourite environment, open it, and build the necessary libraries. Then include these libraries to your new game project. That applies for both Ogre and Bullet. In my case, I can also install Bullet using MacPorts (which is similar to Linux’s apt-get) with no hassle.

    No matter what code I give you, it will not help you much. The Ogre Library produces libraries that are approximately 150 Mbytes (debug mode, OS X). Also, it has some Boost dependencies, that must also be included. Not to mention that these dependencies must be exactly compiled for the C++ STL library that you use. Personally, I used Clang with libc++ as standard library.

    As you can see, any code that I provide you with will cause you more problems that it will solve since the time it will take you to set up the dependencies for your system is honestly not worth the effort. From my code, the bits that you are actually going to use are the ones mentioned in the post.

    Reply
  3. metatomato

    Thanks for sharing an Ogre/Bullet Tutorial, as you mentioned it’s really difficult to find any on the web…
    Just a remark about your code… when you create a btBoxShape with a half-vector (50.f,50.f,50.f) it’s obvious that the top of your box will be at +50 on the Y-coordinate (bottom at -50), so you have to translate it to -50 to get the top at 0. You could try a btBox2DShape with (50.f,0.f,50.f) and so no need to translate.

    Reply
    1. csotiriou

      Thank you for this remark. I will try to update the code and test it. For the time being I will insert a comment about what you said, I am very sure it will help a lot of people.

      Reply
    2. csotiriou

      Thanks a lot for the feedback. I don’t have time to test it now actually, but I inserted an edit on the relevant paragraph, pointing to your comment. Thanks for sharing this.

      Reply
  4. Manpreet Singh

    metatomato already pointed this out, but I’d like to add that you can also use btStaticPlaneShape instead of box shape for the ground. You’re making a 100x100x100 box mesh which is why you have to translate it to get correct results. However, doing this

    groundShape = new btStaticPlaneShape(btVector3(0,1,0), 0);

    and setting the mass to 0 will work without any translation

    Reply
  5. Jacob

    What exactly is the content of “getCollisionObjectCount()”? I have no idea how I would start to make that. Everything else seems really clean and good, though. Thanks!

    Reply
    1. csotiriou

      As you may have noticed, I have built a physics engine wrapper object around the bullet engine. The function you mention is written by me, and returns the number of collidable objects added to the engine. This just returns a total counter that will help me iterate over the collision objects array.

      Reply
      1. Jacob

        Oh, that would make sense. I have it setup so now that I add a new rigid body to the world, I just increment an int variable (my counter). Seems to work well (besides the usual seg. faults). Thanks again for writing all this, it really helped!

        Reply
        1. csotiriou

          About the segfaults… I have experienced them, too. I found out that bullet have made a lot of optimizations to the engine, and they take advantage of the byte alignment in structs.

          Make sure that when compiling the library you also use the headers of this specific version of the library. Even a small decimal point can make a huge difference in stability.

          That was the problem in my case.

          Reply
          1. Jacob

            I get them when I try to step the simulation, and have tracked it down to this line of code: “colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);” in the function “btCollisionWorld::updateSingleAabb”

            I believe that my rigid bodies are going out of scope, as seen on this thread: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=5195

            Just gotta work with it a bit!

  6. seb

    Whate code of this tut is the function “physicsEngine->trackRigidBodyWithName(body, physicsCubeName);” ? Its possible to have the complete code of this tutorial ?

    Reply
  7. i7.Strelok

    It may be late to ask you or you may never read this message.
    I do not speak English but I will try to express myself correctly.
    Your tutorial is very well explained, but not complete.
    I would like to know what these objects are:
    physicsEngine I thought it was a”btDiscreteDynamicsWorld”

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *