The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

martymart (3) [Avatar] Offline
#1
I am currently trying to adapt your collision detection classes from your book Java3D programming. I want to implement a realistic collision response and thus need to calculate the collision normal. Therefore I need to be able to read the geometry of a Shape3D object so that I can get the surface normals which I have created in an IndexedQuadArray (see code below). The problem is no matter what capabilities I set I always get a javax.media.j3d.CapabilityNotSetException: Shape3D: no capability to get geometry error.

Here is the code:
Class where I create the scene:
.
.
.
private void addCube(Transform3D posOrien, Vector3d velocity, Matrix3d angularVel, String name){
Appearance app1 = new Appearance();

Color3f ambientColour1 = new Color3f(1.0f,0.0f,0.0f);
Color3f emissiveColour = new Color3f(0.0f,0.0f,0.0f);
Color3f specularColour = new Color3f(1.0f,1.0f,1.0f);
Color3f diffuseColour1 = new Color3f(1.0f,0.0f,0.0f);
float shininess = 20.0f;
Material m = new Material(ambientColour1,emissiveColour,diffuseColour1,specularColour,shininess);
m.setLightingEnable(true);
app1.setMaterial(m);

//Build the vertex array for the cubes. We can use the same
//data for each cube so we just define one set of data
IndexedQuadArray indexedCube = new IndexedQuadArray(8,
IndexedQuadArray.COORDINATES|IndexedQuadArray.NORMALS, 24);
indexedCube.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
indexedCube.setCapability(Shape3D.ALLOW_APPEARANCE_READ);

Point3f[] cubeCoordinates = { new Point3f( 1.0f, 1.0f, 1.0f),
new Point3f(-1.0f, 1.0f, 1.0f),
new Point3f(-1.0f,-1.0f, 1.0f),
new Point3f( 1.0f,-1.0f, 1.0f),
new Point3f( 1.0f, 1.0f,-1.0f),
new Point3f(-1.0f, 1.0f,-1.0f),
new Point3f(-1.0f,-1.0f,-1.0f),
new Point3f( 1.0f,-1.0f,-1.0f)};
Vector3f[] cubeNormals= {new Vector3f( 0.0f, 0.0f, 1.0f),
new Vector3f( 0.0f, 0.0f,-1.0f),
new Vector3f( 1.0f, 0.0f, 0.0f),
new Vector3f(-1.0f, 0.0f, 0.0f),
new Vector3f( 0.0f, 1.0f, 0.0f),
new Vector3f( 0.0f,-1.0f, 0.0f)};
int cubeCoordIndices[] = {0,1,2,3,7,6,5,4,0,3,7,4,5,6,2,1,0,4,5,1,6,7,3,2};
int cubeNormalIndices[] = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5};
indexedCube.setCoordinates(0, cubeCoordinates);
indexedCube.setNormals(0,cubeNormals);
indexedCube.setCoordinateIndices(0, cubeCoordIndices);
indexedCube.setNormalIndices(0, cubeNormalIndices);

Shape3D myCube = new Shape3D(indexedCube,app1);

TransformGroup cubeTG = new TransformGroup();

cubeTG.setTransform(posOrien);

myCube.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
myCube.setCapability(Shape3D.ALLOW_COLLISION_BOUNDS_READ);
cubeTG.addChild(myCube);

cubeTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
cubeTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
cubeTG.setCapability(TransformGroup.ALLOW_LOCAL_TO_VWORLD_READ);
cubeTG.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
cubeTG.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
cubeTG.setCapability(TransformGroup.ALLOW_BOUNDS_READ);

ObjProp objProp = new ObjProp(velocity, angularVel, name);

recursiveSetUserData(cubeTG, objProp);

sceneBG.addChild(cubeTG);

CollisionBehavior collisionBehavior = new CollisionBehavior(sceneBG, cubeTG);//sceneBG, sphereTg, app
collisionBehavior.setSchedulingBounds(bounds);

sceneBG.addChild(collisionBehavior);
}
.
.
.

Behaviour class:
public boolean isCollision( PickResult[] resultArray ){
.
.
.
if (cc != null && cc instanceof Shape3D){
if ( (((ObjProp)userData).getName()).equals( (String) objProp.getName() ) == false ) {
System.out.println("Home made cube");
Geometry geo = ((Shape3D)cc).getGeometry();
}
}
.
.
.
}

Does any one know what capabilities I need to set so that I can read the geometry.

Thank you Mr Selman

Message was edited by:
martymart
martymart (3) [Avatar] Offline
#2
Re: Read geomentry of Shape3D
I have tested reading the geometry in the first class above which is possible is I set the cabability to do so. But then I can not read the geometry in the the class that I pass the TransformGroup to no matter what I try. I even try setting all SceneGraphObjects capabilities recursivly in the class I pass the TransformGroup to.

Thanks again Martin
dselman (104) [Avatar] Offline
#3
Re: Read geomentry of Shape3D
Martin,

It looks like you are applying the capability to the TG, not to the Shape3D itself. The geometry read capability needs to be on the Shape3D you are trying to get the geometry info for.

Dan
martymart (3) [Avatar] Offline
#4
Re: Read geomentry of Shape3D
"Shape3D myCube = new Shape3D(indexedCube,app1);

TransformGroup cubeTG = new TransformGroup();

cubeTG.setTransform(posOrien);

myCube.setCapability(Shape3D.ALLOW_GEOMETRY_READ);"

I set the capability here, but once the TG is passed to the behaviour class I can not read it any more.