Previously I’ve explored gdx’s 3d abilities at a lower level however there is a much higher level route into the API (you can always use lower level techniques alongside, so its win – win!)
As usual I’m assuming general familiarity with gdx and focusing solely on areas that are potentially troublesome or indeed interesting…
The only tutorial I was able to find for the 3d side of things was at http://blog.xoppa.com/basic-3d-using-libgdx-2/ I used this as the basis for my investigation of bullet, I haven’t bothered with gdx’s own 3d format (funny how every 3d framework seems to need their own!) as it seems to rely on some proprietary toolkit – so I got scared and ran away :o) …
Its probably worth you reading this tutorial as well as its well written and unlike the gdx tests it doesn’t rely on multiple levels of abstraction and is all contained in the one class, so its much easier to learn from.
Being high level once you work out how the API is intended to be used, its rather simple and just a small number of calls later you have a 3d scene up and running.
I won’t spend much time on the 3d api as from the linked tutorial and the source (below) you should be able to easily follow whats going on – there really is no great drama here and I didn’t stumble on any particular gotchas.
You have to be much more careful where it comes to bullet, its a very thin swig wrapper there are a few things to bare in mind.
Return values – gdx bullet often reuses the same objects to return a value, for example if you get a vector from bullet, use this vector to set your own vector or strange things will happen !
myVector.set( body.someVectorReturningBulletMethod() );
There is a couple of sections in the wiki about this that is well worth a read
https://code.google.com/p/libgdx/wiki/PhysicsBullet#Common_classes and https://code.google.com/p/libgdx/wiki/PhysicsBullet#Creating,_destroying_and_referencing_objects
I chose to separate out the main of the bullet code into a separate physics object class, in the main class we only deal with creating the physics world and creating our physics objects.
Although world creation looks complex you can treat the code as boiler plate and just use is as is, bullet is very modular and flexible but initially you need not worry about the details … (I bet most people don’t – still its nice to have that flexibility there if needed)
Lets take a closer look at the physics object class as thats where the interesting stuff happens…
before we can use the class we have to set up a few static values…
physObj.boxTemplateModel = cube;
physObj.ballTemplateModel = ball;
physObj.collisionWorld = collisionWorld;
Physics objects can either be boxes (cubes) of different size along each axis (width, height and depth) or a balls of differing radius, Wavefront obj files are used to define the mesh templates for the ball and cube, the physObj class also needs a reference to the bullet physics world space so it can add objects into our simulation.
The object creation is in the form of
public physObj(pType tp, Vector3 sz, float mass,final Matrix4 transform)
pType tp – can be either physObj.pType.BOX or physObj.pType.SPHERE
Vector3 sz – is the size (y & z are ignored for spheres)
float mass – the mass of an object, if this is set to zero the object is stationary regardless of what collides with it
Matrix4 transform – this is used to initially orient the physics object giving it a position and rotation
The key to the physics object is the way bullet communicates the orientation and position of the physics body. To do this it uses a motion state, all this basically does is hold what is in effect a model view matrix. I’m abusing it (slightly) to also scale the template meshes. As the motion state matrix is a reference to the matrix that the model uses for rendering, when displaying the model there is no need to refer to bullet for the position and orientation as its already filled in that information for us. This is an obvious enough thing to do but not all physics libraries do this…
As far as physics objects are concerned the difference between a sphere and box are fairly trivial, equally trivial would be to add another bullet primitive shape such as a capsule for example. However static (stationary) objects are a little more interesting. A motion state is not needed (in fact using one causes it to stop working!) one thing we do need to do is position the physics body as there is not a motion state to give the initial orientation and position. The shapes inertia also needs to be zero’d like the mass for a static body.
All in the main class is less than 200 lines, the physics object class is less than 100 lines, ok its just a bunch of random shapes hitting a few static objects, but having said that it fast and reasonably easy to follow…
Once you’ve perused the wiki links and tutorial I’ve mentioned, have a look at the attached source code, things to try – add support for a bullet capsule, or even if you’re real ambitious add a static terrain mesh (not actually as hard as you’d think…)