0001: /*
0002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/scenegrapheditor/SceneGraphControl.java,v 1.4 2007/06/01 21:52:29 paulby Exp $
0003: *
0004: * Sun Public License Notice
0005: *
0006: * The contents of this file are subject to the Sun Public License Version
0007: * 1.0 (the "License"). You may not use this file except in compliance with
0008: * the License. A copy of the License is available at http://www.sun.com/
0009: *
0010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
0011: * The Initial Developer of the Original Code is Paul Byrne.
0012: * Portions created by Paul Byrne are Copyright (C) 2002.
0013: * All Rights Reserved.
0014: *
0015: * Contributor(s): Paul Byrne.
0016: *
0017: **/
0018: package org.jdesktop.j3dedit.scenegrapheditor;
0019:
0020: import java.io.File;
0021: import java.io.IOException;
0022: import java.io.ObjectInputStream;
0023: import java.io.BufferedInputStream;
0024: import java.net.URL;
0025: import java.util.HashMap;
0026: import java.util.Vector;
0027: import java.util.Enumeration;
0028:
0029: import javax.swing.JOptionPane;
0030: import javax.swing.ProgressMonitor;
0031: import java.util.ArrayList;
0032:
0033: import javax.media.j3d.*;
0034: import javax.vecmath.Color3f;
0035: import javax.vecmath.Vector3f;
0036: import com.sun.j3d.utils.behaviors.interpolators.RotPosScaleTCBSplinePathInterpolator;
0037: import com.sun.j3d.utils.scenegraph.io.SceneGraphFileWriter;
0038: import com.sun.j3d.utils.scenegraph.io.UnsupportedUniverseException;
0039: import org.jdesktop.j3d.utils.scenegraph.EncapsulatingGroup;
0040: import org.jdesktop.j3d.utils.scenegraph.traverser.TreeScan;
0041: import org.jdesktop.j3d.utils.scenegraph.traverser.NodeChangeProcessor;
0042: import org.jdesktop.j3dfly.utils.loadercontrol.LoaderControl;
0043: import org.jdesktop.j3dfly.utils.loadercontrol.LoaderControlListener;
0044: import org.jdesktop.j3dfly.utils.loadercontrol.UnsupportedFormatException;
0045: import org.jdesktop.j3dfly.utils.gui.WorkingDialog;
0046: import org.jdesktop.j3dfly.utils.developmenttools.DevelopmentLocale;
0047: import org.jdesktop.j3dedit.scenegrapheditor.treeview.TVObject;
0048: import org.jdesktop.j3dedit.J3dEditContext;
0049:
0050: import org.jdesktop.j3dfly.namecontrol.NameControl;
0051: import org.jdesktop.j3dedit.scenegraph.SGGeometry;
0052: import org.jdesktop.j3dedit.scenegraph.SGLink;
0053: import org.jdesktop.j3dedit.scenegraph.SGGeometryPrimitive;
0054: import org.jdesktop.j3dedit.scenegraph.SGTransparencyAttributes;
0055: import org.jdesktop.j3dedit.scenegraph.SGNodeComponent;
0056: import org.jdesktop.j3dedit.scenegraph.SGLoader;
0057: import org.jdesktop.j3dedit.scenegraph.SGBehavior;
0058: import org.jdesktop.j3dedit.scenegraph.SGLeaf;
0059: import org.jdesktop.j3dedit.scenegraph.SGPolygonAttributes;
0060: import org.jdesktop.j3dedit.scenegraph.SGLocale;
0061: import org.jdesktop.j3dedit.scenegraph.SGPointAttributes;
0062: import org.jdesktop.j3dedit.scenegraph.SGTexture;
0063: import org.jdesktop.j3dedit.scenegraph.SGTextureAttributes;
0064: import org.jdesktop.j3dedit.scenegraph.SGTransformInterpolator;
0065: import org.jdesktop.j3dedit.scenegraph.SGBranchGroup;
0066: import org.jdesktop.j3dedit.scenegraph.SGObject;
0067: import org.jdesktop.j3dedit.scenegraph.SGNode;
0068: import org.jdesktop.j3dedit.scenegraph.SGAppearance;
0069: import org.jdesktop.j3dedit.scenegraph.SGGroup;
0070: import org.jdesktop.j3dedit.scenegraph.SGInterpolator;
0071: import org.jdesktop.j3dedit.scenegraph.SGMaterial;
0072: import org.jdesktop.j3dedit.scenegraph.SGShape3D;
0073:
0074: /**
0075: * @author Paul Byrne
0076: * @version $Id: SceneGraphControl.java,v 1.4 2007/06/01 21:52:29 paulby Exp $
0077: *
0078: * Maintains consitancy between Java3D scene graph and the
0079: * users view of the graph
0080: */
0081: public class SceneGraphControl
0082: implements
0083: org.jdesktop.j3dfly.utils.developmenttools.SceneGraphChangeListener {
0084: // com.sun.j3d.demos.utils.loadercontrol.LoaderControlListener {
0085:
0086: private SGGroup viewRoot;
0087: private ArrayList viewRoots = new ArrayList();
0088: private HashMap nodeMapping; // Mapping of Java3D nodes to the SGObject nodes that represent them
0089: private HashMap localeMapping;
0090: private HashMap componentMapping; // Mapping of Java3D node components to the SGObject nodes
0091:
0092: private Vector postProcess; // List of nodes that require post processing once
0093: // scenegraph view construction is complete
0094: private J3dTreePanel treePanel = null;
0095: private LoaderControl loaderControl = null;
0096:
0097: private TreeIconControl treeIconControl = null;
0098:
0099: private NameControl nameControl = null;
0100:
0101: private TreeViewFactory treeViewFactory = new org.jdesktop.j3dedit.scenegrapheditor.treeview.DefaultTreeViewFactory();
0102:
0103: /**
0104: * The Editor Context for this Controller
0105: */
0106: private J3dEditContext context;
0107:
0108: /**
0109: * Create a new SceneGraphControl object.
0110: *
0111: * The new object adds itself to the context
0112: */
0113: public SceneGraphControl(J3dTreePanel treePanel,
0114: J3dEditContext context) {
0115: this .treePanel = treePanel;
0116: this .context = context;
0117: nodeMapping = new HashMap();
0118: localeMapping = new HashMap();
0119: componentMapping = new HashMap();
0120: postProcess = new Vector();
0121: context.setSceneGraphControl(this );
0122:
0123: treeIconControl = context.getConfigLoader()
0124: .getTreeIconControl();
0125:
0126: createLocale(context.getLocale());
0127: }
0128:
0129: /**
0130: * Delete all BranchGraphs except VisualTools and ViewingPlatform
0131: */
0132: /*
0133: private void deleteSceneGraph() {
0134: if (context.getLocale().getBranchGraphs()==null) return;
0135: BranchGroup[] graphs = context.getLocale().getBranchGraphs();
0136: for(int i=0; i<graphs.length; i++) {
0137: if (!(graphs[i] instanceof com.sun.j3d.utils.universe.ViewingPlatform))
0138: context.getLocale().removeBranchGraph( graphs[i] );
0139: }
0140: }
0141: */
0142:
0143: public void prepareToSave() {
0144: setupEditorPersistanceAndRestoreCapabilities((SGObject) viewRoot);
0145: }
0146:
0147: public void saveComplete() {
0148: System.out.println("Setting Cap");
0149: setEditorCapabilities(viewRoot);
0150: }
0151:
0152: /**
0153: * Save the scene graph
0154: */
0155: public void saveSceneGraph(File file) {
0156: //boolean wasLive = WindowManager.getManager().getDevelopmentLocale().getLive();
0157: //if (wasLive)
0158: // WindowManager.getManager().getDevelopmentLocale().setLive( false );
0159:
0160: System.out.println("SceneGraphControl.saveSceneGraph");
0161:
0162: setupEditorPersistanceAndRestoreCapabilities((SGObject) viewRoot);
0163: try {
0164: SceneGraphFileWriter writer = new SceneGraphFileWriter(
0165: file, null, false, "J3dEditor", null);
0166: for (int i = 0; i < context.getLocale().getBranchGraphs().length; i++) {
0167: if (!(context.getLocale().getBranchGraphs()[i] instanceof com.sun.j3d.utils.universe.ViewingPlatform)) {
0168: System.out.println("Written Graph "
0169: + context.getLocale().getBranchGraphs()[i]);
0170: writer.writeBranchGraph(context.getLocale()
0171: .getBranchGraphs()[i]);
0172: }
0173: }
0174:
0175: writer.close();
0176: } catch (IOException e) {
0177: saveError(e);
0178: } catch (UnsupportedUniverseException uue) {
0179:
0180: }
0181:
0182: System.out.println("Reseting ALLOW_DETACH");
0183: // Set capabilities back to values required for current Editor mode
0184: for (int i = 0; i < context.getLocale().getBranchGraphs().length; i++) {
0185: context.getLocale().getBranchGraphs()[i]
0186: .setCapability(BranchGroup.ALLOW_DETACH);
0187: }
0188:
0189: //if (wasLive)
0190: // WindowManager.getManager().getDevelopmentLocale().setLive( true );
0191: }
0192:
0193: public SGObject getViewRoot() {
0194: return viewRoot;
0195: }
0196:
0197: public void setSceneGraph(J3dEditContext context) {
0198: boolean foundVisualTools = false;
0199: this .context = context;
0200:
0201: //deleteSceneGraph();
0202:
0203: context.getLocale().addGraphChangeListener(this );
0204:
0205: createUserViewForLocale(context.getLocale());
0206: }
0207:
0208: /**
0209: * Update the view of the scene graph by re-traversing the branchgraphs
0210: */
0211: public void updateSceneGraph() {
0212: boolean wasLive = context.getLocale().getLive();
0213:
0214: if (wasLive)
0215: context.getLocale().setLive(false);
0216:
0217: createUserViewForLocale(context.getLocale());
0218:
0219: if (treePanel != null) {
0220: treePanel
0221: .setTree((org.jdesktop.j3dedit.scenegrapheditor.treeview.TVObject) viewRoot
0222: .getTreeViewObject());
0223: treePanel.layoutTree();
0224: treePanel.repaint();
0225: }
0226:
0227: if (wasLive)
0228: context.getLocale().setLive(true);
0229: }
0230:
0231: /**
0232: * Returns the SGObject that represents the scene graph node
0233: */
0234: public SGObject getTreeNode(SceneGraphObject obj) {
0235: return (SGObject) nodeMapping.get(obj);
0236: }
0237:
0238: /**
0239: * Returns the SGObject that represents the locale
0240: */
0241: public SGObject getLocaleNode(DevelopmentLocale obj) {
0242: return (SGObject) localeMapping.get(obj);
0243: }
0244:
0245: /**
0246: * Returns the SGObject that represents the scene graph node component
0247: */
0248: public SGObject getTreeNodeComponent(SceneGraphObject obj) {
0249: return (SGObject) componentMapping.get(obj);
0250: }
0251:
0252: /**
0253: * Add the child to the graph structures and set the childs
0254: * capability bits
0255: */
0256: public synchronized void addChild(SGGroup parent,
0257: javax.media.j3d.Node child, boolean autoName) {
0258: if (parent == null) {
0259: System.err.println("ERROR - null parent");
0260: return;
0261: }
0262:
0263: postProcess.clear();
0264: SGNode newGraph = traverseGraph(child);
0265: postProcessNodes();
0266:
0267: ((TVObject) newGraph.getTreeViewObject())
0268: .setContainer(((TVObject) parent.getTreeViewObject())
0269: .getContainer());
0270: setEditorCapabilities(newGraph);
0271: parent.addChild(newGraph);
0272:
0273: if (child.getName() == null && autoName) {
0274: String name = NameGenerator.getNameControl().getName(child);
0275: context.getNameControl().addObject(parent.getSceneName(),
0276: name, // New name
0277: child);
0278: newGraph.setNodeName(name);
0279: }
0280: }
0281:
0282: public void removeChild(SGGroup parent, SGNode child) {
0283: System.out.println("TODO - implement removeChild");
0284: }
0285:
0286: /**
0287: * Add this node component to the Object tracking system
0288: *
0289: * This is called automatically by the SGNodeComponent constructor
0290: */
0291: public void addNodeComponent(SGNodeComponent nodeComponent) {
0292: if (nodeComponent.getJ3dNode() == null)
0293: throw new RuntimeException(
0294: "SGNodeComponent must reference a node component in the scene graph");
0295: componentMapping.put(nodeComponent.getJ3dNode(), nodeComponent);
0296:
0297: //System.out.println("SceneGraphControl.addNodeComponent Component Added "+nodeComponent+" "+componentMapping.size() );
0298: }
0299:
0300: /**
0301: * Remove the node component, this is called automatically when the
0302: * reference count of an SGNodeComponent==0
0303: *
0304: * nodeComponent.getJ3dNode() MUST be non-null otherwise a RuntimeException
0305: * will be thrown.
0306: */
0307: public void removeNodeComponent(SGNodeComponent nodeComponent) {
0308: //System.out.println("Removing "+nodeComponent);
0309: if (nodeComponent.getJ3dNode() == null) {
0310: throw new RuntimeException(
0311: "SGNodeComponent must reference a node component in the scene graph "
0312: + nodeComponent);
0313: }
0314: if (nodeComponent.getReferencedByCount() != 0)
0315: throw new RuntimeException(
0316: "Attempt to remove SGNodeComponent that is still referenced");
0317: componentMapping.remove(nodeComponent.getJ3dNode());
0318: }
0319:
0320: /**
0321: * Clone both the Java3D and the visual graph
0322: */
0323: public SGObject cloneTree(SGObject source)
0324: throws DanglingReferenceException,
0325: RestrictedAccessException {
0326: Node node = ((Node) source.getJ3dSceneGraphObject())
0327: .cloneTree(true);
0328: // TODO Deal with tree levels on cloned nodes
0329: SGObject ret = (SGObject) traverseGraph(node);
0330: ((TVObject) ret.getTreeViewObject())
0331: .setContainer(((TVObject) source.getTreeViewObject())
0332: .getContainer());
0333:
0334: return ret;
0335: }
0336:
0337: private void createLocale(DevelopmentLocale locale) {
0338: nodeMapping.clear();
0339: componentMapping.clear();
0340: postProcess.clear();
0341:
0342: if (nameControl == null) {
0343: nameControl = context.getNameControl();
0344: nameControl.enableSearchOnObject(true);
0345: }
0346:
0347: viewRoot = new SGLocale(locale, context);
0348: localeMapping.put(locale, viewRoot);
0349:
0350: }
0351:
0352: /**
0353: * Traverse the set of graphs and create the user view,
0354: * add a dummy Locale node as the root of the tree
0355: */
0356: private void createUserViewForLocale(DevelopmentLocale locale) {
0357: System.out
0358: .println("--------------------------- UserViewForLocale -----------------");
0359: nodeMapping.clear();
0360: componentMapping.clear();
0361: postProcess.clear();
0362:
0363: if (nameControl == null) {
0364: nameControl = context.getNameControl();
0365: nameControl.enableSearchOnObject(true);
0366: }
0367:
0368: localeMapping.remove(viewRoot);
0369: viewRoot = new SGLocale(locale, context);
0370: localeMapping.put(locale, viewRoot);
0371: for (int i = 0; i < locale.getBranchGraphs().length; i++) {
0372: viewRoot
0373: .addChild(traverseGraph(locale.getBranchGraphs()[i]));
0374: }
0375: treeViewFactory.createTreeViewObject(viewRoot);
0376:
0377: postProcessNodes();
0378:
0379: setEditorCapabilities(viewRoot);
0380: }
0381:
0382: /**
0383: * Returns the viewRoot for this locale, or null if the locale is
0384: * unknown
0385: */
0386: /*
0387: private SGGroup getViewRoot( DevelopmentLocale locale ) {
0388: int vr = -1;
0389:
0390: for( int i=0; i<context.numLocales() && vr==-1; i++)
0391: if (context.getLocale(i)==locale)
0392: vr = i;
0393:
0394: if (vr==-1)
0395: return null;
0396:
0397: return (SGGroup)viewRoots.get(vr);
0398: }
0399: */
0400:
0401: /**
0402: * Set the viewRoot for the locale
0403: */
0404: /*
0405: private void setViewRoot( DevelopmentLocale locale, SGGroup viewRoot ) {
0406: int vr = -1;
0407:
0408: for( int i=0; i<context.numLocales() && vr==-1; i++)
0409: if (context.getLocale(i)==locale)
0410: vr = i;
0411:
0412: if (vr==-1)
0413: throw new RuntimeException("Unknown Locale");
0414:
0415: while(vr>=viewRoots.size())
0416: viewRoots.add( null );
0417: viewRoots.set( vr, viewRoot );
0418: }
0419: */
0420:
0421: /**
0422: * Add the branch graph to the view for this context
0423: */
0424: /*
0425: private void createUserViewForBranchGraph( BranchGroup bg ) {
0426: nodeMapping.clear();
0427: componentMapping.clear();
0428: postProcess.clear();
0429: SGNode newGraph = null;
0430:
0431: if (nameControl==null) {
0432: nameControl = context.getNameControl();
0433: nameControl.enableSearchOnObject( true );
0434: }
0435:
0436: if (viewRoot==null) {
0437: viewRoot = new SGLocale( context.getLocale(), context );
0438: for (int i=0; i<context.getLocale().getBranchGraphs().length; i++) {
0439: newGraph = traverseGraph( context.getLocale().getBranchGraphs()[i] );
0440: viewRoot.addChild( newGraph );
0441: setEditorCapabilities( newGraph );
0442: }
0443: treeViewFactory.createTreeViewObject( viewRoot );
0444: }
0445:
0446: newGraph = traverseGraph( bg );
0447: viewRoot.addChild( newGraph );
0448:
0449: postProcessNodes();
0450:
0451: setEditorCapabilities( newGraph );
0452: }
0453: */
0454:
0455: private void postProcessNodes() {
0456: Enumeration e = postProcess.elements();
0457: while (e.hasMoreElements()) {
0458: SGObject node = (SGObject) e.nextElement();
0459:
0460: SceneGraphObject j3dNode = node.getJ3dSceneGraphObject();
0461:
0462: if (j3dNode instanceof Interpolator)
0463: checkInterpolator((SGBehavior) node,
0464: (Interpolator) j3dNode);
0465: else if (j3dNode instanceof Behavior)
0466: checkBehavior((SGBehavior) node, (Behavior) j3dNode);
0467: }
0468: }
0469:
0470: /**
0471: * Check which type of Interpolator this node is and
0472: * set the appropriate action Node
0473: */
0474: private void checkInterpolator(SGBehavior node, Interpolator j3dNode) {
0475: if (j3dNode instanceof RotationInterpolator) {
0476: TransformGroup actionNode = ((RotationInterpolator) j3dNode)
0477: .getTarget();
0478: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0479: .get(actionNode));
0480: } else if (j3dNode instanceof PositionPathInterpolator) {
0481: TransformGroup actionNode = ((PositionPathInterpolator) j3dNode)
0482: .getTarget();
0483: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0484: .get(actionNode));
0485: } else if (j3dNode instanceof RotationPathInterpolator) {
0486: TransformGroup actionNode = ((RotationPathInterpolator) j3dNode)
0487: .getTarget();
0488: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0489: .get(actionNode));
0490: } else if (j3dNode instanceof RotPosPathInterpolator) {
0491: TransformGroup actionNode = ((RotPosPathInterpolator) j3dNode)
0492: .getTarget();
0493: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0494: .get(actionNode));
0495: } else if (j3dNode instanceof RotPosScalePathInterpolator) {
0496: TransformGroup actionNode = ((RotPosScalePathInterpolator) j3dNode)
0497: .getTarget();
0498: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0499: .get(actionNode));
0500: } else if (j3dNode instanceof PositionInterpolator) {
0501: TransformGroup actionNode = ((PositionInterpolator) j3dNode)
0502: .getTarget();
0503: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0504: .get(actionNode));
0505: } else if (j3dNode instanceof ScaleInterpolator) {
0506: TransformGroup actionNode = ((ScaleInterpolator) j3dNode)
0507: .getTarget();
0508: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0509: .get(actionNode));
0510: } else if (j3dNode instanceof SwitchValueInterpolator) {
0511: Switch actionNode = ((SwitchValueInterpolator) j3dNode)
0512: .getTarget();
0513: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0514: .get(actionNode));
0515: } else if (j3dNode instanceof RotPosScaleTCBSplinePathInterpolator) {
0516: TransformGroup actionNode = ((RotPosScaleTCBSplinePathInterpolator) j3dNode)
0517: .getTarget();
0518: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0519: .get(actionNode));
0520: }
0521: }
0522:
0523: private void checkBehavior(SGBehavior node, Behavior j3dNode) {
0524:
0525: if (j3dNode instanceof com.sun.j3d.utils.behaviors.vp.ViewPlatformBehavior) {
0526: TransformGroup actionNode = ((com.sun.j3d.utils.behaviors.vp.ViewPlatformBehavior) j3dNode)
0527: .getViewingPlatform().getViewPlatformTransform();
0528: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0529: .get(actionNode));
0530: } else if (j3dNode instanceof com.sun.j3d.utils.behaviors.mouse.MouseRotate) {
0531: TransformGroup actionNode = ((com.sun.j3d.utils.behaviors.mouse.MouseRotate) j3dNode)
0532: .getTransformGroup();
0533: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0534: .get(actionNode));
0535: } else if (j3dNode instanceof com.sun.j3d.utils.behaviors.mouse.MouseTranslate) {
0536: TransformGroup actionNode = ((com.sun.j3d.utils.behaviors.mouse.MouseTranslate) j3dNode)
0537: .getTransformGroup();
0538: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0539: .get(actionNode));
0540: } else if (j3dNode instanceof com.sun.j3d.utils.behaviors.mouse.MouseZoom) {
0541: TransformGroup actionNode = ((com.sun.j3d.utils.behaviors.mouse.MouseZoom) j3dNode)
0542: .getTransformGroup();
0543: ((SGBehavior) node).setActionNode((SGObject) nodeMapping
0544: .get(actionNode));
0545: }
0546:
0547: }
0548:
0549: private SGGroup traverseSharedGroup(SharedGroup node) {
0550:
0551: if (nodeMapping.containsKey(node)) {
0552: return (SGGroup) nodeMapping.get(node);
0553: } else
0554:
0555: return traverseGraphGroup(node);
0556: }
0557:
0558: private SGNode traverseGraph(Node node) {
0559: SGNode ret = null;
0560: if (node instanceof Group)
0561: ret = traverseGraphGroup((Group) node);
0562: else if (node instanceof Behavior)
0563: ret = traverseGraphBehavior((Behavior) node);
0564: else if (node instanceof Leaf)
0565: ret = traverseGraphLeaf((Leaf) node);
0566: else
0567: throw new RuntimeException("Unrecognised node "
0568: + node.getClass().getName());
0569:
0570: if (node.getUserData() instanceof NodePersistance) {
0571: //System.out.println(node.getUserData() );
0572: ((SGObject) ret)
0573: .applyPersistanceData((NodePersistance) node
0574: .getUserData());
0575: }
0576:
0577: nodeMapping.put(node, ret);
0578: //if (node instanceof BranchGroup)
0579: // System.out.println(" "+node+" "+ret );
0580:
0581: // NameControl.ObjectName name = nameControl.getObjectName( node );
0582: if (node.getName() != null) {
0583: if (!nameControl.isUnique("", node.getName())) {
0584: node.setName(node.getName() + ":"
0585: + (nameControl.getUniqueID()));
0586: }
0587:
0588: nameControl.addObject("", node.getName(), node);
0589: ret.setNodeName(node.getName());
0590: ret.setSceneName("");
0591: }
0592:
0593: return ret;
0594: }
0595:
0596: private SGNode traverseGraphLeaf(Leaf leaf) {
0597: SGNode node;
0598:
0599: if (leaf instanceof javax.media.j3d.Link) {
0600: node = new SGLink(leaf, context);
0601: ((SGLink) node)
0602: .addSharedGroup(traverseSharedGroup(((javax.media.j3d.Link) leaf)
0603: .getSharedGroup()));
0604: } else if (leaf instanceof javax.media.j3d.Shape3D) {
0605: node = new SGShape3D(leaf, context);
0606: ((SGShape3D) node)
0607: .setSGAppearance(traverseAppearance(((Shape3D) leaf)
0608: .getAppearance()));
0609: Enumeration e = ((Shape3D) leaf).getAllGeometries();
0610: while (e.hasMoreElements()) {
0611: Geometry geom = (Geometry) e.nextElement();
0612: SGGeometry sgGeom = (SGGeometry) componentMapping
0613: .get(geom);
0614: if (sgGeom == null && geom != null)
0615: sgGeom = new SGGeometry(geom, context);
0616: ((SGShape3D) node).addSGGeometry(sgGeom);
0617: }
0618: } else {
0619: node = new SGLeaf(leaf, context);
0620: }
0621: treeViewFactory.createTreeViewObject(node);
0622: node.setNodeType(leaf.getClass().getName(), treeIconControl
0623: .getImage(leaf.getClass()));
0624:
0625: return node;
0626: }
0627:
0628: private SGAppearance traverseAppearance(Appearance app) {
0629: if (app == null)
0630: return null;
0631:
0632: SGAppearance sgApp = (SGAppearance) componentMapping.get(app);
0633: if (sgApp != null)
0634: return sgApp;
0635:
0636: sgApp = new SGAppearance(app, context);
0637:
0638: SGTexture sgTexture = (SGTexture) componentMapping.get(app
0639: .getTexture());
0640: if (sgTexture == null && app.getTexture() != null) {
0641: sgTexture = new SGTexture(app.getTexture(), context);
0642: }
0643: sgApp.setSGTexture(sgTexture);
0644:
0645: SGTextureAttributes sgTextureAttributes = (SGTextureAttributes) componentMapping
0646: .get(app.getTextureAttributes());
0647: if (sgTextureAttributes == null
0648: && app.getTextureAttributes() != null) {
0649: sgTextureAttributes = new SGTextureAttributes(app
0650: .getTextureAttributes(), context);
0651: }
0652: sgApp.setSGTextureAttributes(sgTextureAttributes);
0653:
0654: SGMaterial sgMaterial = (SGMaterial) componentMapping.get(app
0655: .getMaterial());
0656: if (sgMaterial == null && app.getMaterial() != null) {
0657: sgMaterial = new SGMaterial(app.getMaterial(), context);
0658: }
0659: sgApp.setSGMaterial(sgMaterial);
0660:
0661: SGPolygonAttributes sgPolygonAttributes = (SGPolygonAttributes) componentMapping
0662: .get(app.getPolygonAttributes());
0663: if (sgPolygonAttributes == null
0664: && app.getPolygonAttributes() != null) {
0665: sgPolygonAttributes = new SGPolygonAttributes(app
0666: .getPolygonAttributes(), context);
0667: }
0668: sgApp.setSGPolygonAttributes(sgPolygonAttributes);
0669:
0670: SGPointAttributes sgPointAttributes = (SGPointAttributes) componentMapping
0671: .get(app.getPointAttributes());
0672: if (sgPointAttributes == null
0673: && app.getPointAttributes() != null) {
0674: sgPointAttributes = new SGPointAttributes(app
0675: .getPointAttributes(), context);
0676: }
0677: sgApp.setSGPointAttributes(sgPointAttributes);
0678:
0679: SGTransparencyAttributes sgTransparencyAttributes = (SGTransparencyAttributes) componentMapping
0680: .get(app.getTransparencyAttributes());
0681: if (sgTransparencyAttributes == null
0682: && app.getTransparencyAttributes() != null) {
0683: sgTransparencyAttributes = new SGTransparencyAttributes(app
0684: .getTransparencyAttributes(), context);
0685: }
0686: sgApp.setSGTransparencyAttributes(sgTransparencyAttributes);
0687:
0688: return sgApp;
0689: }
0690:
0691: private SGNode traverseGraphBehavior(Behavior behavior) {
0692: SGNode node;
0693: if (behavior instanceof TransformInterpolator)
0694: node = new SGTransformInterpolator(behavior, context);
0695: else if (behavior instanceof Interpolator)
0696: node = new SGInterpolator(behavior, context);
0697: else
0698: node = new SGBehavior(behavior, context);
0699: treeViewFactory.createTreeViewObject(node);
0700: node.setNodeType(behavior.getClass().getName(), treeIconControl
0701: .getImage(behavior.getClass()));
0702:
0703: postProcess.add(node);
0704:
0705: return node;
0706: }
0707:
0708: private SGGroup traverseGraphGroup(Group group) {
0709: SGGroup viewNode;
0710: if (group instanceof com.sun.j3d.utils.geometry.Primitive)
0711: viewNode = new SGGeometryPrimitive(group, context);
0712: else if (group instanceof org.jdesktop.j3dedit.scenegrapheditor.nodes.LoaderGroup
0713: || group.getUserData() instanceof LoaderPersistance)
0714: viewNode = new SGLoader(group, context);
0715: else if (group instanceof javax.media.j3d.BranchGroup)
0716: viewNode = new SGBranchGroup(group, context);
0717: else
0718: viewNode = new SGGroup(group, context);
0719:
0720: treeViewFactory.createTreeViewObject(viewNode);
0721: viewNode.setNodeType(group.getClass().getName(),
0722: treeIconControl.getImage(group.getClass()));
0723:
0724: if (viewNode instanceof SGGeometryPrimitive) {
0725: ((SGGroup) viewNode).hideChildren(true);
0726: }
0727:
0728: int childCount;
0729: if (group instanceof EncapsulatingGroup)
0730: childCount = ((EncapsulatingGroup) group)
0731: .numEncapsulatedChildren();
0732: else
0733: childCount = group.numChildren();
0734: for (int i = 0; i < childCount; i++) {
0735: if (group instanceof EncapsulatingGroup)
0736: viewNode
0737: .addChild(traverseGraph(((EncapsulatingGroup) group)
0738: .getEncapsulatedChild(i)));
0739: else
0740: viewNode.addChild(traverseGraph(group.getChild(i)));
0741: }
0742:
0743: if (group instanceof com.sun.j3d.utils.universe.ViewingPlatform)
0744: makeGraphReadOnly(viewNode);
0745:
0746: return viewNode;
0747: }
0748:
0749: /**
0750: * Traverse the tree from node making all nodes read only
0751: */
0752: private void makeGraphReadOnly(SGObject node) {
0753: node.setReadOnly(true);
0754:
0755: if (node instanceof SGGroup) {
0756: int childCount = ((SGGroup) node).numChildren();
0757: for (int i = 0; i < childCount; i++)
0758: makeGraphReadOnly(((SGGroup) node).getChild(i));
0759: }
0760: }
0761:
0762: /**
0763: * Save all of the editors state information into the userData of
0764: * the SceneGraph.
0765: *
0766: * Also sets the minimum capabilities for each node
0767: */
0768: private void setupEditorPersistanceAndRestoreCapabilities(
0769: SGObject node) {
0770:
0771: if (node instanceof SGLocale) {
0772: SGLocale group = (SGLocale) node;
0773: treeViewFactory.createTreeViewObject(group);
0774: for (int i = 0; i < group.numChildren(); i++)
0775: setupEditorPersistanceAndRestoreCapabilities((SGObject) group
0776: .getChild(i));
0777: } else {
0778: node.getJ3dSceneGraphObject().setUserData(
0779: createPersistance(node));
0780: node.restoreCapabilities();
0781:
0782: if (node instanceof SGGroup) {
0783: SGGroup group = (SGGroup) node;
0784: for (int i = 0; i < group.numChildren(); i++)
0785: setupEditorPersistanceAndRestoreCapabilities((SGObject) group
0786: .getChild(i));
0787: }
0788: }
0789: }
0790:
0791: private Object createPersistance(SGObject node) {
0792: NodePersistance data = node.createPersistanceObject();
0793: node.createPersistanceData(data);
0794:
0795: //System.out.println("Storing Persistance "+data.containsData() );
0796:
0797: if (data.containsData())
0798: return data;
0799: else
0800: return null;
0801: }
0802:
0803: /**
0804: * Set the runtime editor capabilities on the SceneGraph
0805: */
0806: public void setEditorCapabilities() {
0807: if (context.getLocale().getBranchGraphs() != null) {
0808: setEditorCapabilities(viewRoot);
0809: }
0810: }
0811:
0812: /**
0813: * Traverse the graph and set the capabilities of each node
0814: * as per the current editor mode. Traversal of the graph stops when
0815: * a node is encountered with the correct setting.
0816: */
0817: public void setEditorCapabilities(SGObject graph) {
0818:
0819: //System.out.println("SceneGraphControl.setEditorCapabilities "+graph.getJ3dSceneGraphObject() );
0820:
0821: if (graph.getEditorCapabilitiesStatus() == SGObject.CAPABILITIES_READ_WRITE
0822: && org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.performanceLevel == org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.READ_WRITE_ALLOWED)
0823: return;
0824: if (graph.getEditorCapabilitiesStatus() == SGObject.CAPABILITIES_READ
0825: && org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.performanceLevel == org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.READ_ALLOWED)
0826: return;
0827:
0828: if (!(graph instanceof SGLocale)
0829: && !graph.getJ3dSceneGraphObject().isLive())
0830: context.getConfigLoader().getEditorManager()
0831: .setEditorCapabilities(graph);
0832:
0833: if (graph instanceof SGGroup) {
0834: SGGroup group = (SGGroup) graph;
0835: for (int i = 0; i < group.numChildren(); i++) {
0836: if (!group.getChild(i).getJ3dSceneGraphObject()
0837: .isLive())
0838: setEditorCapabilities(group.getChild(i));
0839: }
0840: }
0841: }
0842:
0843: private void loadError(IOException e) {
0844: System.out.println("Error Loading data");
0845: }
0846:
0847: private void saveError(IOException e) {
0848: System.out.println("Error Saving data");
0849: }
0850:
0851: /**
0852: * Returns the Locale to which this node is attached. Normally this will be
0853: * an instance of DevelopmentLocale except when the interposer is being used
0854: * in which case it will be an instance of Locale and the InterposerListener
0855: * will then map it to the InterposerLocale
0856: */
0857: public Locale getLocale(Node node) {
0858: SGNode n = (SGNode) nodeMapping.get(node);
0859: if (n == null)
0860: return null;
0861:
0862: return n.getLocale();
0863: }
0864:
0865: /////////////////////////////////////////////////////
0866: // SceneGraphChangeListener methods
0867:
0868: /** A new Branch graph is about to added to the Locale
0869: */
0870: public void graphAdded(DevelopmentLocale locale,
0871: BranchGroup newGraph) {
0872: //createUserViewForBranchGraph( newGraph );
0873: SGGroup localeSG = ((SGGroup) getLocaleNode(locale));
0874: if (localeSG == null) {
0875: System.out.println("Not current Locale " + locale + " "
0876: + newGraph);
0877: return;
0878: }
0879:
0880: // TODO look at performance of current getLocale call and determine if
0881: // we should add a setLocale. When addChild creates a new node it would
0882: // then set the locale to be the same as the parent node
0883: //localeSG.setLocale( locale );
0884:
0885: addChild(localeSG, newGraph, false);
0886: if (treePanel != null) {
0887: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
0888: treePanel.layoutTree();
0889: treePanel.repaint();
0890: }
0891: }
0892:
0893: /** A Branch graph has been removed
0894: */
0895: public void graphRemoved(DevelopmentLocale locale, BranchGroup graph) {
0896: // TODO Remove graph without re-processing remaining scene.
0897: // We'll have to parse the graph being removed and delete
0898: // all the names etc.
0899: //createUserViewForLocale( locale );
0900: removeChild(((SGGroup) getLocaleNode(locale)),
0901: (SGNode) getTreeNode(graph));
0902: if (treePanel != null) {
0903: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
0904: treePanel.layoutTree();
0905: treePanel.repaint();
0906: }
0907: }
0908:
0909: /** A branch graph has been replaced
0910: */
0911: public void graphReplaced(DevelopmentLocale locale,
0912: BranchGroup oldGraph, BranchGroup newGraph) {
0913: System.out.println("Graph REPLACED....... TODO");
0914:
0915: createUserViewForLocale(locale);
0916: if (treePanel != null) {
0917: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
0918: treePanel.layoutTree();
0919: treePanel.repaint();
0920: }
0921: }
0922:
0923: /** Called when the Locale is notified of SceneGraph Structure changes
0924: * by a call to notifyGraphChanged
0925: *
0926: */
0927: public void graphChanged(DevelopmentLocale locale,
0928: BranchGroup graph, javax.media.j3d.Node node) {
0929: System.out.println("Graph CHanged");
0930: System.exit(1);
0931: //createUserViewForLocale( locale );
0932:
0933: if (treePanel != null) {
0934: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
0935: treePanel.layoutTree();
0936: treePanel.repaint();
0937: }
0938: }
0939:
0940: /**
0941: * Called when a BranchGroup is added to a group within a live scene graph
0942: *
0943: * @params parent The live parent
0944: * @params child The child about to be attached to the parent, the child has
0945: * not been attached at this stage
0946: */
0947: public void groupAddChild(DevelopmentLocale locale,
0948: javax.media.j3d.Group parent, BranchGroup child) {
0949: try {
0950: addChild((SGGroup) getTreeNode(parent), child, false);
0951: } catch (Exception e) {
0952: System.out.println("Mapping size " + nodeMapping.size());
0953: System.out.println(parent);
0954: System.out.println(child);
0955: System.out.println(getTreeNode(parent));
0956: e.printStackTrace();
0957: System.exit(1);
0958: }
0959: if (treePanel != null) {
0960: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
0961: treePanel.layoutTree();
0962: treePanel.repaint();
0963: }
0964: }
0965:
0966: /**
0967: * Called when a BranchGroup is set in a group within a live scene graph
0968: *
0969: * @param parent The live parent
0970: * @param child The child about to be set to the parent, the child has
0971: * not been attached at this stage
0972: */
0973: public void groupSetChild(DevelopmentLocale locale,
0974: javax.media.j3d.Group parent,
0975: javax.media.j3d.BranchGroup child, int index) {
0976: System.out
0977: .println("Doing setChild *****************************");
0978: Node oldChild = parent.getChild(index);
0979: ((SGGroup) getTreeNode(parent))
0980: .removeChild((SGNode) getTreeNode(oldChild));
0981:
0982: // TODO need to control the index of the child
0983: addChild((SGGroup) getTreeNode(parent), child, false);
0984:
0985: if (treePanel != null) {
0986: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
0987: treePanel.layoutTree();
0988: treePanel.repaint();
0989: }
0990: }
0991:
0992: public void groupRemoveAllChildren(DevelopmentLocale locale,
0993: javax.media.j3d.Group parent) {
0994: Node oldChild;
0995:
0996: for (int i = 0; i < parent.numChildren(); i++) {
0997: oldChild = parent.getChild(i);
0998: ((SGGroup) getTreeNode(parent))
0999: .removeChild((SGNode) getTreeNode(oldChild));
1000: }
1001: }
1002:
1003: /** Called when a BranchGroup is removed from a group within a live scene graph
1004: *
1005: * @param parent The live parent
1006: * @param child The live child which is about to be removed
1007: */
1008: public void groupRemoveChild(DevelopmentLocale locale,
1009: javax.media.j3d.Group parent,
1010: javax.media.j3d.BranchGroup child) {
1011: ((SGGroup) getTreeNode(parent))
1012: .removeChild((SGNode) getTreeNode(child));
1013:
1014: if (treePanel != null) {
1015: treePanel.setTree((TVObject) viewRoot.getTreeViewObject());
1016: treePanel.layoutTree();
1017: treePanel.repaint();
1018: }
1019: }
1020:
1021: // End of SceneGraphChangeListener methods
1022: //////////////////////////////////////////////////////
1023:
1024: /**
1025: * Traverse the graph and generate default names for all
1026: * the 'interesting' objects that are not named.
1027: *
1028: * Only Behaviors, Fog, Lights, Sound and Loaders are given default names
1029: */
1030: public void createDefaultNames(SGObject root, String sceneName) {
1031:
1032: if (root.getNodeName() == null
1033: && (root instanceof SGLoader
1034: || root.getJ3dSceneGraphObject() instanceof javax.media.j3d.Fog
1035: || root.getJ3dSceneGraphObject() instanceof javax.media.j3d.Light
1036: || root.getJ3dSceneGraphObject() instanceof javax.media.j3d.Sound || root
1037: .getJ3dSceneGraphObject() instanceof javax.media.j3d.Behavior)) {
1038:
1039: String name = NameGenerator.getNameControl().getName(
1040: root.getJ3dSceneGraphObject());
1041: context.getNameControl().addObject(sceneName, name, // New name
1042: root.getJ3dSceneGraphObject());
1043: root.setNodeName(name);
1044: root.setSceneName(sceneName);
1045: }
1046:
1047: if (root instanceof SGGroup) {
1048: for (int i = 0; i < ((SGGroup) root).numChildren(); i++)
1049: createDefaultNames(((SGGroup) root).getChild(i),
1050: sceneName);
1051: }
1052: }
1053:
1054: /**
1055: * Enable/Disable the 3D Highlight mode
1056: *
1057: * The mode should be disabled by default in order to
1058: * achieve best rendering performance
1059: *
1060: * When enabled the AppearanceOverrideEnable flag of all
1061: * Shape3D nodes in the scene is set to true
1062: */
1063: public void setHighlight3DModeEnable(final boolean enable) {
1064: actualSetHighlight3DModeEnable(viewRoot, enable);
1065: }
1066:
1067: private void actualSetHighlight3DModeEnable(SGObject treeRoot,
1068: final boolean enable) {
1069: SceneGraphObject node;
1070:
1071: node = treeRoot.getJ3dSceneGraphObject();
1072:
1073: if (node instanceof javax.media.j3d.Shape3D)
1074: ((javax.media.j3d.Shape3D) node)
1075: .setAppearanceOverrideEnable(enable);
1076:
1077: if (treeRoot instanceof SGGroup) {
1078: for (int i = 0; i < ((SGGroup) treeRoot).numChildren(); i++)
1079: actualSetHighlight3DModeEnable(((SGGroup) treeRoot)
1080: .getChild(i), enable);
1081: }
1082: }
1083:
1084: private javax.media.j3d.BranchGroup altAppearanceBG = null;
1085:
1086: public void setHighlight3D(SGObject node, boolean highlight) {
1087: if (highlight && altAppearanceBG == null) {
1088: javax.media.j3d.AlternateAppearance altAppearance = new javax.media.j3d.AlternateAppearance();
1089: TransparencyAttributes transAttr = new TransparencyAttributes();
1090: transAttr
1091: .setTransparencyMode(TransparencyAttributes.BLENDED);
1092: transAttr.setTransparency(0.8f);
1093: Appearance app = new Appearance();
1094: app.setTransparencyAttributes(transAttr);
1095: altAppearance.setAppearance(app);
1096: altAppearance.setInfluencingBounds(new BoundingSphere(
1097: new javax.vecmath.Point3d(),
1098: Double.POSITIVE_INFINITY));
1099:
1100: altAppearanceBG = new BranchGroup();
1101: altAppearanceBG.addChild(altAppearance);
1102: altAppearanceBG.setCapability(BranchGroup.ALLOW_DETACH);
1103: }
1104:
1105: actualSetHighlight3DModeEnable(node, !highlight);
1106:
1107: if (highlight) {
1108: context.getLocale().getHiddenBranchGraph().addChild(
1109: altAppearanceBG);
1110: } else {
1111: context.getLocale().getHiddenBranchGraph().removeChild(
1112: altAppearanceBG);
1113: }
1114:
1115: }
1116:
1117: }
|