Java 3D scenegraph.io Extensibility

# Using your own Classes with scenegraph.io

The scenegraph.io APIs 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 unrecognized SceneGraphObject class is encountered is to traverse up the superclasses of the object until a recognized 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:

    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, 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 will have been lost.

To overcome this, the scenegraph.io API provides an interface for you to implement in your own classes that 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:

- createSceneGraphObjectReferences If your object has references to other SceneGraphObjects then you need to obtain an object reference (int) for each reference using the SceneGraphReferenceControl object passed as a parameter to this method. If you don't have references to other SceneGraphObjects then no action is required.

- saveChildren If your object is a subclass of Group and you want the scenegraph.io package to save the children then this must return true. If it returns false, the object will be saved but not its children.

- writeSceneGraphObject In this method you must write all the state information for your class, including the object references obtained in createSceneGraphObjectReferences, to the DataOutput stream passed into this method.

- readSceneGraphObject By the time this method is called your class has been instantiated and the state information in the Java3D superclass will have been loaded. You should load all the state information you saved for your class.

- restoreSceneGraphObjectReferences is called once all the SceneGraph objects have been loaded and allows you to restore the references to the other SceneGraph objects.

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

## Behavior Example

    public class BehaviorIO extends javax.media.j3d.Behavior implements SceneGraphIO
        private TransformGroup target;   // The TG on which 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();
        }

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

## `BlackBox' Group Example

This example is a Group node that creates its subgraph during its instantiation. An example where you might use this is to represent some geometry that 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;
>         }