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.vecmath.*;
040: import javax.media.j3d.*;
041:
042: /**
043: * This class is to implement a H-Anim 1.1 compatible avatar.
044: *
045: * @author Silvere Martin-Michiellot
046: * @version 1.1
047: */
048:
049: //search for the string h-anim in every file in this package if you want to find useful comments
050: //on this h-anim implementation
051: //Humanoid could extend Leaf
052: //Segment and Site, each of which containing geometries, could extend Shape3D
053: public class Humanoid extends Object {
054:
055: protected String humanoidName;
056: protected static final String version = "1.1";
057: //corresponding to HumanoidBody;
058: protected Joint humanoidRootJoint;
059: private boolean firstTime;
060: protected BranchGroup branchGroup;
061: protected Transform3D transform3D;
062:
063: /**
064: * Constructs a new Humanoid
065: * @param humanoidName the name of the Humanoid
066: */
067: public Humanoid(String humanoidName) {
068:
069: super ();
070: this .setName(humanoidName);
071: firstTime = true;
072: transform3D = new Transform3D();
073:
074: }
075:
076: /**
077: * Gets the Humanoid name
078: * @return the name of this Humanoid
079: */
080: public String getName() {
081:
082: return this .humanoidName;
083:
084: }
085:
086: /**
087: * Sets the Humanoid name
088: * @param humanoidName the name of this Humanoid
089: */
090: public void setName(String humanoidName) {
091:
092: this .humanoidName = humanoidName;
093:
094: }
095:
096: /**
097: * Gets the static version from which this Humanoid was build
098: * @return version (should always be 1.1)
099: */
100: public String getVersion() {
101:
102: return version;
103:
104: }
105:
106: /**
107: * Gets the root joint for this Humanoid. This hierarchical top joint of the H-Anim specification
108: * @return the top most joint of this Humanoid
109: */
110: public Joint getHumanoidRootJoint() {
111:
112: return this .humanoidRootJoint;
113:
114: }
115:
116: /**
117: * Sets the root joint for this Humanoid. This hierarchical top joint of the H-Anim specification. This Joint should always be given the name Joint.HumanoidRoot
118: * @param HumanoidRootJoint the top most joint of this Humanoid
119: * @exception IllegalArgumentException is the name of the Joint is not Joint.HumanoidRoot
120: */
121: public void setHumanoidRootJoint(Joint humanoidRootJoint) {
122:
123: if (Joint.getJointIdentifierNumber(humanoidRootJoint.getName()) == Joint.HumanoidRoot) {
124: //according to h-anim spec., vl5 and sacroiliac would be acceptable root joints
125: //I have chosen to implement a higher level node: humanoidRoot
126: //which in turn has two children: vl5 and sacroiliac
127: //Every computer developper should understand this choice
128: //since it makes everything easier
129: this .humanoidRootJoint = humanoidRootJoint;
130: } else {
131: throw new java.lang.IllegalArgumentException(
132: "humanoidRootJoint is not a named HumanoidRoot.");
133: }
134:
135: }
136:
137: /**
138: * Gets the Java3D BranchGroup corresponding to this Humanoid description. Every Joint should be added to the hierarchy before calling this method. If you nevertheless need to add some more Joints, use refreshBranchGroup(). Please note that manipulations of the Humanoid that were done in between (like Gestures) may not reflect correct values thereafter. Multiple calls to getBranchGroup() will always return the same BranchGroup regardless of addition of a new Joint.
139: * Every element in the resulting BranchGroup has its userData set to the Name of the corresponding Humanoid part.
140: * As of this version, we do NOT use
141: * for Humanoid: info, version, viewpoints
142: * for Joint: uLimit, lLimit, limitOrientation, stiffness
143: * for Segment: centerOfMass, mass, momentsOfInertia
144: * for Displacer: coordIndex, displacements
145: * (Displacers can be retrieved as a branchGroup from elsewhere)
146: * H-Anim doesn't propose any constraint to implement these fields.
147: * @return the BranchGroup that completely describes the H-Anim avatar in Java3D
148: * @see com.db.hanim.Humanoid#refreshBranchGroup()
149: */
150: public BranchGroup getBranchGroup() {
151: //retrieves the geometry to be added to the Java3D graph
152: //Every element in the resulting BranchGroup has its userData set to the Name of the corresponding Humanoid part.
153: //
154: //As of this version, we do NOT use
155: //for Humanoid: info, version, viewpoints
156: //for Joint: uLimit, lLimit, limitOrientation, stiffness
157: //for Segment: centerOfMass, mass, momentsOfInertia
158: //for Displacer: coordIndex, displacements
159: //h-anim doesn't propose any constraint to implement these fields.
160: //Moreover, for Joint, Segment and Site: center and scaleOrientation are stored with other transformations in ONE Transform3D
161:
162: TransformGroup transformGroup;
163: TransformGroup subTransformGroup;
164: Transform3D transform3D;
165: Joint joint;
166:
167: if (firstTime) {
168: branchGroup = new BranchGroup();
169: branchGroup.setCapability(Node.ALLOW_BOUNDS_READ);
170: branchGroup.setCapability(Group.ALLOW_CHILDREN_READ);
171: branchGroup.setCapability(Group.ALLOW_CHILDREN_WRITE);
172: branchGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
173: //BranchGroup specific capability bits have to be set by user afterwards
174: branchGroup.setUserData(this .getName());
175:
176: transform3D = new Transform3D();
177: this .getTransform(transform3D);
178: transformGroup = new TransformGroup(transform3D);
179: setFullCapabilitiesForTransformGroup(transformGroup);
180: transformGroup.setUserData(this .getName());
181:
182: branchGroup.addChild(transformGroup);
183:
184: joint = this .getHumanoidRootJoint();
185: if (joint != null) {
186: transform3D = new Transform3D();
187: subTransformGroup = new TransformGroup(transform3D);
188: setFullCapabilitiesForTransformGroup(subTransformGroup);
189: browseFullTree(joint, subTransformGroup);
190: transformGroup.addChild(subTransformGroup);
191: }
192:
193: firstTime = false;
194: }
195:
196: return branchGroup;
197:
198: }
199:
200: /**
201: * Gets the Java3D BranchGroup corresponding to this Humanoid description. This method should only be called after a call to getBranchGroup() a change to the Humanoid hierarchy.
202: * @return the BranchGroup that completely describes the H-Anim avatar in Java3D
203: * @see com.db.hanim.Humanoid#getBranchGroup()
204: */
205: public BranchGroup refreshBranchGroup() {
206:
207: firstTime = true;
208: return this .getBranchGroup();
209:
210: }
211:
212: /**
213: * Gets the H-Anim level of Compatiblity for this Humanoid computed using HAnimLevelsOfAnimation.
214: * @return the H-Anim level of Compatiblity for this Humanoid ranging from 0 to 4. Minus 1 is returned if this Humanoid is not compatible with any level of animation. Most Humanoids will return 0 or 1 for real time applications.
215: * @see com.db.hanim.HAnimLevelsOfAnimation
216: */
217: public int getLevelOfCompatibility() {
218: //returns -1 if no level of compatiblity is found
219:
220: HAnimLevelsOfAnimation hAnimLevelsOfAnimation;
221:
222: hAnimLevelsOfAnimation = new HAnimLevelsOfAnimation();
223:
224: return hAnimLevelsOfAnimation.getLevelOfCompatibility(this );
225:
226: }
227:
228: /**
229: * Modifies the center of the joints l_eyeball_joint and r_eyeball_joint and the sites l_tragion and r_tragion and skull_tip with the values set in PhysicalBody
230: * @param physicalBody to take the values from
231: */
232: public void setAvatarUsingPhysicalBody(PhysicalBody physicalBody) {
233: //finds the joints l_eyeball_joint and r_eyeball_joint
234: //finds the sites l_tragion and r_tragion and skull_tip
235: //and set their center with the values found in physicalBody
236: //this is not in h-anim since it also relies on java3d concepts
237: //please note that this is an experimental feature
238: //(mostly because the two specs don't use the same defaults points,
239: // for total height and ears)
240:
241: Joint l_eyeballJoint;
242: Joint r_eyeballJoint;
243: Joint skullbaseJoint;
244: Segment skullSegment;
245: Site l_tragionSite;
246: Site skull_tipSite;
247: Point3d skull_tipSiteCenter;
248: Site r_tragionSite;
249:
250: HashSet hashSet;
251: boolean found;
252: Iterator iterator;
253: Site site;
254:
255: Point3d leftEarPosition;
256: Point3d leftEyePosition;
257: double nominalEyeHeightFromGround;
258: Point3d rightEarPosition;
259: Point3d rightEyePosition;
260:
261: leftEarPosition = new Point3d();
262: leftEyePosition = new Point3d();
263: rightEarPosition = new Point3d();
264: rightEyePosition = new Point3d();
265:
266: physicalBody.getLeftEarPosition(leftEarPosition);
267: physicalBody.getLeftEyePosition(leftEyePosition);
268: nominalEyeHeightFromGround = physicalBody
269: .getNominalEyeHeightFromGround();
270: physicalBody.getRightEarPosition(rightEarPosition);
271: physicalBody.getRightEyePosition(rightEyePosition);
272:
273: l_eyeballJoint = this .findJoint(Joint
274: .getJointIdentifierName(Joint.l_eyeball_joint));
275: r_eyeballJoint = this .findJoint(Joint
276: .getJointIdentifierName(Joint.r_eyeball_joint));
277: skullbaseJoint = this .findJoint(Joint
278: .getJointIdentifierName(Joint.skullbase));
279:
280: if ((l_eyeballJoint != null) && (r_eyeballJoint != null)) {
281:
282: l_eyeballJoint.setCenter(leftEyePosition);
283: r_eyeballJoint.setCenter(rightEyePosition);
284:
285: if (skullbaseJoint != null) {
286: skullSegment = skullbaseJoint.getSegment();
287: if (skullSegment != null) {
288: hashSet = skullSegment.getSites();
289: if (!hashSet.isEmpty()) {
290: iterator = hashSet.iterator();
291: l_tragionSite = null;
292: skull_tipSite = null;
293: r_tragionSite = null;
294: while (iterator.hasNext()) {
295: site = (Site) iterator.next();
296: if (site.getName() == Site
297: .getSiteIdentifierName(Site.l_tragion)) {
298: l_tragionSite = site;
299: } else if (site.getName() == Site
300: .getSiteIdentifierName(Site.skull_tip)) {
301: skull_tipSite = site;
302: } else if (site.getName() == Site
303: .getSiteIdentifierName(Site.r_tragion)) {
304: r_tragionSite = site;
305: }
306: }
307: if ((l_tragionSite != null)
308: && (r_tragionSite != null)
309: && (skull_tipSite != null)) {
310:
311: skull_tipSiteCenter = new Point3d();
312: l_tragionSite.setCenter(leftEarPosition);
313: skull_tipSite
314: .getCenter(skull_tipSiteCenter);
315: skull_tipSiteCenter.y = nominalEyeHeightFromGround;
316: skull_tipSite
317: .setCenter(skull_tipSiteCenter);
318: r_tragionSite.setCenter(rightEarPosition);
319:
320: }
321: }
322: }
323: }
324:
325: }
326:
327: }
328:
329: /**
330: * Builds a PhysicalBody using the center of the joints l_eyeball_joint and r_eyeball_joint and the sites l_tragion and r_tragion and skull_tip of the Humanoid
331: * @return PhysicalBody built using the center values
332: */
333: public PhysicalBody getPhysicalBodyUsingAvatar() {
334: //finds the joints l_eyeball_joint and r_eyeball_joint
335: //finds the sites l_tragion and r_tragion and skull_tip
336: //and builds up a new PhysicalBody based on their center
337: //this is not in h-anim since it also relies on java3d concepts
338: //please note that this is an experimental feature
339: //(mostly because the two specs don't use the same defaults points,
340: // for total height and ears)
341:
342: PhysicalBody physicalBody;
343:
344: Joint l_eyeballJoint;
345: Joint r_eyeballJoint;
346: Joint skullbaseJoint;
347: Segment skullSegment;
348: Site l_tragionSite;
349: Site skull_tipSite;
350: Point3d skull_tipSiteCenter;
351: Site r_tragionSite;
352:
353: HashSet hashSet;
354: boolean found;
355: Iterator iterator;
356: Site site;
357:
358: Point3d leftEarPosition;
359: Point3d leftEyePosition;
360: double nominalEyeHeightFromGround;
361: Point3d rightEarPosition;
362: Point3d rightEyePosition;
363:
364: physicalBody = new PhysicalBody();
365:
366: leftEarPosition = new Point3d();
367: leftEyePosition = new Point3d();
368: rightEarPosition = new Point3d();
369: rightEyePosition = new Point3d();
370:
371: l_eyeballJoint = this .findJoint(Joint
372: .getJointIdentifierName(Joint.l_eyeball_joint));
373: r_eyeballJoint = this .findJoint(Joint
374: .getJointIdentifierName(Joint.r_eyeball_joint));
375: skullbaseJoint = this .findJoint(Joint
376: .getJointIdentifierName(Joint.skullbase));
377:
378: if ((l_eyeballJoint != null) && (r_eyeballJoint != null)) {
379:
380: l_eyeballJoint.getCenter(leftEyePosition);
381: r_eyeballJoint.getCenter(rightEyePosition);
382:
383: physicalBody.setLeftEyePosition(leftEyePosition);
384: physicalBody.setRightEyePosition(rightEyePosition);
385:
386: if (skullbaseJoint != null) {
387: skullSegment = skullbaseJoint.getSegment();
388: if (skullSegment != null) {
389: hashSet = skullSegment.getSites();
390: if (!hashSet.isEmpty()) {
391: iterator = hashSet.iterator();
392: l_tragionSite = null;
393: skull_tipSite = null;
394: r_tragionSite = null;
395: while (iterator.hasNext()) {
396: site = (Site) iterator.next();
397: if (site.getName() == Site
398: .getSiteIdentifierName(Site.l_tragion)) {
399: l_tragionSite = site;
400: } else if (site.getName() == Site
401: .getSiteIdentifierName(Site.skull_tip)) {
402: skull_tipSite = site;
403: } else if (site.getName() == Site
404: .getSiteIdentifierName(Site.r_tragion)) {
405: r_tragionSite = site;
406: }
407: }
408: if ((l_tragionSite != null)
409: && (r_tragionSite != null)
410: && (skull_tipSite != null)) {
411:
412: skull_tipSiteCenter = new Point3d();
413: l_tragionSite.getCenter(leftEarPosition);
414: skull_tipSite
415: .getCenter(skull_tipSiteCenter);
416: nominalEyeHeightFromGround = skull_tipSiteCenter.y;
417: r_tragionSite.getCenter(rightEarPosition);
418:
419: physicalBody
420: .setLeftEarPosition(leftEarPosition);
421: physicalBody
422: .setNominalEyeHeightFromGround(nominalEyeHeightFromGround);
423: physicalBody
424: .setRightEarPosition(rightEarPosition);
425:
426: }
427: }
428: }
429: }
430:
431: }
432: return physicalBody;
433:
434: }
435:
436: /**
437: * Gets the Transform3D that defines the overall postion of the Humanoid
438: * @param transform3D to put into position and orientation
439: */
440: //java3D like call (not a function)...
441: public void getTransform(Transform3D transform3D) {
442:
443: transform3D.set(this .transform3D);
444:
445: }
446:
447: /**
448: * Sets the Transform3D that defines the overall postion of the Humanoid
449: * @param transform3D the new position and orientation
450: */
451: public void setTransform(Transform3D humanoidTransform) {
452:
453: this .transform3D = humanoidTransform;
454:
455: }
456:
457: /**
458: * Gets a Joint from the Joints defined in this Humanoid hierarchy
459: * @param String the name used for that Joint
460: * @return the Joint with the given name
461: */
462: public Joint findJoint(String JointName) {
463:
464: return find1Joint(this .getHumanoidRootJoint(), JointName);
465:
466: }
467:
468: private Joint find1Joint(Joint rootJoint, String jointName) {
469:
470: Joint resultJoint;
471: HashSet hashSet;
472: Iterator iterator;
473: boolean found;
474:
475: if (rootJoint.getName().equals(jointName)) {
476: return rootJoint;
477: } else {
478: hashSet = rootJoint.getChildren();
479: if (hashSet.isEmpty()) {
480: return null;
481: } else {
482: iterator = hashSet.iterator();
483: found = false;
484: resultJoint = null;
485: while ((iterator.hasNext()) && (!found)) {
486: resultJoint = find1Joint((Joint) iterator.next(),
487: jointName);
488: found = (resultJoint != null);
489: }
490: return resultJoint;
491: }
492:
493: }
494:
495: }
496:
497: /**
498: * Gets a Segment from the Segments defined in this Humanoid hierarchy
499: * @param String the name used for that Segment
500: * @return the Segment with the given name
501: */
502: public Segment findSegment(String SegmentName) {
503:
504: return find1Segment(this .getHumanoidRootJoint().getSegment(),
505: SegmentName);
506:
507: }
508:
509: private Segment find1Segment(Segment rootSegment, String segmentName) {
510:
511: Segment resultSegment;
512: HashSet hashSet;
513: Iterator iterator;
514: boolean found;
515:
516: if (rootSegment.getName().equals(segmentName)) {
517: return rootSegment;
518: } else {
519: if (rootSegment.getJoint() != null) {
520: hashSet = rootSegment.getJoint().getChildren();
521: if (hashSet.isEmpty()) {
522: return null;
523: } else {
524: iterator = hashSet.iterator();
525: found = false;
526: resultSegment = null;
527: while ((iterator.hasNext()) && (!found)) {
528: resultSegment = find1Segment((Segment) iterator
529: .next(), segmentName);
530: found = (resultSegment != null);
531: }
532: return resultSegment;
533: }
534:
535: } else {
536: return null;
537: }
538:
539: }
540:
541: }
542:
543: /**
544: * Gets a Segment from the Segments defined in this Humanoid hierarchy
545: * @param String the name used for that Segment
546: * @return the Segment with the given name
547: */
548: public Displacer findDisplacer(String displacerName) {
549:
550: return find1Displacer(this .getHumanoidRootJoint(),
551: displacerName);
552:
553: }
554:
555: private Displacer find1Displacer(Joint rootJoint,
556: String displacerName) {
557:
558: Displacer resultDisplacer;
559: HashSet hashSet;
560: Iterator iterator;
561: boolean found;
562:
563: resultDisplacer = null;
564:
565: if (rootJoint.getChildren() != null) {
566: hashSet = rootJoint.getChildren();
567: iterator = hashSet.iterator();
568: found = false;
569: while ((iterator.hasNext()) && (!found)) {
570: resultDisplacer = find1Displacer((Joint) iterator
571: .next(), displacerName);
572: found = (resultDisplacer != null);
573: }
574: if (found) {
575: return resultDisplacer;
576: } else {
577: if (rootJoint.getSegment() != null) {
578: hashSet = rootJoint.getSegment().getDisplacers();
579: found = false;
580: resultDisplacer = null;
581: while ((iterator.hasNext()) && (!found)) {
582: resultDisplacer = (Displacer) iterator.next();
583: found = (resultDisplacer.getName() == displacerName);
584: }
585: if (found) {
586: return resultDisplacer;
587: } else {
588: return null;
589: }
590: } else {
591: return null;
592: }
593: }
594:
595: } else {
596: return null;
597: }
598:
599: }
600:
601: /**
602: * Gets the diplacers in the whole hierarchy (not the Java3D corresponding code)
603: * @return the HashSet of the diplacers in the humanoid hierarchy
604: */
605: public HashSet getDisplacers() {
606:
607: return getAllDisplacers(this .getHumanoidRootJoint(),
608: new HashSet());
609:
610: }
611:
612: private HashSet getAllDisplacers(Joint rootJoint, HashSet hashSet) {
613:
614: HashSet resultDisplacers;
615: Iterator iterator;
616: boolean found;
617:
618: resultDisplacers = new HashSet();
619: if (rootJoint.getChildren() != null) {
620: iterator = rootJoint.getChildren().iterator();
621: while (iterator.hasNext()) {
622: resultDisplacers.addAll(getAllDisplacers(
623: (Joint) iterator.next(), new HashSet()));
624: }
625: }
626: if (rootJoint.getSegment() != null) {
627: resultDisplacers.addAll(rootJoint.getSegment()
628: .getDisplacers());
629: }
630:
631: return resultDisplacers;
632:
633: }
634:
635: //P' = T × C × R × SR × S × -SR × -C × P
636: private void browseFullTree(Joint joint,
637: TransformGroup transformGroup) {
638: //it is assumed that joint and its corresponding transformGroup are not null
639:
640: TransformGroup subTransformGroup;
641: Transform3D transform3D;
642: Joint childJoint;
643: Segment segment;
644: Site site;
645: Displacer displacer;
646: Iterator iterator;
647:
648: TransformGroup transformGroupTranslation;
649: TransformGroup transformGroupCenter;
650: TransformGroup transformGroupRotation;
651: TransformGroup transformGroupScaleRotation;
652: TransformGroup transformGroupScale;
653: TransformGroup transformGroupMinusScaleRotation;
654: TransformGroup transformGroupMinusCenter;
655: Transform3D transform3DTranslation;
656: Transform3D transform3DCenter;
657: Transform3D transform3DRotation;
658: Transform3D transform3DScaleRotation;
659: Transform3D transform3DScale;
660: Transform3D transform3DMinusScaleRotation;
661: Transform3D transform3DMinusCenter;
662:
663: Vector3d vector3dTranslation;
664: Quat4d quat4d;
665: Vector3d vector3dScale;
666: Matrix3d matrix3d;
667: Point3d point3d;
668: Vector3d vector3dCenter;
669:
670: TransformGroup siteTransformGroup;
671: Transform3D siteTransform3D;
672:
673: TransformGroup siteTransformGroupTranslation;
674: TransformGroup siteTransformGroupCenter;
675: TransformGroup siteTransformGroupRotation;
676: TransformGroup siteTransformGroupScaleRotation;
677: TransformGroup siteTransformGroupScale;
678: TransformGroup siteTransformGroupMinusScaleRotation;
679: TransformGroup siteTransformGroupMinusCenter;
680: Transform3D siteTransform3DTranslation;
681: Transform3D siteTransform3DCenter;
682: Transform3D siteTransform3DRotation;
683: Transform3D siteTransform3DScaleRotation;
684: Transform3D siteTransform3DScale;
685: Transform3D siteTransform3DMinusScaleRotation;
686: Transform3D siteTransform3DMinusCenter;
687:
688: Vector3d vector3dSiteTranslation;
689: Quat4d quat4dSite;
690: Vector3d vector3dSiteScale;
691: Matrix3d matrix3dSite;
692: Point3d point3dSite;
693: Vector3d vector3dSiteCenter;
694:
695: transformGroup.setUserData(joint.getName());
696:
697: segment = joint.getSegment();
698:
699: vector3dTranslation = new Vector3d();
700: quat4d = new Quat4d();
701: vector3dScale = new Vector3d();
702: matrix3d = new Matrix3d();
703: point3d = new Point3d();
704:
705: transform3D = new Transform3D();
706:
707: joint.getTransform(transform3D);
708: transform3D.get(vector3dTranslation);
709: transform3D.get(quat4d);
710: transform3D.getScale(vector3dScale);
711: transform3D.getRotationScale(matrix3d);
712: joint.getCenter(point3d);
713:
714: vector3dCenter = new Vector3d(point3d.x, point3d.y, point3d.z);
715:
716: transform3DMinusCenter = new Transform3D();
717: transform3DMinusCenter.set(vector3dCenter);
718: transform3DMinusCenter.invert();
719: transformGroupMinusCenter = new TransformGroup(
720: transform3DMinusCenter);
721: setFullCapabilitiesForTransformGroup(transformGroupMinusCenter);
722: transformGroupMinusCenter
723: .setUserData(new String("MinusCenter"));
724: transform3DMinusScaleRotation = new Transform3D();
725: transform3DMinusScaleRotation.set(matrix3d);
726: transform3DMinusScaleRotation.invert();
727: transformGroupMinusScaleRotation = new TransformGroup(
728: transform3DMinusScaleRotation);
729: setFullCapabilitiesForTransformGroup(transformGroupMinusScaleRotation);
730: transformGroupMinusScaleRotation.setUserData(new String(
731: "MinusScaleRotation"));
732: transformGroupMinusScaleRotation
733: .addChild(transformGroupMinusCenter);
734: transform3DScale = new Transform3D();
735: transform3DScale.set(vector3dScale);
736: transformGroupScale = new TransformGroup(transform3DScale);
737: setFullCapabilitiesForTransformGroup(transformGroupScale);
738: transformGroupScale.setUserData(new String("Scale"));
739: transformGroupScale.addChild(transformGroupMinusScaleRotation);
740: transform3DScaleRotation = new Transform3D();
741: transform3DScaleRotation.set(matrix3d);
742: transformGroupScaleRotation = new TransformGroup(
743: transform3DScaleRotation);
744: setFullCapabilitiesForTransformGroup(transformGroupScaleRotation);
745: transformGroupScaleRotation.setUserData(new String(
746: "ScaleRotation"));
747: transformGroupScaleRotation.addChild(transformGroupScale);
748: transform3DRotation = new Transform3D();
749: transform3DRotation.set(quat4d);
750: transformGroupRotation = new TransformGroup(transform3DRotation);
751: setFullCapabilitiesForTransformGroup(transformGroupRotation);
752: transformGroupRotation.setUserData(new String("Rotation"));
753: transformGroupRotation.addChild(transformGroupScaleRotation);
754: transform3DCenter = new Transform3D();
755: transform3DCenter.set(vector3dCenter);
756: transformGroupCenter = new TransformGroup(transform3DCenter);
757: setFullCapabilitiesForTransformGroup(transformGroupCenter);
758: transformGroupCenter.setUserData(new String("Center"));
759: transformGroupCenter.addChild(transformGroupRotation);
760: transform3DTranslation = new Transform3D();
761: transform3DTranslation.set(vector3dTranslation);
762: transformGroupTranslation = new TransformGroup(
763: transform3DTranslation);
764: setFullCapabilitiesForTransformGroup(transformGroupTranslation);
765: transformGroupTranslation.setUserData(joint.getName());
766: transformGroupTranslation.addChild(transformGroupCenter);
767:
768: transformGroup.addChild(transformGroupTranslation);
769:
770: if (segment != null) {
771:
772: transformGroupMinusCenter.addChild(segment.getNode());
773:
774: segment.getNode().setUserData(segment.getName());
775:
776: //capability bits for Node should be set up by user before userSegment.setNode(userNode);
777:
778: iterator = segment.getSites().iterator();
779:
780: while (iterator.hasNext()) {
781:
782: site = (Site) iterator.next();
783: vector3dSiteTranslation = new Vector3d();
784: quat4dSite = new Quat4d();
785: vector3dSiteScale = new Vector3d();
786: matrix3dSite = new Matrix3d();
787: point3dSite = new Point3d();
788:
789: siteTransform3D = new Transform3D();
790:
791: site.getTransform(siteTransform3D);
792: transform3D.get(vector3dSiteTranslation);
793: transform3D.get(quat4dSite);
794: transform3D.getScale(vector3dSiteScale);
795: transform3D.getRotationScale(matrix3dSite);
796: site.getCenter(point3dSite);
797:
798: vector3dSiteCenter = new Vector3d(point3dSite.x,
799: point3dSite.y, point3dSite.z);
800:
801: siteTransform3DMinusCenter = new Transform3D();
802: siteTransform3DMinusCenter.set(vector3dSiteCenter);
803: siteTransform3DMinusCenter.invert();
804: siteTransformGroupMinusCenter = new TransformGroup(
805: siteTransform3DMinusCenter);
806: setFullCapabilitiesForTransformGroup(siteTransformGroupMinusCenter);
807: siteTransformGroupMinusCenter.setUserData(new String(
808: "MinusCenter"));
809: siteTransformGroupMinusCenter.addChild(site.getNode());
810: siteTransform3DMinusScaleRotation = new Transform3D();
811: siteTransform3DMinusScaleRotation.set(matrix3dSite);
812: siteTransform3DMinusScaleRotation.invert();
813: siteTransformGroupMinusScaleRotation = new TransformGroup(
814: siteTransform3DMinusScaleRotation);
815: setFullCapabilitiesForTransformGroup(siteTransformGroupMinusScaleRotation);
816: siteTransformGroupMinusScaleRotation
817: .setUserData(new String("MinusScaleRotation"));
818: siteTransformGroupMinusScaleRotation
819: .addChild(siteTransformGroupMinusCenter);
820: siteTransform3DScale = new Transform3D();
821: siteTransform3DScale.set(vector3dScale);
822: siteTransformGroupScale = new TransformGroup(
823: siteTransform3DScale);
824: setFullCapabilitiesForTransformGroup(siteTransformGroupScale);
825: siteTransformGroupScale
826: .setUserData(new String("Scale"));
827: siteTransformGroupScale
828: .addChild(siteTransformGroupMinusScaleRotation);
829: siteTransform3DScaleRotation = new Transform3D();
830: siteTransform3DScaleRotation.set(matrix3dSite);
831: siteTransformGroupScaleRotation = new TransformGroup(
832: siteTransform3DScaleRotation);
833: setFullCapabilitiesForTransformGroup(siteTransformGroupScaleRotation);
834: siteTransformGroupScaleRotation.setUserData(new String(
835: "ScaleRotation"));
836: siteTransformGroupScaleRotation
837: .addChild(siteTransformGroupScale);
838: siteTransform3DRotation = new Transform3D();
839: siteTransform3DRotation.set(quat4d);
840: siteTransformGroupRotation = new TransformGroup(
841: siteTransform3DRotation);
842: setFullCapabilitiesForTransformGroup(siteTransformGroupRotation);
843: siteTransformGroupRotation.setUserData(new String(
844: "Rotation"));
845: siteTransformGroupRotation
846: .addChild(siteTransformGroupScaleRotation);
847: siteTransform3DCenter = new Transform3D();
848: siteTransform3DCenter.set(vector3dSiteCenter);
849: siteTransformGroupCenter = new TransformGroup(
850: siteTransform3DCenter);
851: setFullCapabilitiesForTransformGroup(siteTransformGroupCenter);
852: siteTransformGroupCenter.setUserData(new String(
853: "Center"));
854: siteTransformGroupCenter
855: .addChild(siteTransformGroupRotation);
856: siteTransform3DTranslation = new Transform3D();
857: siteTransform3DTranslation.set(vector3dSiteTranslation);
858: siteTransformGroupTranslation = new TransformGroup(
859: siteTransform3DTranslation);
860: setFullCapabilitiesForTransformGroup(siteTransformGroupTranslation);
861: siteTransformGroupTranslation.setUserData(site
862: .getName());
863: siteTransformGroupTranslation
864: .addChild(siteTransformGroupCenter);
865:
866: transformGroupMinusCenter
867: .addChild(siteTransformGroupTranslation);
868:
869: site.getNode().setUserData(site.getName());
870:
871: //capability bits for Node should be set up by user before userSegment.setNode(userNode);
872:
873: //Displacer are implemented elsewhere as a BranchGroup with Morphs just under the
874: //top level BranchGroup
875:
876: }
877:
878: iterator = joint.getChildren().iterator();
879:
880: while (iterator.hasNext()) {
881: childJoint = (Joint) iterator.next();
882: browseFullTree(childJoint, transformGroupMinusCenter);
883: transform3D = new Transform3D();
884: childJoint.getTransform(transform3D);
885: subTransformGroup = new TransformGroup(transform3D);
886: setFullCapabilitiesForTransformGroup(subTransformGroup);
887: browseFullTree(childJoint, subTransformGroup);
888: transformGroupMinusCenter.addChild(subTransformGroup);
889: }
890:
891: }
892:
893: }
894:
895: private TransformGroup setFullCapabilitiesForTransformGroup(
896: TransformGroup transformGroup) {
897:
898: transformGroup
899: .setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
900: transformGroup
901: .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
902: transformGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
903: transformGroup.setCapability(Group.ALLOW_CHILDREN_READ);
904: transformGroup.setCapability(Group.ALLOW_CHILDREN_WRITE);
905: transformGroup.setCapability(Group.ALLOW_COLLISION_BOUNDS_READ);
906: transformGroup
907: .setCapability(Group.ALLOW_COLLISION_BOUNDS_WRITE);
908: transformGroup
909: .setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
910: transformGroup
911: .setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);
912: transformGroup.setCapability(Node.ALLOW_BOUNDS_READ);
913: transformGroup.setCapability(Node.ALLOW_BOUNDS_WRITE);
914: transformGroup.setCapability(Node.ALLOW_COLLIDABLE_READ);
915: transformGroup.setCapability(Node.ALLOW_COLLIDABLE_WRITE);
916: transformGroup.setCapability(Node.ALLOW_LOCAL_TO_VWORLD_READ);
917: transformGroup.setCapability(Node.ALLOW_PICKABLE_READ);
918: transformGroup.setCapability(Node.ALLOW_PICKABLE_WRITE);
919: transformGroup.setCapability(Node.ENABLE_COLLISION_REPORTING);
920: transformGroup.setCapability(Node.ENABLE_PICK_REPORTING);
921:
922: return transformGroup;
923:
924: }
925: }
|