// Java 3D Test Applet // RotPosScalePathTest.java // Copyright (c) 1999 ENDO Yasuyuki // mailto:yasuyuki@javaopen.org // http://www.javaopen.org/j3dbook/index.html import java.applet.*; import java.awt.*; import java.awt.event.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.behaviors.picking.PickRotateBehavior; import com.sun.j3d.utils.behaviors.picking.PickObject; import com.sun.j3d.utils.behaviors.picking.PickingCallback; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.geometry.Primitive; import com.sun.j3d.utils.geometry.Box; public class RotPosScalePathTest extends Applet { private Canvas3D canvas = null; private Point3f[] pverts = null; private float[] knots = { 0.0f, 0.4f, 0.6f, 1.0f }; private float[] scales = { 1.0f, 1.0f, 1.0f, 1.0f }; private TuplePanel tp0 = new TuplePanel( new Point3f( 0.0f, -0.6f, 0.1f) ); private TuplePanel tp1 = new TuplePanel( new Point3f(-0.4f, -0.2f, 0.1f) ); private TuplePanel tp2 = new TuplePanel( new Point3f( 0.4f, 0.2f, 0.1f) ); private TuplePanel tp3 = new TuplePanel( new Point3f(0.0f, 0.6f, 0.1f) ); private TransformGroup[] ptrans = null; private AlphaPanel apanel = null; private RotPosScalePathInterpolator rinterp = null; public RotPosScalePathTest() { this.setLayout(new BorderLayout()); apanel = new AlphaPanel(); this.add(apanel, BorderLayout.NORTH); Panel ppanel = new Panel(); ppanel.setLayout( new GridLayout(4, 0) ); this.add(ppanel, BorderLayout.SOUTH); Panel[] ppanels = new Panel[4]; for (int i=0; i<4; i++) { ppanels[i] = new Panel(); ppanel.add(ppanels[i]); } final Button sbutton = new Button("Start"); sbutton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { String blabel = sbutton.getLabel(); if (blabel.equals("Start")) { rinterp.setEnable(true); apanel.reset(); sbutton.setLabel("Stop"); } else if (blabel.equals("Stop")) { rinterp.setEnable(false); sbutton.setLabel("Start"); } } }); ppanels[0].add(sbutton); ppanels[0].add( new Label("k0") ); TextField k0field = new TextField("0.0"); k0field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[0] = k; rinterp.setKnot(0, k); } catch (NumberFormatException ex) {} } }); ppanels[0].add(k0field); //tp0 = new TuplePanel( new Point3f(0.0f, -0.6f, 0.1f) ); String[] labels0 = {"p0.x", "p0.y", "p0.z"}; tp0.setLabels(labels0); tp0.addTupleEventListener( new TupleEventListener() { public void tupleStateChanged(TupleEvent e) { pverts[0] = e.getPoint3f(); Transform3D t3d = new Transform3D(); t3d.setTranslation(new Vector3f((Tuple3f)pverts[0])); ptrans[0].setTransform(t3d); rinterp.setPosition(0, pverts[0]); } }); ppanels[0].add(tp0); ppanels[0].add( new Label("s0") ); TextField s0field = new TextField("1.0"); s0field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float s = 0.0f; try { s = Float.parseFloat(e.getActionCommand()); scales[0] = s; Transform3D t3d = new Transform3D(); ptrans[0].getTransform(t3d); t3d.setScale(s); ptrans[0].setTransform(t3d); rinterp.setScale(0, s); } catch (NumberFormatException ex) {} } }); ppanels[0].add(s0field); ppanels[1].add( new Label("k1") ); TextField k1field = new TextField("0.4"); k1field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[1] = k; rinterp.setKnot(1, k); } catch (NumberFormatException ex) {} } }); ppanels[1].add(k1field); //tp1 = new TuplePanel( new Point3f(-0.4f, -0.2f, 0.1f) ); String[] labels1 = {"p1.x", "p1.y", "p1.z"}; tp1.setLabels(labels1); tp1.addTupleEventListener( new TupleEventListener() { public void tupleStateChanged(TupleEvent e) { pverts[1] = e.getPoint3f(); Transform3D t3d = new Transform3D(); t3d.setTranslation(new Vector3f((Tuple3f)pverts[1])); ptrans[1].setTransform(t3d); rinterp.setPosition(1, pverts[1]); } }); ppanels[1].add(tp1); ppanels[1].add( new Label("s1") ); TextField s1field = new TextField("1.0"); s1field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float s = 0.0f; try { s = Float.parseFloat(e.getActionCommand()); scales[1] = s; Transform3D t3d = new Transform3D(); ptrans[1].getTransform(t3d); t3d.setScale(s); ptrans[1].setTransform(t3d); rinterp.setScale(1, s); } catch (NumberFormatException ex) {} } }); ppanels[1].add(s1field); ppanels[2].add( new Label("k2") ); TextField k2field = new TextField("0.6"); k2field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[2] = k; rinterp.setKnot(2, k); } catch (NumberFormatException ex) {} } }); ppanels[2].add(k2field); //tp2 = new TuplePanel( new Point3f(0.4f, 0.2f, 0.1f) ); String[] labels2 = {"p2.x", "p2.y", "p2.z"}; tp2.setLabels(labels2); tp2.addTupleEventListener( new TupleEventListener() { public void tupleStateChanged(TupleEvent e) { pverts[2] = e.getPoint3f(); Transform3D t3d = new Transform3D(); t3d.setTranslation(new Vector3f((Tuple3f)pverts[2])); ptrans[2].setTransform(t3d); rinterp.setPosition(2, pverts[2]); } }); ppanels[2].add(tp2); ppanels[2].add( new Label("s2") ); TextField s2field = new TextField("1.0"); s2field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float s = 0.0f; try { s = Float.parseFloat(e.getActionCommand()); scales[2] = s; Transform3D t3d = new Transform3D(); ptrans[2].getTransform(t3d); t3d.setScale(s); ptrans[2].setTransform(t3d); rinterp.setScale(2, s); } catch (NumberFormatException ex) {} } }); ppanels[2].add(s2field); ppanels[3].add( new Label("k3") ); TextField k3field = new TextField("1.0"); k3field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float k = 0.0f; try { k = Float.parseFloat(e.getActionCommand()); if (k < 0.0f) k = 0.0f; if (k > 1.0f) k = 1.0f; knots[3] = k; rinterp.setKnot(3, k); } catch (NumberFormatException ex) {} } }); ppanels[3].add(k3field); //tp3 = new TuplePanel( new Point3f(0.0f, 0.6f, 0.1f) ); String[] labels3 = {"p3.x", "p3.y", "p3.z"}; tp3.setLabels(labels3); tp3.addTupleEventListener( new TupleEventListener() { public void tupleStateChanged(TupleEvent e) { pverts[3] = e.getPoint3f(); Transform3D t3d = new Transform3D(); t3d.setTranslation(new Vector3f((Tuple3f)pverts[3])); ptrans[3].setTransform(t3d); rinterp.setPosition(3, pverts[3]); } }); ppanels[3].add(tp3); ppanels[3].add( new Label("s3") ); TextField s3field = new TextField("1.0"); s3field.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float s = 0.0f; try { s = Float.parseFloat(e.getActionCommand()); scales[3] = s; Transform3D t3d = new Transform3D(); ptrans[3].getTransform(t3d); t3d.setScale(s); ptrans[3].setTransform(t3d); rinterp.setScale(3, s); } catch (NumberFormatException ex) {} } }); ppanels[3].add(s3field); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); canvas = new Canvas3D(config); this.add(canvas, BorderLayout.CENTER); SimpleUniverse universe = new SimpleUniverse(canvas); universe.getViewingPlatform().setNominalViewingTransform(); BranchGroup scene = createSceneGraph(); universe.addBranchGraph(scene); } private BranchGroup createSceneGraph() { BranchGroup root = new BranchGroup(); root.setCapability(BranchGroup.ALLOW_DETACH); BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0); TransformGroup mtrans = new TransformGroup(); mtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); mtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); mtrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING); mtrans.setUserData("mtrans"); root.addChild(mtrans); final TransformGroup rtrans = new TransformGroup(); rtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); rtrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); root.addChild(rtrans); pverts = new Point3f[4]; pverts[0] = (Point3f)tp0.getTuple3f(); pverts[1] = (Point3f)tp1.getTuple3f(); pverts[2] = (Point3f)tp2.getTuple3f(); pverts[3] = (Point3f)tp3.getTuple3f(); ptrans = new TransformGroup[4]; for (int i=0; i<4; i++) { Transform3D pt3d = new Transform3D(); pt3d.set( new Vector3f( (Tuple3f)pverts[i] ) ); ptrans[i] = new TransformGroup(pt3d); ptrans[i].setCapability(TransformGroup.ALLOW_TRANSFORM_READ); ptrans[i].setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); rtrans.addChild(ptrans[i]); } TransformGroup p0trans = createCube(0.05, new Vector3d(), true); p0trans.setUserData("p0"); ptrans[0].addChild(p0trans); TransformGroup p1trans = createCube(0.05, new Vector3d(), true); p1trans.setUserData("p1"); ptrans[1].addChild(p1trans); TransformGroup p2trans = createCube(0.05, new Vector3d(), true); p2trans.setUserData("p2"); ptrans[2].addChild(p2trans); TransformGroup p3trans = createCube(0.05, new Vector3d(), true); p3trans.setUserData("p3"); ptrans[3].addChild(p3trans); PickRotateBehavior mrotator = new PickRotateBehavior(root, canvas, bounds, PickObject.USE_GEOMETRY); mrotator.setupCallback( new PickingCallback() { public void transformChanged(int type, TransformGroup trans) { if (trans != null) { String udata = (String)trans.getUserData(); if (udata != null) { //System.out.println(udata);//DEBUG Transform3D t3d = new Transform3D(); trans.getTransform(t3d); if (udata.equals("mtrans")) { rtrans.setTransform(t3d); } else if (udata.equals("p0")) { Quat4f quat = new Quat4f(); t3d.get(quat); rinterp.setQuat(0, quat); } else if (udata.equals("p1")) { Quat4f quat = new Quat4f(); t3d.get(quat); rinterp.setQuat(1, quat); } else if (udata.equals("p2")) { Quat4f quat = new Quat4f(); t3d.get(quat); rinterp.setQuat(2, quat); } else if (udata.equals("p3")) { Quat4f quat = new Quat4f(); t3d.get(quat); rinterp.setQuat(3, quat); } } } } }); root.addChild(mrotator); double[] vertices = { -0.8, -0.8, 0.0, -0.8, 0.8, 0.0, -0.4, -0.8, 0.0, -0.4, 0.8, 0.0, 0.0, -0.8, 0.0, 0.0, 0.8, 0.0, 0.4, -0.8, 0.0, 0.4, 0.8, 0.0, 0.8, -0.8, 0.0, 0.8, 0.8, 0.0, -0.8, -0.8, 0.0, 0.8, -0.8, 0.0, -0.8, -0.4, 0.0, 0.8, -0.4, 0.0, -0.8, 0.0, 0.0, 0.8, 0.0, 0.0, -0.8, 0.4, 0.0, 0.8, 0.4, 0.0, -0.8, 0.8, 0.0, 0.8, 0.8, 0.0 }; LineArray geom = new LineArray( vertices.length / 3, GeometryArray.COORDINATES); geom.setCapability(GeometryArray.ALLOW_INTERSECT); geom.setCoordinates(0, vertices); Shape3D grid = new Shape3D(geom); grid.setCapability(Shape3D.ALLOW_GEOMETRY_READ); mtrans.addChild(grid); mtrans.addChild( createCorner(0.05f, new Vector3d(-0.8, -0.8, 0.0)) ); mtrans.addChild( createCorner(0.05f, new Vector3d( 0.8, -0.8, 0.0)) ); mtrans.addChild( createCorner(0.05f, new Vector3d(-0.8, 0.8, 0.0)) ); mtrans.addChild( createCorner(0.05f, new Vector3d( 0.8, 0.8, 0.0)) ); Quat4f[] quats = new Quat4f[4]; for (int i=0; i<4; i++) quats[i] = new Quat4f(0.0f, 0.0f, 0.0f, 0.0f); TransformGroup ctrans = createCube(0.05, new Vector3d(0.0, 0.0, 0.1), false); rtrans.addChild(ctrans); Transform3D rt3d = new Transform3D(); rinterp = new RotPosScalePathInterpolator( apanel.getAlpha(), ctrans, rt3d, knots, quats, pverts, scales ); rinterp.setSchedulingBounds(bounds); rinterp.setEnable(false); root.addChild(rinterp); return root; } private TransformGroup createCorner(float size, Vector3d position) { Transform3D t3d = new Transform3D(); t3d.set(position); TransformGroup trans = new TransformGroup(t3d); Appearance app = new Appearance(); Box box = new Box(size, size, size, Primitive.ENABLE_GEOMETRY_PICKING, app); trans.addChild(box); return trans; } private TransformGroup createCube(double size, Vector3d pos, boolean pick) { Transform3D t3d = new Transform3D(); t3d.set(pos); TransformGroup ctrans = new TransformGroup(t3d); ctrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); ctrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); if (pick) ctrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING); ColorCube cube = new ColorCube(size); cube.setCapability(Shape3D.ALLOW_GEOMETRY_READ); cube.getGeometry().setCapability(GeometryArray.ALLOW_INTERSECT); ctrans.addChild(cube); return ctrans; } public static void main(String[] args) { RotPosScalePathTest applet = new RotPosScalePathTest(); Frame frame = new MainFrame(applet, 500, 600); } }