25 March 2009

Java3D and Eclipse

The world is not flat, and 3D maps is one of the latest hypes in navigation systems. (Is anybody using them for real, I wonder....)

So there is a need for me to deal with 3D city and terrain models in my applications, and of course the first thing you want is a 3D viewer. I started experimenting with Java3D a few months ago, and it felt such a relief compared to OpenGL programming in C. The only thing that gave me a hard time is the lack of documentation in some areas, but in the end I could answer most of my questions by studying the source code or by trial and error.

At first, I wrote a couple of stand-alone viewers with a Canvas3D embedded in an AWT Frame, but what I really need is Java3D embedded in an Eclipse view or editor.

I found a couple of postings on Java3D with SWT which sounded rather discouraging, but in the end it was rather straightforward. The java3d-eclipse project on Sourceforge gave me some useful hints, but I cannot recommend using it, since the way that it re-bundles the Java3D JARs is definitely not OSGi-compliant.

Now here is my own recipe:
  • Get the sources for Java3D 1.5.2 from https://java3d.dev.java.net. There is no source package, you have to use CVS. You need three subprojects: j3d-core, j3d-core-utils and vecmath.
  • Compile vecmath into a stand-alone OSGi bundle.
  • Follow the Java3D build instructions to build j3d-core and j3d-utils in one go, including some native library compilation and Java code generation.
  • j3d-core and j3d-core-utils mutually depend on each other and cannot be compiled separately, so I really don't understand why Sun created two libraries instead of one. Anyway, to be friendly to Maven and OSGi, I copied the original sources, the generated sources and the native library binaries to just one Maven project, created a POM and built my Java3D OSGi bundle using the maven-bundle-plugin.
  • I did this both for Windows and Linux and managed to launch the HelloUniverse demo from Equinox.
  • For cross-platform use, move the platform specific code (both the native libs and a handful of Java classes) to separate projects and build OSGi fragments for these, similar to SWT.
After these preparations, embedding a Canvas3D into an Eclipse view or editor is as easy as this:

public void createPartControl(Composite parent)
{
awtContainer = new Composite(parent, SWT.EMBEDDED);

Frame frame = SWT_AWT.new_Frame(awtContainer);
frame.setLayout(new BorderLayout());

GraphicsConfiguration config = SimpleUniverse
.getPreferredConfiguration();

Canvas3D canvas = new Canvas3D(config);

createUniverse(canvas);
frame.add(canvas, BorderLayout.CENTER);
}

No comments: