All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.media.j3d.Morph Maven / Gradle / Ivy

/*
 * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

package javax.media.j3d;

import java.util.Hashtable;

/**
 * The Morph leaf node permits an application to morph between
 * multiple GeometryArrays.  The Morph node contains a single
 * Appearance node, an array of GeometryArray objects, and an array of
 * corresponding weights. The Morph node combines these GeometryArrays
 * into an aggregate shape based on each GeometryArray's corresponding
 * weight. Typically, Behavior nodes will modify the weights to
 * achieve various morphing effects.
 *
 * 

* The following restrictions apply to each GeometryArray object * in the specified array of GeometryArray objects: * *

    *
  • * All N geometry arrays must be of the * same type (that is, the same subclass of GeometryArray). *
  • * *

    *

  • * The vertexFormat, texCoordSetCount, and validVertexCount must be * the same for all N geometry arrays. *
  • * *

    *

  • * The texCoordSetMap array must be identical (element-by-element) for * all N geometry arrays. *
  • * *

    *

  • * For IndexedGeometryArray objects, the validIndexCount must be the same * for all N geometry arrays. *
  • * *

    *

  • * For GeometryStripArray objects, the stripVertexCounts array must * be identical (element-by-element) for all N geometry arrays. *
  • * *

    *

  • * For IndexedGeometryStripArray objects, the stripIndexCounts array must * be identical (element-by-element) for all N geometry arrays. *
  • * *

    *

  • * For indexed geometry by-reference, the array lengths of each * enabled vertex component (coord, color, normal, texcoord) * must be the same for all N geometry arrays. *
  • *
* *

* For IndexedGeometryArray objects, the vertex arrays are morphed * before the indexes are applied. Only the indexes in the * first geometry array (geometry[0]) are used when rendering the * geometry. * * @deprecated As of Java 3D version 1.4. */ public class Morph extends Leaf { /** * Specifies that the node allows read access to its geometry information. */ public static final int ALLOW_GEOMETRY_ARRAY_READ = CapabilityBits.MORPH_ALLOW_GEOMETRY_ARRAY_READ; /** * Specifies that the node allows write access to its geometry information. */ public static final int ALLOW_GEOMETRY_ARRAY_WRITE = CapabilityBits.MORPH_ALLOW_GEOMETRY_ARRAY_WRITE; /** * Specifies that the node allows read access to its appearance information. */ public static final int ALLOW_APPEARANCE_READ = CapabilityBits.MORPH_ALLOW_APPEARANCE_READ; /** * Specifies that the node allows write access to its appearance information. */ public static final int ALLOW_APPEARANCE_WRITE = CapabilityBits.MORPH_ALLOW_APPEARANCE_WRITE; /** * Specifies that the node allows read access to its morph * weight vector. */ public static final int ALLOW_WEIGHTS_READ = CapabilityBits.MORPH_ALLOW_WEIGHTS_READ; /** * Specifies that the node allows write access to its morph * weight vector. */ public static final int ALLOW_WEIGHTS_WRITE = CapabilityBits.MORPH_ALLOW_WEIGHTS_WRITE; /** * Specifies that the node allows reading its collision Bounds. */ public static final int ALLOW_COLLISION_BOUNDS_READ = CapabilityBits.MORPH_ALLOW_COLLISION_BOUNDS_READ; /** * Specifies the node allows writing its collision Bounds. */ public static final int ALLOW_COLLISION_BOUNDS_WRITE = CapabilityBits.MORPH_ALLOW_COLLISION_BOUNDS_WRITE; /** * Specifies that this node allows reading its appearance override * enable flag. * * @since Java 3D 1.2 */ public static final int ALLOW_APPEARANCE_OVERRIDE_READ = CapabilityBits.MORPH_ALLOW_APPEARANCE_OVERRIDE_READ; /** * Specifies that this node allows writing its appearance override * enable flag. * * @since Java 3D 1.2 */ public static final int ALLOW_APPEARANCE_OVERRIDE_WRITE = CapabilityBits.MORPH_ALLOW_APPEARANCE_OVERRIDE_WRITE; // Array for setting default read capabilities private static final int[] readCapabilities = { ALLOW_GEOMETRY_ARRAY_READ, ALLOW_APPEARANCE_READ, ALLOW_WEIGHTS_READ, ALLOW_COLLISION_BOUNDS_READ, ALLOW_APPEARANCE_OVERRIDE_READ }; // non public default constructor Morph() { // set default read capabilities setDefaultReadCapabilities(readCapabilities); } /** * Constructs and initializes a Morph node with the specified array * of GeometryArray objects. Default values are used for all other * parameters as follows: *

    * appearance : null
    * weights : [1, 0, 0, 0, ...]
    * collision bounds : null
    * appearance override enable : false
    *

* A null appearance object specifies that default values are used * for all appearance attributes. * * @param geometryArrays the geometry components of the morph; * a null or zero-length array of GeometryArray objects is * permitted, and specifies that no geometry is drawn. In this case, * the array of weights is initialized to a zero-length array. * * @exception IllegalArgumentException if any of the specified * geometry array objects differ from each other in any of the * following ways: *

    *
  • Type of geometry array object (subclass of GeometryArray)
  • *
  • vertexFormat
  • *
  • texCoordSetCount
  • *
  • texCoordSetMap
  • *
  • validVertexCount
  • *
  • validIndexCount, for IndexedGeometryArray objects
  • *
  • stripVertexCounts array, for GeometryStripArray objects
  • *
  • stripIndexCounts array, for IndexedGeometryStripArray objects
  • *
  • the array lengths of each enabled vertex component * (coord, color, normal, texcoord), * for indexed geometry by-reference
  • *
* * @exception UnsupportedOperationException if the specified * geometry arrays contain vertex attributes (that is, if their * vertexFormat includes the VERTEX_ATTRIBUTES flag). */ public Morph(GeometryArray geometryArrays[]) { // set default read capabilities setDefaultReadCapabilities(readCapabilities); ((MorphRetained)retained).setGeometryArrays(geometryArrays); } /** * Constructs and initializes a Morph node with the specified array * of GeometryArray objects and the specified appearance object. * * @param geometryArrays the geometry components of the Morph node * a null or zero-length array of GeometryArray objects is * permitted, and specifies that no geometry is drawn. In this case, * the array of weights is initialized to a zero-length array. * @param appearance the appearance component of the Morph node * * @exception IllegalArgumentException if any of the specified * geometry array objects differ from each other in any of the * following ways: *
    *
  • Type of geometry array object (subclass of GeometryArray)
  • *
  • vertexFormat
  • *
  • texCoordSetCount
  • *
  • texCoordSetMap
  • *
  • validVertexCount
  • *
  • validIndexCount, for IndexedGeometryArray objects
  • *
  • stripVertexCounts array, for GeometryStripArray objects
  • *
  • stripIndexCounts array, for IndexedGeometryStripArray objects
  • *
  • the array lengths of each enabled vertex component * (coord, color, normal, texcoord), * for indexed geometry by-reference
  • *
* * @exception UnsupportedOperationException if the specified * geometry arrays contain vertex attributes (that is, if their * vertexFormat includes the VERTEX_ATTRIBUTES flag). */ public Morph(GeometryArray geometryArrays[], Appearance appearance) { // set default read capabilities setDefaultReadCapabilities(readCapabilities); ((MorphRetained)retained).setGeometryArrays(geometryArrays); ((MorphRetained)this.retained).setAppearance(appearance); } /** * Creates the retained mode MorphRetained object that this * Morph object will point to. */ @Override void createRetained() { retained = new MorphRetained(); retained.setSource(this); } /** * Sets the collision bounds of a node. * @param bounds the collision bounding object for a node * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph */ public void setCollisionBounds(Bounds bounds) { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_COLLISION_BOUNDS_WRITE)) throw new CapabilityNotSetException(J3dI18N.getString("Morph0")); ((MorphRetained)this.retained).setCollisionBounds(bounds); } /** * Returns the collision bounding object of this node. * @return the node's collision bounding object * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph */ public Bounds getCollisionBounds() { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_COLLISION_BOUNDS_READ)) throw new CapabilityNotSetException(J3dI18N.getString("Morph1")); return ((MorphRetained)this.retained).getCollisionBounds(); } /** * Sets the geometryArrays component of the Morph node. * * If the current array of GeometryArrays in this Morph object is * non-null with a length greater than 0, the specified array of * GeometryArrays must be the same length as the current array. * If the current array of GeometryArrays in this Morph object is * null or has a length of 0, and the specified array of * GeometryArrays is non-null with a length greater than 0, the * length of the incoming array defines the number of the geometry * objects that will be morphed. In this case, the weights array * is allocated to be of the same length as the geometry array; * the first element (weights[0]) is initialized to 1.0 and all of * the other weights are initialized to 0.0. * * @param geometryArrays the new geometryArrays component * for the Morph node. * * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph *

* * @exception IllegalArgumentException if the length of the * specified array of geometry arrays is not equal to the length * of this Morph node's current array of geometry arrays (and the * current array's length is non-zero), or if any of the specified * geometry array objects differ from each other in any of the * following ways: *

    *
  • Type of geometry array object (subclass of GeometryArray)
  • *
  • vertexFormat
  • *
  • texCoordSetCount
  • *
  • texCoordSetMap
  • *
  • validVertexCount
  • *
  • validIndexCount, for IndexedGeometryArray objects
  • *
  • stripVertexCounts array, for GeometryStripArray objects
  • *
  • stripIndexCounts array, for IndexedGeometryStripArray objects
  • *
  • the array lengths of each enabled vertex component * (coord, color, normal, texcoord), * for indexed geometry by-reference
  • *
* * @exception UnsupportedOperationException if the specified * geometry arrays contain vertex attributes (that is, if their * vertexFormat includes the VERTEX_ATTRIBUTES flag). */ public void setGeometryArrays(GeometryArray geometryArrays[]) { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_GEOMETRY_ARRAY_WRITE)) throw new CapabilityNotSetException(J3dI18N.getString("Morph2")); ((MorphRetained)this.retained).setGeometryArrays(geometryArrays); } /** * Retrieves the geometryArray component of this Morph node. * @param index the index of GeometryArray to be returned * @return the geometryArray component of this Morph node * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph */ public GeometryArray getGeometryArray(int index) { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_GEOMETRY_ARRAY_READ)) throw new CapabilityNotSetException(J3dI18N.getString("Morph3")); return ((MorphRetained)this.retained).getGeometryArray(index); } /** * Sets the appearance component of this Morph node. A null * appearance component specifies that default values are used for all * appearance attributes. * @param appearance the new appearance component for this Morph node * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph */ public void setAppearance(Appearance appearance) { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_APPEARANCE_WRITE)) throw new CapabilityNotSetException(J3dI18N.getString("Morph4")); ((MorphRetained)this.retained).setAppearance(appearance); } /** * Retrieves the appearance component of this morph node. * @return the appearance component of this morph node * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph */ public Appearance getAppearance() { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_APPEARANCE_READ)) throw new CapabilityNotSetException(J3dI18N.getString("Morph5")); return ((MorphRetained)this.retained).getAppearance(); } /** * Checks whether the geometry in this morph node intersects with * the specified pickShape. * * @param path the SceneGraphPath to this morph node * @param pickShape the PickShape to be intersected * * @return true if the pick shape intersects this node; false * otherwise. * * @exception IllegalArgumentException if pickShape is a PickPoint. * Java 3D doesn't have spatial information of the surface. * Use PickBounds with BoundingSphere and a small radius, instead. * * @exception CapabilityNotSetException if the Geometry.ALLOW_INTERSECT * capability bit is not set in all of the Geometry objects * referred to by this morph node. */ public boolean intersect(SceneGraphPath path, PickShape pickShape) { return intersect(path, pickShape, null); } /** * Checks whether the geometry in this morph node intersects with * the specified pickRay. * * @param path the SceneGraphPath to this morph node * @param pickRay the PickRay to be intersected * @param dist the closest distance of the intersection * * @return true if the pick shape intersects this node; false * otherwise. If true, dist contains the closest distance of * intersection. * * @exception CapabilityNotSetException if the Geometry.ALLOW_INTERSECT * capability bit is not set in all of the Geometry objects * referred to by this morph node. */ public boolean intersect(SceneGraphPath path, PickRay pickRay, double[] dist) { if (isLiveOrCompiled()) { checkForAllowIntersect(); } return ((MorphRetained)this.retained).intersect(path, pickRay, dist); } /** * Checks whether the geometry in this morph node intersects with * the specified pickShape. * * @param path the SceneGraphPath to this morph node * @param pickShape the PickShape to be intersected * @param dist the closest distance of the intersection * * @return true if the pick shape intersects this node; false * otherwise. If true, dist contains the closest distance of * intersection. * * @exception IllegalArgumentException if pickShape is a PickPoint. * Java 3D doesn't have spatial information of the surface. * Use PickBounds with BoundingSphere and a small radius, instead. * * @exception CapabilityNotSetException if the Geometry.ALLOW_INTERSECT * capability bit is not set in all of the Geometry objects * referred to by this morph node. * * @since Java 3D 1.3 */ public boolean intersect(SceneGraphPath path, PickShape pickShape, double[] dist) { if (isLiveOrCompiled()) { checkForAllowIntersect(); } if (pickShape instanceof PickPoint) { throw new IllegalArgumentException(J3dI18N.getString("Morph10")); } return ((MorphRetained)this.retained).intersect(path, pickShape, dist); } /** * Sets this Morph node's morph weight vector. The Morph node "weights" * the corresponding GeometryArray by the amount specified. * The weights apply a morph weight vector component that creates * the desired morphing effect. * The length * of the weights parameter must be equal to the length * of the array with which this Morph node was created, otherwise * an IllegalArgumentException is thown. * @param weights the morph weight vector that the morph node will * use in combining the node's geometryArrays. The morph node will "weight" * the corresponding GeometryArray by the amount specified. * N.B.: the sum of the weights should equal 1.0 * * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph * @exception IllegalArgumentException if sum of all 'weights' is * NOT 1.0 or number of weights is NOT exqual to number of GeometryArrays. */ public void setWeights(double weights[]) { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_WEIGHTS_WRITE)) throw new CapabilityNotSetException(J3dI18N.getString("Morph8")); ((MorphRetained)this.retained).setWeights(weights); } /** * Retrieves the Morph node's morph weight vector. * @return the morph weight vector component of this morph node * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph */ public double[] getWeights() { if (isLiveOrCompiled()) if(!this.getCapability(ALLOW_WEIGHTS_READ)) throw new CapabilityNotSetException(J3dI18N.getString("Morph9")); return ((MorphRetained)this.retained).getWeights(); } /** * Sets a flag that indicates whether this node's appearance can * be overridden. If the flag is true, this node's * appearance may be overridden by an AlternateAppearance leaf * node, regardless of the value of the ALLOW_APPEARANCE_WRITE * capability bit. * The default value is false. * * @param flag the apperance override enable flag * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph * * @see AlternateAppearance * * @since Java 3D 1.2 */ public void setAppearanceOverrideEnable(boolean flag) { if (isLiveOrCompiled()) if (!this.getCapability(ALLOW_APPEARANCE_OVERRIDE_WRITE)) throw new CapabilityNotSetException(J3dI18N.getString("Morph11")); ((MorphRetained)this.retained).setAppearanceOverrideEnable(flag); } /** * Retrieves the appearanceOverrideEnable flag for this node. * @return true if the appearance can be overridden; false * otherwise. * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph * * @since Java 3D 1.2 */ public boolean getAppearanceOverrideEnable() { if (isLiveOrCompiled()) if (!this.getCapability(ALLOW_APPEARANCE_OVERRIDE_READ)) throw new CapabilityNotSetException(J3dI18N.getString("Morph12")); return ((MorphRetained)this.retained).getAppearanceOverrideEnable(); } /** * Creates a new instance of the node. This routine is called * by cloneTree to duplicate the current node. * @param forceDuplicate when set to true, causes the * duplicateOnCloneTree flag to be ignored. When * false, the value of each node's * duplicateOnCloneTree variable determines whether * NodeComponent data is duplicated or copied. * * @see Node#cloneTree * @see Node#cloneNode * @see Node#duplicateNode * @see NodeComponent#setDuplicateOnCloneTree */ @Override public Node cloneNode(boolean forceDuplicate) { Morph m = new Morph(); m.duplicateNode(this, forceDuplicate); return m; } /** * Copies all node information from originalNode into * the current node. This method is called from the * cloneNode method which is, in turn, called by the * cloneTree method. *

* For any NodeComponent objects * contained by the object being duplicated, each NodeComponent * object's duplicateOnCloneTree value is used to determine * whether the NodeComponent should be duplicated in the new node * or if just a reference to the current node should be placed in the * new node. This flag can be overridden by setting the * forceDuplicate parameter in the cloneTree * method to true. *
* NOTE: Applications should not call this method directly. * It should only be called by the cloneNode method. * * @param originalNode the original node to duplicate. * @param forceDuplicate when set to true, causes the * duplicateOnCloneTree flag to be ignored. When * false, the value of each node's * duplicateOnCloneTree variable determines whether * NodeComponent data is duplicated or copied. * @exception ClassCastException if originalNode is not an instance of * Morph * * @see Node#cloneTree * @see Node#cloneNode * @see NodeComponent#setDuplicateOnCloneTree */ @Override public void duplicateNode(Node originalNode, boolean forceDuplicate) { checkDuplicateNode(originalNode, forceDuplicate); } /** * Copies all Morph information from * originalNode into * the current node. This method is called from the * cloneNode method which is, in turn, called by the * cloneTree method.

* * @param originalNode the original node to duplicate. * @param forceDuplicate when set to true, causes the * duplicateOnCloneTree flag to be ignored. When * false, the value of each node's * duplicateOnCloneTree variable determines whether * NodeComponent data is duplicated or copied. * * @exception RestrictedAccessException if this object is part of a live * or compiled scenegraph. * * @see Node#duplicateNode * @see Node#cloneTree * @see NodeComponent#setDuplicateOnCloneTree */ @Override void duplicateAttributes(Node originalNode, boolean forceDuplicate) { super.duplicateAttributes(originalNode, forceDuplicate); MorphRetained attr = (MorphRetained) originalNode.retained; MorphRetained rt = (MorphRetained) retained; Hashtable hashtable = originalNode.nodeHashtable; double weights[] = attr.getWeights(); rt.setCollisionBounds(attr.getCollisionBounds()); rt.setAppearance((Appearance) getNodeComponent( attr.getAppearance(), forceDuplicate, hashtable)); GeometryArray ga[] = new GeometryArray[weights.length]; for (int i=weights.length-1; i>=0; i--) { ga[i] = (GeometryArray) getNodeComponent( attr.getGeometryArray(i), forceDuplicate, hashtable); } rt.setGeometryArrays(ga); rt.setWeights(weights); } // Method to check whether all geometries have allow intersect // capability bit set; it will throw an exception if any don't // have the bit set. private void checkForAllowIntersect() { MorphRetained morphR = ((MorphRetained)this.retained); int numGeometryArrays = morphR.getNumGeometryArrays(); for (int i = 0; i < numGeometryArrays; i++) { if (!morphR.geometryArrays[i].source. getCapability(Geometry.ALLOW_INTERSECT)) { throw new CapabilityNotSetException(J3dI18N.getString("Morph6")); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy