Using your own Classes with scenegraph.io

The scenegraph.io API's will handle the IO for all the core Java3D SceneGraphObjects. However if you create a subclass of one of these objects and add it to your Scene Graph the IO system, by default, will not store any state information specific to your class.

The default behavior when an unrecognised SceneGraphObject class is encountered is to traverse up the superclasses of the object until a recognised Java3D class is located. The data structures for this class are then used for IO. The system does store the class name of the original object.

For example, if I create a class with thus

public class MyBranchGroup extends javax.media.j3d.BranchGroup {

private int myData;

....

}

When the Scene Graph is written to a file and this node is encountered the superclass javax.media.j3d.BranchGroup will be used to store all the state for the object so any children of MyBranchGroup and the capabilities etc will be stored but myData will be lost. When the scene graph is loaded MyBranchGroup will be instantiated and will be populated with all the state from BranchGroup but myData has been lost.

To overcome this the scenegraph.io API provides an interface which you can implement in your own classes which provides the opportunity for you to save the state of your classes during the IO processes. This is the SceneGraphIO interface.

When the scenegraph is saved, the methods of SceneGraphIO are called in this order

  1. createSceneGraphObjectReferences

  2. saveChildren

  3. writeSceneGraphObject

During the load cycle the method call order is

  1. Instantiate Object using default constructor

  2. Populate object with state from superclasses

  3. readSceneGraphObject

  4. restoreSceneGraphObjectReferences



Within each method you need to perform the following actions

Here are some examples, only the parts of the source pertaining to IO are show....

Behavior

public class BehaviorIO extends javax.media.j3d.Behavior implemented SceneGraphIO

private TransformGroup target; // The TG onwhich this behavior acts

private int targetRef; // Object Reference for target

public void createSceneGraphObjectReferences( SceneGraphObjectReferenceControl ref ) {

targetRef = ref.addReference( target );

}

public void restoreSceneGraphObjectReferences( SceneGraphObjectReferenceControl ref ) {

target = (TransformGroup)ref.resolveReference( targetRef );

}

public void writeSceneGraphObject( java.io.DataOutput out ) throws IOException {

out.writeInt( targetRef );

}

public void readSceneGraphObject( java.io.DataInput in ) throws IOException {

targetRef = in.readInt();

}

public boolean saveChildren() { // This has no effect as this is not a subclass of Group

return true;

}



'BlackBox' Group

This example is a Group node which creates it's subgraph during it's instantiation, an example where you might use this is to represent some geometry which is loaded from an external file format such a OpenFLT.

public class House extends Group implements SceneGraphIO

public House() {

super();

this.addChild( OpenFlightLoader.load( "/dir/house.flt" );

}

public void createSceneGraphObjectReferences( SceneGraphObjectReferenceControl ref ) {

// No references

}

public void restoreSceneGraphObjectReferences( SceneGraphObjectReferenceControl ref ) {

// No references

}

public void writeSceneGraphObject( java.io.DataOutput out ) throws IOException {

// No local state

}

public void readSceneGraphObject( java.io.DataInput in ) throws IOException {

// No local state

}

public boolean saveChildren() {

// Don't save the children as they will be restored by the openflightloader

return false;

}