Loaders: how to set capabilities of the scene

So I am trying to do terrain following and later on collision avoidance. Well, I use loaders to construct all of my objects. The specific one is the VRML loader.

Anyways, how do you set capabilities to the Shape3D objects that the loader creates. The loader returns a scene, so how do you get down to the terminals of the scene to get to the Shape3D so that you can set capabilities like ALLOW_GEOMETRY_READ.

Thanks

So I think I came up w/ a method to attack this problem (I haven’t tested this out yet though). You get the scene from the loader, get the BranchGroup and then get all the children of the BG. Once you get the enum, then you can set the capabilities of each object. The only thing is, all these objects must be Shap3D for this to work out. I’m not sure if this is always the case. Below is some code to go w/ it. Any suggestions?

    Scene s = loader.load(fileName);

     //Here we go - lets get all objects out of sceen
     BranchGroup bg = s.getSceneGroup();

     Enumeration enum1 = bg.getAllChildren();

     while(enum1.hasMoreElements()){
        shape = (Shape3D)enum1.nextElement();
        shape.setCapability(<whatever capability you want);
      }

It’s the right approach, but instead of assuming that each Node in the graph is a Shape3D, you should get it out of the Enumeration as a Node, and then check to see if it an instanceof Shape3D before forcing the cast.

At least that way you won’t get a ClassCastException at runtime!!

You will want to also check for Group nodes, because then you will want to iterate through all of the children of the sub-group. I believe most of the VRML Loaders support nested Groups.

Here’s an example SceneGraph to illustrate:


BranchGroup
+-- Shape3D
+-- Shape3D
+-- TransformGroup
      +-- Shape3D
      +-- Shape3D
      +-- TransformGroup
            +-- Shape3D
       +-- TransformGroup
            +-- Shape3D
+--  etc, etc, etc...

I am doing exactly the same thing in a ModelManager class, which supports loading several different types of Loaders (OBJ, VRML, and 3DS for now).

Yep, what you said worked. Here is the code I am using to get through all the nodes of the scene for those of you who are interested.

So you will want to call this function inside of the while loop in the above post.

private void setCapabilities(Node node){
if(node.getClass().getName().equals(“javax.media.j3d.Shape3D”)){
Shape3D shape = (Shape3D)node;
shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
Geometry geom = shape.getGeometry();
geom.setCapability(GeometryArray.ALLOW_COORDINATE_READ); geom.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ);
geom.setCapability(IndexedGeometryArray.ALLOW_FORMAT_READ);
geom.setCapability(IndexedGeometryArray.ALLOW_COUNT_READ);
}
else if(node.getClass().getName().equals(“javax.media.j3d.BranchGroup”)){
Enumeration enum2 = ((BranchGroup)node).getAllChildren();
while(enum2.hasMoreElements()){
setCapabilities((Node)enum2.nextElement());
}
}
else if(node.getClass().getName().equals(“javax.media.j3d.TransformGroup”)){
Enumeration enum2 = ((TransformGroup)node).getAllChildren();
while(enum2.hasMoreElements()){
setCapabilities((Node)enum2.nextElement());
}
}
else if(node.getClass().getName().equals(“javax.media.j3d.Group”)){
Enumeration enum2 = ((Group)node).getAllChildren();
while(enum2.hasMoreElements()){
setCapabilities((Node)enum2.nextElement());
}
}
}