001: /*
002: * Copyright (c) 2000-2001 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, but not to modify or redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silvere Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: * @Author: Silvere Martin-Michiellot for Digital Biosphere
032: * @Version: 1.1 (to stay in touch with h-anim)
033: *
034: */
035:
036: package com.db.hanim;
037:
038: import java.util.*;
039: import javax.media.j3d.*;
040: import javax.vecmath.*;
041:
042: /**
043: * This class is to implement the actual displacement of a Displacer.
044: *
045: * @author Silvere Martin-Michiellot
046: * @version 1.1
047: */
048:
049: //please use a Shape3D as segment node
050: public class Displacement {
051:
052: protected Humanoid humanoid;
053: protected long duration;
054: protected int loop;
055: protected Alpha alpha;
056:
057: public Displacement(Humanoid humanoid, long duration, int loop) {
058:
059: this .humanoid = humanoid;
060: this .duration = duration;
061: this .alpha = new Alpha(this .loop, Alpha.INCREASING_ENABLE, 0,
062: 0, this .duration, 0, 0, 0, 0, 0);
063: this .loop = loop;
064:
065: }
066:
067: //retrieves displacements for full humanoid
068: public BranchGroup getDisplacements() {
069:
070: Enumeration enumeration;
071: Hashtable hashtable;
072: BranchGroup branchGroup;
073: BranchGroup subBranchGroup;
074: Vector vector;
075: Segment segment;
076: Displacer displacer;
077:
078: branchGroup = new BranchGroup();
079: vector = new Vector();
080: hashtable = this .getDisplacers();
081: enumeration = hashtable.keys();
082:
083: while (enumeration.hasMoreElements()) {
084: segment = (Segment) enumeration.nextElement();
085: displacer = (Displacer) hashtable.get(segment);
086: subBranchGroup = this .getDisplacement(segment, displacer);
087: vector.add(subBranchGroup.getChild(0));
088: vector.add(subBranchGroup.getChild(1));
089: }
090:
091: return this .addAllChildren(branchGroup, vector.elements());
092:
093: }
094:
095: //branchgroup should be obtained by using getDisplacements() or getDisplacement()
096: public void doDisplacer(BranchGroup branchGroup, Displacer displacer) {
097:
098: Enumeration enumeration;
099: Object object;
100:
101: enumeration = branchGroup.getAllChildren();
102:
103: while (enumeration.hasMoreElements()) {
104:
105: object = enumeration.nextElement();
106: if (object instanceof MorphingBehavior) {
107: if (((MorphingBehavior) object).getUserData() == displacer) {
108: ((MorphingBehavior) object).restart();
109: }
110: }
111:
112: }
113:
114: }
115:
116: private Hashtable getDisplacers() {
117:
118: return getAllDisplacers(humanoid.getHumanoidRootJoint(),
119: new Hashtable());
120:
121: }
122:
123: private Hashtable getAllDisplacers(Joint rootJoint,
124: Hashtable hashtable) {
125:
126: Hashtable resultDisplacers;
127: Iterator iterator;
128: boolean found;
129:
130: resultDisplacers = new Hashtable();
131: if (rootJoint.getChildren() != null) {
132: iterator = rootJoint.getChildren().iterator();
133: while (iterator.hasNext()) {
134: resultDisplacers.putAll(getAllDisplacers(
135: (Joint) iterator.next(), new Hashtable()));
136: }
137: }
138: if (rootJoint.getSegment() != null) {
139:
140: iterator = rootJoint.getSegment().getDisplacers()
141: .iterator();
142:
143: while (iterator.hasNext()) {
144: resultDisplacers.put(iterator.next(), rootJoint
145: .getSegment());
146: }
147:
148: }
149:
150: return resultDisplacers;
151:
152: }
153:
154: //sort of multiple call to getDisplacement but the resulting branchGoup is less complex
155: public BranchGroup getDisplacements(Segment segment) {
156:
157: BranchGroup branchGroup;
158: BranchGroup subBranchGroup;
159: Iterator iterator;
160: Vector vector;
161:
162: branchGroup = new BranchGroup();
163: vector = new Vector();
164:
165: iterator = segment.getDisplacers().iterator();
166: while (iterator.hasNext()) {
167: subBranchGroup = this .getDisplacement(segment,
168: (Displacer) iterator.next());
169: vector.add(subBranchGroup.getChild(0));
170: vector.add(subBranchGroup.getChild(1));
171: }
172:
173: return this .addAllChildren(branchGroup, vector.elements());
174:
175: }
176:
177: //displacer must be a displacer of segment
178: public BranchGroup getDisplacement(Segment segment,
179: Displacer displacer) {
180:
181: int[] index;
182: Point3d[] points;
183:
184: BranchGroup branchGroup;
185: GeometryArray[] geometryArrays;
186: Morph morph;
187: MorphingBehavior morphingBehavior;
188: Shape3D shape3D;
189: GeometryArray geometryArray1;
190: GeometryArray geometryArray2;
191:
192: branchGroup = new BranchGroup();
193:
194: if (segment.getDisplacers().contains(displacer)) {
195: if (segment.getNode() instanceof Shape3D) {
196: shape3D = (Shape3D) segment.getNode();
197:
198: if (shape3D.getGeometry() instanceof GeometryArray) {
199: geometryArray1 = (GeometryArray) shape3D
200: .getGeometry();
201: geometryArray2 = (GeometryArray) geometryArray1
202: .cloneNodeComponent(true);
203: index = displacer.getCoordIndex();
204: points = displacer.getDisplacements();
205:
206: if (points.length == index.length) {
207: for (int i = 0; i < index.length; i++) {
208: geometryArray2.setCoordinate(index[i],
209: points[i]);
210: }
211:
212: geometryArrays = new GeometryArray[2];
213:
214: geometryArrays[0] = geometryArray1;
215: geometryArrays[1] = geometryArray2;
216:
217: morph = new Morph(geometryArrays, shape3D
218: .getAppearance());
219: morph.setCapability(Morph.ALLOW_WEIGHTS_READ);
220: morph.setCapability(Morph.ALLOW_WEIGHTS_WRITE);
221:
222: branchGroup.addChild(morph);
223:
224: // Finally, create the morphing behavior
225: morphingBehavior = new MorphingBehavior(alpha,
226: morph);
227: morphingBehavior
228: .setSchedulingBounds(this .humanoid
229: .getBranchGroup().getBounds());
230: morphingBehavior.setUserData(displacer);
231:
232: branchGroup.addChild(morphingBehavior);
233:
234: }
235:
236: }
237: }
238: }
239:
240: return branchGroup;
241:
242: }
243:
244: private BranchGroup addAllChildren(BranchGroup branchGroup,
245: Enumeration enumeration) {
246:
247: while (enumeration.hasMoreElements()) {
248: branchGroup.addChild((Node) enumeration.nextElement());
249: }
250:
251: return branchGroup;
252:
253: }
254:
255: }
|