Dear Peter, I have worked out a solution for this problem:-) But on M$\'s windows2000 platform, not Linux(Are you linux guy?I like it either, but I have to work this project on Windows. Maybe we can discuss Linux later, surely not in this mailing list) What I do is putting all my colllision behaviors into a BranchGroup, and attach this BranchGroup into the scene. When I want to detach the scene from root, I will detach this collision behavior branchGroup first, after this detach, sleep the thread for a very short period of time, then come to what I relly want to do, detaching the scene\'s root. It works!! Below is the revised test program, maybe you can try it out. Good luck. Hope this trick works fine on your machine&platform.
-----BEGIN OF CODE----- /* * testCollision.java * * Created on October 17, 2002, 11:39 PM */ import javax.media.j3d.*; import java .awt.*; import javax.vecmath.*; /** * * @author Peter Antoniac */ public class testCollision extends javax.swing.JFrame { public testCollision() { super("Testing Collision removal"); setSize(300,400); getContentPane().setLayout(new java.awt.BorderLayout()); setBackground(new java.awt.Color(255, 255, 255)); setName("Testing Window"); // Create the 3D Objects pGTmpl3D = new GraphicsConfigTemplate3D(); pGConf = getGraphicsConfiguration(); pGDev = pGConf.getDevice(); pCanvas3D = new Canvas3D(pGTmpl3D.getBestConfiguration(pGDev.getConfigurations())); getContentPane().add(pCanvas3D); setVisible(true); pUniverse = new VirtualUniverse(); pLocale = new Locale(pUniverse); pView = new View(); pVPlatform = new ViewPlatform(); pBGroup_0 = new BranchGroup(); pTGroup_0 = new TransformGroup(); /** * Construct the ViewBranch */ pView.addCanvas3D(pCanvas3D); pView.setPhysicalBody(new PhysicalBody()); pView.setPhysicalEnvironment(new PhysicalEnvironment()); pTGroup_0.addChild(pVPlatform); pBGroup_0.addChild(pTGroup_0); pLocale.addBranchGraph(pBGroup_0); pView.attachViewPlatform(pVPlatform); /** * Creating the Content Branch including the Collision... */ pBGroup_1 = new BranchGroup(); pTGroup_1 = new TransformGroup(); // Capabilities settings pBGroup_1.setCapability(BranchGroup.ALLOW_DETACH); // this is for debugging only! pBGroup_1.setCapability(BranchGroup.ALLOW_CHILDREN_READ); /** this is for moving the node * pTGroup_1.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ); * pTGroup_1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); * pTGroup_1.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); * pTGroup_1.setCapability(Group.ALLOW_CHILDREN_EXTEND); */ pTGroup_1.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND); pTGroup_1.setCapability(TransformGroup.ALLOW_CHILDREN_READ); pTGroup_1.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE); pAppearance = new Appearance(); pAppearance.setMaterial(new Material( new Color3f(1,0,0), //ambient color new Color3f(1,0,0), //emisive color new Color3f(1,0,0), //difuse color new Color3f(1,1,1), //specular color 100f)); pBox=new com.sun.j3d.utils.geometry.Box(0.2f,0.2f,0.2f,pAppearance); pT3D_0 = new Transform3D(); pT3D_1 = new Transform3D(); pT3D_0.setTranslation(new Vector3d(0,0,-4)); pT3D_1.rotX(Math.PI/4); pT3D_0.mul(pT3D_1); pTGroup_1.setTransform(pT3D_0); pTGroup_1.addChild(pBox); pBGroup_1.addChild(pTGroup_1); // Setting the collision object pCHandle=new CollisionHandler(pTGroup_1); pCHandle.setSchedulingBounds(new BoundingSphere(new Point3d(0,0,0),0.4d)); pBGroup_2 = new BranchGroup(); pBGroup_2.setCapability(BranchGroup.ALLOW_DETACH); pBGroup_2.addChild(pCHandle); pBGroup_1.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); pBGroup_1.addChild(pBGroup_2); // Live pLocale.addBranchGraph(pBGroup_1); // setResizable(false); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); pCanvas3D.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent e) { switch (e.getKeyChar()) { case \'P\': case \'p\': if (!pBGroup_1.isLive()){ System.out.println("Placing the box"); pLocale.addBranchGraph(pBGroup_1); } break; case \'R\': System.out.println("R"); pBGroup_2.detach(); try{ Thread.sleep(10); }catch(Exception ex){} pBGroup_1.detach(); break; case \'r\': pBGroup_1.detach(); if (pBGroup_1.isLive() &&pCHandle.isLive()){ System.out.println("Removing the box"); // Using Locale.removeBranchGraph or detach has the same effect! :(( // pLocale.removeBranchGraph(pBGroup_1); pBGroup_1.detach(); } break; default: System.out.println("Wrong key. Press P or R keys!"); } } }); pCanvas3D.requestFocus(); pack(); } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } /** * @param args the command line arguments */ public static void main(String args[]) { new testCollision().show(); } // Variables declaration private VirtualUniverse pUniverse; private Canvas3D pCanvas3D; private Locale pLocale; private View pView; private ViewPlatform pVPlatform; private TransformGroup pTGroup_0,pTGroup_1; private BranchGroup pBGroup_0,pBGroup_1, pBGroup_2, pBGroup_3; private Transform3D pT3D_0,pT3D_1; private Appearance pAppearance; private com.sun.j3d.utils.geometry.Box pBox; private GraphicsConfigTemplate3D pGTmpl3D; private GraphicsDevice pGDev; private GraphicsConfiguration pGConf; private CollisionHandler pCHandle; class CollisionHandler extends Behavior { /** Creates a new instance of CollissionHandler */ public CollisionHandler(Node pNode) { armingNode(pNode); } /** Initialize should be call after armingNode! Best practice is to first set the node * and later to add the object to the scenegraph */ public void initialize() { wakeupOn(pWOr); } public void processStimulus(java.util.Enumeration e) { System.out.println("Debug collision: BINGO!"); while(e.hasMoreElements()){ WakeupCriterion pWCriterion = (WakeupCriterion) e.nextElement(); if (pWCriterion instanceof WakeupOnCollisionEntry){ //something } else if (pWCriterion instanceof WakeupOnCollisionExit){ //something else } } // set next WakeupCriterion wakeupOn(pWOr); } void armingNode(Node pNode) { aWCriteria[0]= pWUEnter = new WakeupOnCollisionEntry(pNode,WakeupOnCollisionEntry.USE_GEOMETRY); aWCriteria[1]= pWUExit = new WakeupOnCollisionExit(pNode,WakeupOnCollisionExit.USE_GEOMETRY); pWOr=new WakeupOr(aWCriteria); } private WakeupCriterion[] aWCriteria = new WakeupCriterion[2]; private WakeupOr pWOr; private WakeupOnCollisionEntry pWUEnter; private WakeupOnCollisionExit pWUExit; } } -------------END OF CODE-------------------