package org.freehep.j3d.plot; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.behaviors.mouse.*; /** * Abstract class extended by other 3D Plot widgets. * * Defines default mouse behaviour etc. * @author Joy Kyriakopulos (joyk@fnal.gov) * @version $Id: Plot3D.java 8584 2006-08-10 23:06:37Z duns $ */ public abstract class Plot3D extends Canvas3D { protected boolean init = false; protected boolean parallelProjection = false; protected SimpleUniverse universe; Plot3D() { super(SimpleUniverse.getPreferredConfiguration()); } protected void init() { Node plot = createPlot(); BranchGroup scene = defineMouseBehaviour(plot); setupLights(scene); // Surface plot wants an extra light scene.compile(); universe = new SimpleUniverse(this); universe.getViewingPlatform().setNominalViewingTransform(); universe.addBranchGraph(scene); if (parallelProjection) { setProjectionPolicy(universe, parallelProjection); } init = true; } // addNotify is called when the Canvas3D is added to a container public void addNotify() { if (!init) init(); super.addNotify(); // must call for Java3D to operate properly when overriding } public boolean getParallelProjection() { return parallelProjection; } public void setParallelProjection(boolean b) { if (parallelProjection != b) { parallelProjection = b; setProjectionPolicy(universe, parallelProjection); } } /** * Override to provide plot content */ protected abstract Node createPlot(); /** * Override to provide different mouse behaviour */ protected BranchGroup defineMouseBehaviour(Node scene) { BranchGroup bg = new BranchGroup(); Bounds bounds = getDefaultBounds(); TransformGroup objTransform = new TransformGroup(); objTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objTransform.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); objTransform.addChild(scene); bg.addChild(objTransform); MouseRotate mouseRotate = new MouseRotate(); mouseRotate.setTransformGroup(objTransform); mouseRotate.setSchedulingBounds(bounds); bg.addChild(mouseRotate); MouseTranslate mouseTranslate = new MouseTranslate(); mouseTranslate.setTransformGroup(objTransform); mouseTranslate.setSchedulingBounds(bounds); bg.addChild(mouseTranslate); MouseZoom mouseZoom = new MouseZoom(); mouseZoom.setTransformGroup(objTransform); mouseZoom.setSchedulingBounds(bounds); bg.addChild(mouseZoom); // Set initial transformation Transform3D trans = createDefaultOrientation(); objTransform.setTransform(trans); Behavior keyBehavior = new PlotKeyNavigatorBehavior(objTransform,.1f,10f); objTransform.addChild(keyBehavior); keyBehavior.setSchedulingBounds(bounds); // set up a rotation animating behavior // rotator = setupZRotator(dynamicXform); // rotator.setSchedulingBounds(bounds); // rotator.setEnable(false); // dynamicXform.addChild(rotator); return bg; } protected void setupLights(BranchGroup root) { DirectionalLight lightD = new DirectionalLight(); lightD.setDirection(new Vector3f(0.0f, -0.7f, -0.7f)); lightD.setInfluencingBounds(getDefaultBounds()); root.addChild(lightD); // This second light is added for the Surface Plot, so you // can see the "under" surface DirectionalLight lightD1 = new DirectionalLight(); lightD1.setDirection(new Vector3f(0.0f, 0.7f, 0.7f)); lightD1.setInfluencingBounds(getDefaultBounds()); root.addChild(lightD1); AmbientLight lightA = new AmbientLight(); lightA.setInfluencingBounds(getDefaultBounds()); root.addChild(lightA); } /** * Override to set a different initial transformation */ protected Transform3D createDefaultOrientation() { Transform3D trans = new Transform3D(); trans.setIdentity(); trans.rotX(-Math.PI / 4.); trans.setTranslation(new Vector3f(0.f, -.3f, 0.f)); return trans; } /** * Set the projection policy for the plot - either perspective or projection */ protected void setProjectionPolicy(SimpleUniverse universe, boolean parallelProjection) { View view = universe.getViewer().getView(); if (parallelProjection) view.setProjectionPolicy(View.PARALLEL_PROJECTION); else view.setProjectionPolicy(View.PERSPECTIVE_PROJECTION); } /** * Returns a bounds object that can be used for most behaviours, * lighting models, etc. */ protected Bounds getDefaultBounds() { if (bounds == null) { Point3d center = new Point3d(0, 0, 0); bounds = new BoundingSphere(center, 10); } return bounds; } private Bounds bounds; }