001: /*
002: * $RCSfile: Morph.java,v $
003: *
004: * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.6 $
028: * $Date: 2008/02/28 20:17:26 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.Hashtable;
035: import javax.vecmath.*;
036:
037: /**
038: * The Morph leaf node permits an application to morph between
039: * multiple GeometryArrays. The Morph node contains a single
040: * Appearance node, an array of GeometryArray objects, and an array of
041: * corresponding weights. The Morph node combines these GeometryArrays
042: * into an aggregate shape based on each GeometryArray's corresponding
043: * weight. Typically, Behavior nodes will modify the weights to
044: * achieve various morphing effects.
045: *
046: * <p>
047: * The following restrictions apply to each GeometryArray object
048: * in the specified array of GeometryArray objects:
049: *
050: * <ul>
051: * <li>
052: * All <i>N</i> geometry arrays must be of the
053: * same type (that is, the same subclass of GeometryArray).
054: * </li>
055: *
056: * <p>
057: * <li>
058: * The vertexFormat, texCoordSetCount, and validVertexCount must be
059: * the same for all <i>N</i> geometry arrays.
060: * </li>
061: *
062: * <p>
063: * <li>
064: * The texCoordSetMap array must be identical (element-by-element) for
065: * all <i>N</i> geometry arrays.
066: * </li>
067: *
068: * <p>
069: * <li>
070: * For IndexedGeometryArray objects, the validIndexCount must be the same
071: * for all <i>N</i> geometry arrays.
072: * </li>
073: *
074: * <p>
075: * <li>
076: * For GeometryStripArray objects, the stripVertexCounts array must
077: * be identical (element-by-element) for all <i>N</i> geometry arrays.
078: * </li>
079: *
080: * <p>
081: * <li>
082: * For IndexedGeometryStripArray objects, the stripIndexCounts array must
083: * be identical (element-by-element) for all <i>N</i> geometry arrays.
084: * </li>
085: *
086: * <p>
087: * <li>
088: * For indexed geometry by-reference, the array lengths of each
089: * enabled vertex component (coord, color, normal, texcoord)
090: * must be the same for all <i>N</i> geometry arrays.
091: * </li>
092: * </ul>
093: *
094: * <p>
095: * For IndexedGeometryArray objects, the vertex arrays are morphed
096: * <i>before</i> the indexes are applied. Only the indexes in the
097: * first geometry array (geometry[0]) are used when rendering the
098: * geometry.
099: *
100: * @deprecated As of Java 3D version 1.4.
101: */
102:
103: public class Morph extends Leaf {
104:
105: /**
106: * Specifies that the node allows read access to its geometry information.
107: */
108: public static final int ALLOW_GEOMETRY_ARRAY_READ = CapabilityBits.MORPH_ALLOW_GEOMETRY_ARRAY_READ;
109:
110: /**
111: * Specifies that the node allows write access to its geometry information.
112: */
113: public static final int ALLOW_GEOMETRY_ARRAY_WRITE = CapabilityBits.MORPH_ALLOW_GEOMETRY_ARRAY_WRITE;
114:
115: /**
116: * Specifies that the node allows read access to its appearance information.
117: */
118: public static final int ALLOW_APPEARANCE_READ = CapabilityBits.MORPH_ALLOW_APPEARANCE_READ;
119:
120: /**
121: * Specifies that the node allows write access to its appearance information.
122: */
123: public static final int ALLOW_APPEARANCE_WRITE = CapabilityBits.MORPH_ALLOW_APPEARANCE_WRITE;
124:
125: /**
126: * Specifies that the node allows read access to its morph
127: * weight vector.
128: */
129: public static final int ALLOW_WEIGHTS_READ = CapabilityBits.MORPH_ALLOW_WEIGHTS_READ;
130:
131: /**
132: * Specifies that the node allows write access to its morph
133: * weight vector.
134: */
135: public static final int ALLOW_WEIGHTS_WRITE = CapabilityBits.MORPH_ALLOW_WEIGHTS_WRITE;
136:
137: /**
138: * Specifies that the node allows reading its collision Bounds.
139: */
140: public static final int ALLOW_COLLISION_BOUNDS_READ = CapabilityBits.MORPH_ALLOW_COLLISION_BOUNDS_READ;
141:
142: /**
143: * Specifies the node allows writing its collision Bounds.
144: */
145: public static final int ALLOW_COLLISION_BOUNDS_WRITE = CapabilityBits.MORPH_ALLOW_COLLISION_BOUNDS_WRITE;
146:
147: /**
148: * Specifies that this node allows reading its appearance override
149: * enable flag.
150: *
151: * @since Java 3D 1.2
152: */
153: public static final int ALLOW_APPEARANCE_OVERRIDE_READ = CapabilityBits.MORPH_ALLOW_APPEARANCE_OVERRIDE_READ;
154:
155: /**
156: * Specifies that this node allows writing its appearance override
157: * enable flag.
158: *
159: * @since Java 3D 1.2
160: */
161: public static final int ALLOW_APPEARANCE_OVERRIDE_WRITE = CapabilityBits.MORPH_ALLOW_APPEARANCE_OVERRIDE_WRITE;
162:
163: // Array for setting default read capabilities
164: private static final int[] readCapabilities = {
165: ALLOW_GEOMETRY_ARRAY_READ, ALLOW_APPEARANCE_READ,
166: ALLOW_WEIGHTS_READ, ALLOW_COLLISION_BOUNDS_READ,
167: ALLOW_APPEARANCE_OVERRIDE_READ };
168:
169: // non public default constructor
170: Morph() {
171: // set default read capabilities
172: setDefaultReadCapabilities(readCapabilities);
173: }
174:
175: /**
176: * Constructs and initializes a Morph node with the specified array
177: * of GeometryArray objects. Default values are used for all other
178: * parameters as follows:
179: * <ul>
180: * appearance : null<br>
181: * weights : [1, 0, 0, 0, ...]<br>
182: * collision bounds : null<br>
183: * appearance override enable : false<br>
184: * </ul><P>
185: * A null appearance object specifies that default values are used
186: * for all appearance attributes.
187: *
188: * @param geometryArrays the geometry components of the morph;
189: * a null or zero-length array of GeometryArray objects is
190: * permitted, and specifies that no geometry is drawn. In this case,
191: * the array of weights is initialized to a zero-length array.
192: *
193: * @exception IllegalArgumentException if any of the specified
194: * geometry array objects differ from each other in any of the
195: * following ways:
196: * <ul>
197: * <li>Type of geometry array object (subclass of GeometryArray)</li>
198: * <li>vertexFormat</li>
199: * <li>texCoordSetCount</li>
200: * <li>texCoordSetMap</li>
201: * <li>validVertexCount</li>
202: * <li>validIndexCount, for IndexedGeometryArray objects</li>
203: * <li>stripVertexCounts array, for GeometryStripArray objects</li>
204: * <li>stripIndexCounts array, for IndexedGeometryStripArray objects</li>
205: * <li>the array lengths of each enabled vertex component
206: * (coord, color, normal, texcoord),
207: * for indexed geometry by-reference</li>
208: * </ul>
209: *
210: * @exception UnsupportedOperationException if the specified
211: * geometry arrays contain vertex attributes (that is, if their
212: * vertexFormat includes the <code>VERTEX_ATTRIBUTES</code> flag).
213: */
214: public Morph(GeometryArray geometryArrays[]) {
215: // set default read capabilities
216: setDefaultReadCapabilities(readCapabilities);
217:
218: ((MorphRetained) retained).setGeometryArrays(geometryArrays);
219: }
220:
221: /**
222: * Constructs and initializes a Morph node with the specified array
223: * of GeometryArray objects and the specified appearance object.
224: *
225: * @param geometryArrays the geometry components of the Morph node
226: * a null or zero-length array of GeometryArray objects is
227: * permitted, and specifies that no geometry is drawn. In this case,
228: * the array of weights is initialized to a zero-length array.
229: * @param appearance the appearance component of the Morph node
230: *
231: * @exception IllegalArgumentException if any of the specified
232: * geometry array objects differ from each other in any of the
233: * following ways:
234: * <ul>
235: * <li>Type of geometry array object (subclass of GeometryArray)</li>
236: * <li>vertexFormat</li>
237: * <li>texCoordSetCount</li>
238: * <li>texCoordSetMap</li>
239: * <li>validVertexCount</li>
240: * <li>validIndexCount, for IndexedGeometryArray objects</li>
241: * <li>stripVertexCounts array, for GeometryStripArray objects</li>
242: * <li>stripIndexCounts array, for IndexedGeometryStripArray objects</li>
243: * <li>the array lengths of each enabled vertex component
244: * (coord, color, normal, texcoord),
245: * for indexed geometry by-reference</li>
246: * </ul>
247: *
248: * @exception UnsupportedOperationException if the specified
249: * geometry arrays contain vertex attributes (that is, if their
250: * vertexFormat includes the <code>VERTEX_ATTRIBUTES</code> flag).
251: */
252: public Morph(GeometryArray geometryArrays[], Appearance appearance) {
253: // set default read capabilities
254: setDefaultReadCapabilities(readCapabilities);
255:
256: ((MorphRetained) retained).setGeometryArrays(geometryArrays);
257: ((MorphRetained) this .retained).setAppearance(appearance);
258: }
259:
260: /**
261: * Creates the retained mode MorphRetained object that this
262: * Morph object will point to.
263: */
264: void createRetained() {
265: retained = new MorphRetained();
266: retained.setSource(this );
267: }
268:
269: /**
270: * Sets the collision bounds of a node.
271: * @param bounds the collision bounding object for a node
272: * @exception CapabilityNotSetException if appropriate capability is
273: * not set and this object is part of live or compiled scene graph
274: */
275: public void setCollisionBounds(Bounds bounds) {
276:
277: if (isLiveOrCompiled())
278: if (!this .getCapability(ALLOW_COLLISION_BOUNDS_WRITE))
279: throw new CapabilityNotSetException(J3dI18N
280: .getString("Morph0"));
281:
282: ((MorphRetained) this .retained).setCollisionBounds(bounds);
283: }
284:
285: /**
286: * Returns the collision bounding object of this node.
287: * @return the node's collision bounding object
288: * @exception CapabilityNotSetException if appropriate capability is
289: * not set and this object is part of live or compiled scene graph
290: */
291: public Bounds getCollisionBounds() {
292:
293: if (isLiveOrCompiled())
294: if (!this .getCapability(ALLOW_COLLISION_BOUNDS_READ))
295: throw new CapabilityNotSetException(J3dI18N
296: .getString("Morph1"));
297:
298: return ((MorphRetained) this .retained).getCollisionBounds();
299: }
300:
301: /**
302: * Sets the geometryArrays component of the Morph node.
303: *
304: * If the current array of GeometryArrays in this Morph object is
305: * non-null with a length greater than 0, the specified array of
306: * GeometryArrays must be the same length as the current array.
307: * If the current array of GeometryArrays in this Morph object is
308: * null or has a length of 0, and the specified array of
309: * GeometryArrays is non-null with a length greater than 0, the
310: * length of the incoming array defines the number of the geometry
311: * objects that will be morphed. In this case, the weights array
312: * is allocated to be of the same length as the geometry array;
313: * the first element (weights[0]) is initialized to 1.0 and all of
314: * the other weights are initialized to 0.0.
315: *
316: * @param geometryArrays the new geometryArrays component
317: * for the Morph node.
318: *
319: * @exception CapabilityNotSetException if appropriate capability is
320: * not set and this object is part of live or compiled scene graph
321: * <p>
322: *
323: * @exception IllegalArgumentException if the length of the
324: * specified array of geometry arrays is not equal to the length
325: * of this Morph node's current array of geometry arrays (and the
326: * current array's length is non-zero), or if any of the specified
327: * geometry array objects differ from each other in any of the
328: * following ways:
329: * <ul>
330: * <li>Type of geometry array object (subclass of GeometryArray)</li>
331: * <li>vertexFormat</li>
332: * <li>texCoordSetCount</li>
333: * <li>texCoordSetMap</li>
334: * <li>validVertexCount</li>
335: * <li>validIndexCount, for IndexedGeometryArray objects</li>
336: * <li>stripVertexCounts array, for GeometryStripArray objects</li>
337: * <li>stripIndexCounts array, for IndexedGeometryStripArray objects</li>
338: * <li>the array lengths of each enabled vertex component
339: * (coord, color, normal, texcoord),
340: * for indexed geometry by-reference</li>
341: * </ul>
342: *
343: * @exception UnsupportedOperationException if the specified
344: * geometry arrays contain vertex attributes (that is, if their
345: * vertexFormat includes the <code>VERTEX_ATTRIBUTES</code> flag).
346: */
347: public void setGeometryArrays(GeometryArray geometryArrays[]) {
348:
349: if (isLiveOrCompiled())
350: if (!this .getCapability(ALLOW_GEOMETRY_ARRAY_WRITE))
351: throw new CapabilityNotSetException(J3dI18N
352: .getString("Morph2"));
353:
354: ((MorphRetained) this .retained)
355: .setGeometryArrays(geometryArrays);
356: }
357:
358: /**
359: * Retrieves the geometryArray component of this Morph node.
360: * @param index the index of GeometryArray to be returned
361: * @return the geometryArray component of this Morph node
362: * @exception CapabilityNotSetException if appropriate capability is
363: * not set and this object is part of live or compiled scene graph
364: */
365: public GeometryArray getGeometryArray(int index) {
366:
367: if (isLiveOrCompiled())
368: if (!this .getCapability(ALLOW_GEOMETRY_ARRAY_READ))
369: throw new CapabilityNotSetException(J3dI18N
370: .getString("Morph3"));
371:
372: return ((MorphRetained) this .retained).getGeometryArray(index);
373: }
374:
375: /**
376: * Sets the appearance component of this Morph node. A null
377: * appearance component specifies that default values are used for all
378: * appearance attributes.
379: * @param appearance the new appearance component for this Morph node
380: * @exception CapabilityNotSetException if appropriate capability is
381: * not set and this object is part of live or compiled scene graph
382: */
383: public void setAppearance(Appearance appearance) {
384:
385: if (isLiveOrCompiled())
386: if (!this .getCapability(ALLOW_APPEARANCE_WRITE))
387: throw new CapabilityNotSetException(J3dI18N
388: .getString("Morph4"));
389:
390: ((MorphRetained) this .retained).setAppearance(appearance);
391: }
392:
393: /**
394: * Retrieves the appearance component of this morph node.
395: * @return the appearance component of this morph node
396: * @exception CapabilityNotSetException if appropriate capability is
397: * not set and this object is part of live or compiled scene graph
398: */
399: public Appearance getAppearance() {
400:
401: if (isLiveOrCompiled())
402: if (!this .getCapability(ALLOW_APPEARANCE_READ))
403: throw new CapabilityNotSetException(J3dI18N
404: .getString("Morph5"));
405:
406: return ((MorphRetained) this .retained).getAppearance();
407: }
408:
409: /**
410: * Checks whether the geometry in this morph node intersects with
411: * the specified pickShape.
412: *
413: * @param path the SceneGraphPath to this morph node
414: * @param pickShape the PickShape to be intersected
415: *
416: * @return true if the pick shape intersects this node; false
417: * otherwise.
418: *
419: * @exception IllegalArgumentException if pickShape is a PickPoint.
420: * Java 3D doesn't have spatial information of the surface.
421: * Use PickBounds with BoundingSphere and a small radius, instead.
422: *
423: * @exception CapabilityNotSetException if the Geometry.ALLOW_INTERSECT
424: * capability bit is not set in all of the Geometry objects
425: * referred to by this morph node.
426: */
427: public boolean intersect(SceneGraphPath path, PickShape pickShape) {
428: return intersect(path, pickShape, null);
429: }
430:
431: /**
432: * Checks whether the geometry in this morph node intersects with
433: * the specified pickRay.
434: *
435: * @param path the SceneGraphPath to this morph node
436: * @param pickRay the PickRay to be intersected
437: * @param dist the closest distance of the intersection
438: *
439: * @return true if the pick shape intersects this node; false
440: * otherwise. If true, dist contains the closest distance of
441: * intersection.
442: *
443: * @exception CapabilityNotSetException if the Geometry.ALLOW_INTERSECT
444: * capability bit is not set in all of the Geometry objects
445: * referred to by this morph node.
446: */
447: public boolean intersect(SceneGraphPath path, PickRay pickRay,
448: double[] dist) {
449:
450: if (isLiveOrCompiled()) {
451: checkForAllowIntersect();
452: }
453:
454: return ((MorphRetained) this .retained).intersect(path, pickRay,
455: dist);
456: }
457:
458: /**
459: * Checks whether the geometry in this morph node intersects with
460: * the specified pickShape.
461: *
462: * @param path the SceneGraphPath to this morph node
463: * @param pickShape the PickShape to be intersected
464: * @param dist the closest distance of the intersection
465: *
466: * @return true if the pick shape intersects this node; false
467: * otherwise. If true, dist contains the closest distance of
468: * intersection.
469: *
470: * @exception IllegalArgumentException if pickShape is a PickPoint.
471: * Java 3D doesn't have spatial information of the surface.
472: * Use PickBounds with BoundingSphere and a small radius, instead.
473: *
474: * @exception CapabilityNotSetException if the Geometry.ALLOW_INTERSECT
475: * capability bit is not set in all of the Geometry objects
476: * referred to by this morph node.
477: *
478: * @since Java 3D 1.3
479: */
480: public boolean intersect(SceneGraphPath path, PickShape pickShape,
481: double[] dist) {
482:
483: if (isLiveOrCompiled()) {
484: checkForAllowIntersect();
485: }
486:
487: if (pickShape instanceof PickPoint) {
488: throw new IllegalArgumentException(J3dI18N
489: .getString("Morph10"));
490: }
491:
492: return ((MorphRetained) this .retained).intersect(path,
493: pickShape, dist);
494: }
495:
496: /**
497: * Sets this Morph node's morph weight vector. The Morph node "weights"
498: * the corresponding GeometryArray by the amount specified.
499: * The weights apply a morph weight vector component that creates
500: * the desired morphing effect.
501: * The length
502: * of the <code>weights</code> parameter must be equal to the length
503: * of the array with which this Morph node was created, otherwise
504: * an IllegalArgumentException is thown.
505: * @param weights the morph weight vector that the morph node will
506: * use in combining the node's geometryArrays. The morph node will "weight"
507: * the corresponding GeometryArray by the amount specified.
508: * N.B.: the sum of the weights should equal 1.0
509: *
510: * @exception CapabilityNotSetException if appropriate capability is
511: * not set and this object is part of live or compiled scene graph
512: * @exception IllegalArgumentException if sum of all 'weights' is
513: * NOT 1.0 or number of weights is NOT exqual to number of GeometryArrays.
514: */
515: public void setWeights(double weights[]) {
516: if (isLiveOrCompiled())
517: if (!this .getCapability(ALLOW_WEIGHTS_WRITE))
518: throw new CapabilityNotSetException(J3dI18N
519: .getString("Morph8"));
520:
521: ((MorphRetained) this .retained).setWeights(weights);
522: }
523:
524: /**
525: * Retrieves the Morph node's morph weight vector.
526: * @return the morph weight vector component of this morph node
527: * @exception CapabilityNotSetException if appropriate capability is
528: * not set and this object is part of live or compiled scene graph
529: */
530: public double[] getWeights() {
531: if (isLiveOrCompiled())
532: if (!this .getCapability(ALLOW_WEIGHTS_READ))
533: throw new CapabilityNotSetException(J3dI18N
534: .getString("Morph9"));
535:
536: return ((MorphRetained) this .retained).getWeights();
537: }
538:
539: /**
540: * Sets a flag that indicates whether this node's appearance can
541: * be overridden. If the flag is true, this node's
542: * appearance may be overridden by an AlternateAppearance leaf
543: * node, regardless of the value of the ALLOW_APPEARANCE_WRITE
544: * capability bit.
545: * The default value is false.
546: *
547: * @param flag the apperance override enable flag
548: * @exception CapabilityNotSetException if appropriate capability is
549: * not set and this object is part of live or compiled scene graph
550: *
551: * @see AlternateAppearance
552: *
553: * @since Java 3D 1.2
554: */
555: public void setAppearanceOverrideEnable(boolean flag) {
556: if (isLiveOrCompiled())
557: if (!this .getCapability(ALLOW_APPEARANCE_OVERRIDE_WRITE))
558: throw new CapabilityNotSetException(J3dI18N
559: .getString("Morph11"));
560:
561: ((MorphRetained) this .retained)
562: .setAppearanceOverrideEnable(flag);
563: }
564:
565: /**
566: * Retrieves the appearanceOverrideEnable flag for this node.
567: * @return true if the appearance can be overridden; false
568: * otherwise.
569: * @exception CapabilityNotSetException if appropriate capability is
570: * not set and this object is part of live or compiled scene graph
571: *
572: * @since Java 3D 1.2
573: */
574: public boolean getAppearanceOverrideEnable() {
575: if (isLiveOrCompiled())
576: if (!this .getCapability(ALLOW_APPEARANCE_OVERRIDE_READ))
577: throw new CapabilityNotSetException(J3dI18N
578: .getString("Morph12"));
579:
580: return ((MorphRetained) this .retained)
581: .getAppearanceOverrideEnable();
582: }
583:
584: /**
585: * Creates a new instance of the node. This routine is called
586: * by <code>cloneTree</code> to duplicate the current node.
587: * @param forceDuplicate when set to <code>true</code>, causes the
588: * <code>duplicateOnCloneTree</code> flag to be ignored. When
589: * <code>false</code>, the value of each node's
590: * <code>duplicateOnCloneTree</code> variable determines whether
591: * NodeComponent data is duplicated or copied.
592: *
593: * @see Node#cloneTree
594: * @see Node#cloneNode
595: * @see Node#duplicateNode
596: * @see NodeComponent#setDuplicateOnCloneTree
597: */
598: public Node cloneNode(boolean forceDuplicate) {
599: Morph m = new Morph();
600: m.duplicateNode(this , forceDuplicate);
601: return m;
602: }
603:
604: /**
605: * Copies all node information from <code>originalNode</code> into
606: * the current node. This method is called from the
607: * <code>cloneNode</code> method which is, in turn, called by the
608: * <code>cloneTree</code> method.
609: * <P>
610: * For any <code>NodeComponent</code> objects
611: * contained by the object being duplicated, each <code>NodeComponent</code>
612: * object's <code>duplicateOnCloneTree</code> value is used to determine
613: * whether the <code>NodeComponent</code> should be duplicated in the new node
614: * or if just a reference to the current node should be placed in the
615: * new node. This flag can be overridden by setting the
616: * <code>forceDuplicate</code> parameter in the <code>cloneTree</code>
617: * method to <code>true</code>.
618: * <br>
619: * NOTE: Applications should <i>not</i> call this method directly.
620: * It should only be called by the cloneNode method.
621: *
622: * @param originalNode the original node to duplicate.
623: * @param forceDuplicate when set to <code>true</code>, causes the
624: * <code>duplicateOnCloneTree</code> flag to be ignored. When
625: * <code>false</code>, the value of each node's
626: * <code>duplicateOnCloneTree</code> variable determines whether
627: * NodeComponent data is duplicated or copied.
628: * @exception ClassCastException if originalNode is not an instance of
629: * <code>Morph</code>
630: *
631: * @see Node#cloneTree
632: * @see Node#cloneNode
633: * @see NodeComponent#setDuplicateOnCloneTree
634: */
635: public void duplicateNode(Node originalNode, boolean forceDuplicate) {
636: checkDuplicateNode(originalNode, forceDuplicate);
637: }
638:
639: /**
640: * Copies all Morph information from
641: * <code>originalNode</code> into
642: * the current node. This method is called from the
643: * <code>cloneNode</code> method which is, in turn, called by the
644: * <code>cloneTree</code> method.<P>
645: *
646: * @param originalNode the original node to duplicate.
647: * @param forceDuplicate when set to <code>true</code>, causes the
648: * <code>duplicateOnCloneTree</code> flag to be ignored. When
649: * <code>false</code>, the value of each node's
650: * <code>duplicateOnCloneTree</code> variable determines whether
651: * NodeComponent data is duplicated or copied.
652: *
653: * @exception RestrictedAccessException if this object is part of a live
654: * or compiled scenegraph.
655: *
656: * @see Node#duplicateNode
657: * @see Node#cloneTree
658: * @see NodeComponent#setDuplicateOnCloneTree
659: */
660: void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
661: super .duplicateAttributes(originalNode, forceDuplicate);
662:
663: MorphRetained attr = (MorphRetained) originalNode.retained;
664: MorphRetained rt = (MorphRetained) retained;
665:
666: Hashtable hashtable = originalNode.nodeHashtable;
667:
668: double weights[] = attr.getWeights();
669:
670: rt.setCollisionBounds(attr.getCollisionBounds());
671: rt.setAppearance((Appearance) getNodeComponent(attr
672: .getAppearance(), forceDuplicate, hashtable));
673:
674: GeometryArray ga[] = new GeometryArray[weights.length];
675:
676: for (int i = weights.length - 1; i >= 0; i--) {
677: ga[i] = (GeometryArray) getNodeComponent(attr
678: .getGeometryArray(i), forceDuplicate, hashtable);
679: }
680: rt.setGeometryArrays(ga);
681: rt.setWeights(weights);
682: }
683:
684: // Method to check whether all geometries have allow intersect
685: // capability bit set; it will throw an exception if any don't
686: // have the bit set.
687: private void checkForAllowIntersect() {
688: MorphRetained morphR = ((MorphRetained) this .retained);
689: int numGeometryArrays = morphR.getNumGeometryArrays();
690: for (int i = 0; i < numGeometryArrays; i++) {
691: if (!morphR.geometryArrays[i].source
692: .getCapability(Geometry.ALLOW_INTERSECT)) {
693:
694: throw new CapabilityNotSetException(J3dI18N
695: .getString("Morph6"));
696: }
697: }
698: }
699:
700: }
|