Back about three months ago, I announced on this blog that it was time for me to move on from jMonkeyEngine (jME) and work towards bringing to life a new, more professionally driven 3D Java engine. Three months is not a lot of time to create a better engine, but together with my good friends Rikard Herlitz and Petter Måhlén, I believe we now have something special to introduce to the world: Ardor3D.
Ardor3D began life as a fork from jME's com.jme and a few of the com.jmex packages. This was done for a few reasons:
- We felt there was a lot that was good code that could be reused.
- People (such as clients of Ardor Labs) use jME and it would be useful for porting to be as straightforward as possible.
- We could legally re-license the parts we had written ourselves (or wrote the majority of) to fit the Ardor3D license.
- Parts we could not relicense, we could rewrite or even just keep on the jME BSD license.
- the *.app package and everything under there. So the whole concept of *Game.
- the *.system package. So in other words, no more DisplaySystem.
- the *.input package. jME's input system was a jumbled mess.
Ok you're saying, enough about the purge. Tell me about the new stuff.
Math:
All of the basic math objects were rewritten as double precision and include the ability to be immutable. Added is a new Vector4 class, gone are several lesser used classes like Eigen. We are also now using a new Transform object in our scenegraph classes to represent, well, the transforms. What's particularly nice about the new math classes is that it makes handling macro and micro scale scenes and cameras in such scenes a lot easier and more stable.
RenderStates:
In Ardor3D you can new up your RenderState classes whenever and whereever you like. Instead of:
DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
how about:
new TextureState();
There are no implementation specific RenderStates to worry about, so the import/export process is much simpler as well and can be done in any thread without access to a Renderer or OpenGL binding.
Scenegraph and MeshData:
Instead of working with TriMesh, QuadMesh, SomeFunkyMeshICreated, etc. the scenegraph is nicely split into scenegraph classes (such as Node, Spatial and Mesh) and primitive data such as your vertices, indices, normals, etc. (encapsulated in a new MeshData class). This split makes it trivial to reuse mesh data in your scene (make two Meshes with different transforms and reuse the same meshdata object.)
MeshData stores one or more IndexModes that allow you to specify if the data inside is triangles, quads, strips, etc. I say one or more because you can also specify lengths, which are basically a way to say that given an IntBuffer for indices, the first X indices make up one draw call, the next Y make up another draw call, and so forth. Together with multiple IndexModes you can have a single Mesh that makes up a complex geometry (for example, a cylinder where the length is made up of a strip and the two end caps are triangle fans.)
Also of note, we have protected the SceneGraph objects a lot more from changes that it can not easily detect. Thus it is much more aware of changes to itself and able handle most normal updates itself. (In most cases you'll never have to remember to updateModelBounds, updateRenderStates, etc again.) Not only is this easier to use, but it has allowed us to skip a lot of excess computations during scene updates. A nice feature these changes allows for is event based notification when a scenegraph changes. You can attach a listener to your root node, for example, and use those updates events to decide to refresh the screen.
Rendering:
We flipped the concept of rendering. Instead of a monolithic Renderer that has to understand how to do the core rendering for all objects, now the logic for rendering an object lies in the object itself. The Renderer is simply a tool for you to use to get your rendering done, with available calls such as doTransforms, setupVertexData, drawElements, etc. This should allow for much wider range of custom scene objects.
Modularity, AWT and the core:
We've broken up our source to be standalone modules at the project level, keeping the core of Ardor3D nice and lean. It also has no AWT references which should make it easier to port to certain future platforms. The core supports loading TGA and DDS textures, and you can use AWT to load png, jpg, gif and bmp by making use of Ardor3D's extensions.
Canvas/Canvas Renderer and app:
With DisplaySystem gone, you still need a way to make windows and canvases. This is now accomplished in with a combination of Canvas which signifies where the GL context will be used (such as AwtCanvas, SwtCanvas, NativeCanvas) and CanvasRenderer, which is the tie to the OpenGL binding you are using to implement the rendering (Such as JoglCanvasRenderer and LwjglCanvasRenderer.) This is an area still heavily under construction, but we're happy with the results so far.
As I mentioned previously, gone are the app.*Game classes. Instead we have created a modular MVC system of Updater, View, and Scene interfaces with a Framework class that can be used to bring them together. These plug nicely into the CanvasRenderer. It may seem like a lot to pull together, but it's fairly simple and we have examples. We've also made it explicitly possible (although not necessary) to use Dependency Injection via Guice to do a lot of the setup for you.
Input:
As I mentioned, we've done away with jME's old input system. In its place is a new event based input system that nicely handles multiple rendering targets. Event trigger conditions use the Predicate interface from Google's collection package, allowing you to put together nice trigger conditions like "when the enter key is held down and I am dragging the mouse..." It's still somewhat of a work in progress and probably will change as we get new use cases. A replacement for FirstPersonHandler using this new system is already included in the core, and I've successfully used the new input package at Ardor Labs customers.
License:
Ardor3D is licensed under the zlib/libpng license. This is a permissive open source license that is also used by great game middleware such as Bullet.
Wrap up:
Our first public release is coming in a week or two and I hope this small taste has left you hungry to give Ardor3D a try. When you do, keep in mind that we are presently at release 0.2 and still have a ways to go before 1.0. Still, I think we've come a long way in three months and have some great things to show you!
Stay tuned, and Happy Holidays! :)

Post a Comment