001: /*
002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/scenegrapheditor/visualtools/InterpolatorPathView.java,v 1.1 2005/04/20 22:21:29 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dedit.scenegrapheditor.visualtools;
019:
020: import java.util.ArrayList;
021: import java.util.Vector;
022: import java.util.Iterator;
023: import java.util.Enumeration;
024: import javax.media.j3d.BranchGroup;
025: import javax.media.j3d.Interpolator;
026: import javax.media.j3d.Alpha;
027: import javax.media.j3d.TransformGroup;
028: import javax.media.j3d.Transform3D;
029: import javax.media.j3d.WakeupOnElapsedFrames;
030: import javax.media.j3d.LineStripArray;
031: import javax.media.j3d.Shape3D;
032: import javax.media.j3d.SharedGroup;
033: import javax.media.j3d.Link;
034: import javax.vecmath.Point3f;
035: import javax.vecmath.Matrix4d;
036: import com.sun.j3d.utils.behaviors.interpolators.KBRotPosScaleSplinePathInterpolator;
037:
038: /**
039: * Displays the path of an Interpolator.
040: *
041: * The interpolator MUST have get/setTarget methods
042: *
043: * @author paulby
044: * @version
045: */
046: public class InterpolatorPathView extends BranchGroup {
047:
048: private Interpolator interp;
049: private Vector criteria;
050:
051: private LineStripArray geom = null;
052: private BranchGroup pathBG;
053: private BranchGroup tickBG;
054: private BranchGroup rootBG;
055: private SharedGroup tickSharedGroup;
056: private TransformGroup tickScaleTG;
057: private TransformGroup targetOffsetTG;
058:
059: /** Creates new InterpolatorPathVie */
060: public InterpolatorPathView() {
061: super ();
062:
063: this .setPickable(false);
064:
065: targetOffsetTG = new TransformGroup();
066: targetOffsetTG
067: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
068:
069: pathBG = new BranchGroup();
070: pathBG.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
071: pathBG.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
072: pathBG.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
073: BranchGroup tmpBG = new BranchGroup();
074: tmpBG.setCapability(BranchGroup.ALLOW_DETACH);
075: pathBG.addChild(tmpBG); // Dummy child, will be removed when geometry is added
076: rootBG = new BranchGroup();
077: rootBG.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
078: rootBG.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
079:
080: tickBG = new BranchGroup();
081: tickBG.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
082: tickBG.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
083: tickBG.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
084: tickBG.setCapability(BranchGroup.ALLOW_DETACH);
085:
086: targetOffsetTG.addChild(rootBG);
087: rootBG.addChild(tickBG);
088: rootBG.addChild(pathBG);
089:
090: this .addChild(targetOffsetTG);
091:
092: tickSharedGroup = new SharedGroup();
093: Transform3D trans = new Transform3D();
094: trans.setScale(0.2f);
095: tickScaleTG = new TransformGroup(trans);
096: tickSharedGroup.addChild(tickScaleTG);
097:
098: LineStripArray tickGeom = new LineStripArray(3,
099: LineStripArray.COORDINATES, new int[] { 3 });
100: tickGeom.setCoordinates(0, new float[] { 0, 0, 0, 0, 1, 0, 0,
101: 1, 0.4f });
102:
103: Shape3D tickShape = new Shape3D(tickGeom);
104: tickScaleTG.addChild(tickShape);
105:
106: }
107:
108: public void setInterpolator(Interpolator interp) {
109: this .interp = interp;
110: }
111:
112: /**
113: * Set the Target for this interpolator
114: *
115: * This is used to extract the LocalToVworld transform for the target
116: * so the points can be positioned correctly
117: */
118: public void setTarget(TransformGroup target) {
119: Transform3D trans = new Transform3D();
120: target.getLocalToVworld(trans);
121: targetOffsetTG.setTransform(trans);
122: }
123:
124: /**
125: * Process the Interpolator and build the geometric representation of
126: * it's path
127: */
128: public void interpolatorChanged() {
129: KBRotPosScaleSplinePathInterpolator in = (KBRotPosScaleSplinePathInterpolator) interp;
130: Transform3D trans = new Transform3D();
131:
132: // Lets have 10 points per Segment
133: float stepSize = 1f / (in.getArrayLength() * 10f);
134: float alphaValue = 0.0f;
135:
136: int loopSize = (int) Math.floor(1f / stepSize) + 1;
137:
138: checkGeometry(loopSize);
139:
140: Enumeration e = tickBG.getAllChildren();
141: for (int i = 0; i < loopSize; i++) {
142: in.computeTransform(alphaValue, trans);
143: alphaValue += stepSize;
144: Point3f p = new Point3f();
145: trans.transform(p);
146: geom.setCoordinate(i, p);
147: ((TransformGroup) e.nextElement()).setTransform(trans);
148: }
149:
150: }
151:
152: /**
153: * Clear the view
154: */
155: public void clear() {
156: pathBG.removeChild(0);
157:
158: tickBG.detach();
159: while (tickBG.numChildren() != 0)
160: tickBG.removeChild(0);
161: rootBG.addChild(tickBG);
162: geom = null;
163: }
164:
165: /**
166: * Check if the geometry structure is the correct size. Create a new
167: * object if it is not.
168: */
169: public void checkGeometry(int geometrySize) {
170: if (geom == null || geom.getVertexCount() != geometrySize) {
171: System.out.println("Creating new geom");
172: geom = new LineStripArray(geometrySize,
173: LineStripArray.COORDINATES,
174: new int[] { geometrySize });
175: geom.setCapability(LineStripArray.ALLOW_COORDINATE_WRITE);
176: geom.setCapability(LineStripArray.ALLOW_COUNT_READ);
177:
178: pathBG.removeChild(0);
179: Shape3D shape = new Shape3D(geom);
180: BranchGroup tmpBG = new BranchGroup();
181: tmpBG.setCapability(BranchGroup.ALLOW_DETACH);
182: tmpBG.addChild(shape);
183: pathBG.addChild(tmpBG);
184:
185: if (tickBG.numChildren() < geometrySize) {
186:
187: tickBG.detach();
188: while (tickBG.numChildren() < geometrySize) {
189: TransformGroup tg = new TransformGroup();
190: tg
191: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
192: tg.addChild(new Link(tickSharedGroup));
193: tickBG.addChild(tg);
194: }
195: rootBG.addChild(tickBG);
196: } else if (tickBG.numChildren() > geometrySize) {
197: tickBG.detach();
198: while (tickBG.numChildren() > geometrySize) {
199: tickBG.removeChild(0);
200: }
201: rootBG.addChild(tickBG);
202: }
203: }
204: }
205:
206: /**
207: * A special implementation of Alpha that lets us gather transforms from
208: * the interpolator
209: */
210: class IPVAlpha extends Alpha {
211:
212: float value = 0f;
213: float stepSize = 0.01f;
214:
215: public IPVAlpha() {
216: super ();
217: }
218:
219: /**
220: * Set the increment size of the alpha value
221: */
222: public void setStepSize(float stepSize) {
223: this .stepSize = stepSize;
224: }
225:
226: /**
227: * Reset value to 0
228: *
229: */
230: public void reset() {
231: value = 0f;
232: }
233:
234: public float getStepSize() {
235: return stepSize;
236: }
237:
238: public float value() {
239: float ret = value;
240: value += stepSize;
241: return ret;
242: }
243:
244: public float value(long atTime) {
245: throw new RuntimeException(
246: "ERROR InterpolatorPathView IPVAlpha.value(atTime) called");
247: }
248: }
249:
250: /**
251: * A transform group that stores each update to it's matrix
252: */
253: class CaptureTG extends TransformGroup {
254:
255: ArrayList transforms = new ArrayList();
256:
257: public CaptureTG() {
258: super ();
259: this .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
260: this .setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
261: }
262:
263: public void setTransform(Transform3D transform) {
264: Matrix4d mat = new Matrix4d();
265: transform.get(mat);
266: transforms.add(mat);
267: }
268:
269: /**
270: * Clear the captured transforms
271: */
272: public void clear() {
273: transforms.clear();
274: }
275:
276: /**
277: * Return the captured transforms
278: */
279: public ArrayList getTransforms() {
280: return transforms;
281: }
282:
283: }
284: }
|