javax.media.j3d.SceneGraphObject Maven / Gradle / Ivy
Show all versions of java3d-core Show documentation
/*
* Copyright 1997-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;
/**
* SceneGraphObject is the common superclass for all scene graph
* objects. Scene graph objects are classified into two main types:
* nodes and node components. The Node object is the common superclass
* of all nodes, which includes TransformGroup, Shape3D, etc.
* The NodeComponent object is the common superclass of all node
* components, which includes Geometry, Appearance, etc.
*
*
* All scene graph objects have a name, a user data object, a set of
* capability bits, and a set of capabilityIsFrequent bits.
*
*
* Capability bits control whether a particular attribute in a node or
* node component is readable or writable. For live or compiled scene
* graphs, only those attributes whose capabilities are set before the
* scene graph is compiled or made live may be read or written. The
* default value for all read capability bits is true, meaning
* that all attributes may be read by default. The default value for
* all write capability bits is false, meaning that no
* attributes may be written by default. Read capability bits are
* defined as those capability bits of the form ALLOW_*_READ
,
* plus the ALLOW_INTERSECT
capability bit. Write
* capability bits are defined as those capability bits of the form
* ALLOW_*_WRITE
, plus the ALLOW_CHILDREN_EXTEND
* and ALLOW_DETACH
capability bits.
*
*
* NOTE that the ENABLE_COLLISION_REPORTING
and
* ENABLE_PICK_REPORTING
bits are not really capability bits,
* although they are set with the setCapability method. The default value
* for each of the ENABLE_*_REPORTING bits
is false.
*
*
* For more information, see the
* Introduction to the Java 3D API.
*/
public abstract class SceneGraphObject extends Object {
// Any global flags? (e.g., execution cullable, collideable)
// Reference to the retained-mode scene-graph element.
SceneGraphObjectRetained retained;
// This object's capability bits
private long capabilityBits = 0L;
// This object's capabilityIsFrequent bits
private long capabilityIsFrequentBits = ~0L;
//boolean indicating is Scene Graph is compiled
private boolean compiled = false;
//boolean indicating if Scene Graph is live.
private boolean live = false;
//boolean indicating if Scene Graph is live or compiled
private boolean liveOrCompiled = false;
// A reference to user data
private Object userData = null;
// Optional name for object.
private String objectName = null;
// use for cloneTree/cloneNode only, set to null after the operation
Hashtable nodeHashtable = null;
/**
* Constructs a SceneGraphObject with default parameters. The default
* values are as follows:
*
* all read capability bits : set (true)
* all write capability bits : clear (false)
* all capabilityIsFrequent bits : set (true)
* isLive : false
* isCompiled : false
* user data : null
* name : null
*
*/
public SceneGraphObject() {
createRetained();
}
/**
* Creates the retained mode object that this scene graph object
* will point to. This should be overridden by those classes
* that have a specific retained mode object.
*/
void createRetained() {
this.retained = null;
// Non-abstract subclasses of SceneGraphObject should override
// this function with code which is something like the following:
//
// this.retained = new Retained();
// this.retained.setSource(this);
}
/**
* Method to set default read capability bits to true
*/
void setDefaultReadCapabilities(int[] bits) {
if (true /*VirtualUniverse.mc.defaultReadCapability*/) {
for (int i=0; i < bits.length; i++) {
setCapability(bits[i]);
}
}
}
/**
* Retrieves the specified capability bit. Note that only one capability
* bit may be retrieved per method invocation--capability bits cannot
* be ORed together.
* @param bit the bit whose value is returned
* @return true if the bit is set, false if the bit is clear
*/
public final boolean getCapability(int bit) {
return (capabilityBits & (1L << bit)) != 0L;
}
/**
* Sets the specified capability bit. Note that only one capability bit
* may be set per method invocation--capability bits cannot be ORed
* together.
* @param bit the bit to set
* @exception RestrictedAccessException if this object is part of live
* or compiled scene graph
*/
public final void setCapability(int bit) {
if (isLiveOrCompiled()) {
throw new RestrictedAccessException(J3dI18N.getString("SceneGraphObject0"));
}
capabilityBits |= (1L << bit);
retained.handleFrequencyChange(bit);
}
/**
* Clear the specified capability bit. Note that only one capability bit
* may be cleared per method invocation--capability bits cannot be ORed
* together.
* @param bit the bit to clear
* @exception RestrictedAccessException if this object is part of live
* or compiled scene graph
*/
public final void clearCapability(int bit) {
if (isLiveOrCompiled())
throw new RestrictedAccessException(J3dI18N.getString("SceneGraphObject0"));
capabilityBits &= ~(1L << bit);
retained.handleFrequencyChange(bit);
}
// Internal method, returns true if no capability bits are set
final boolean capabilityBitsEmpty() {
return capabilityBits == 0L;
}
/**
* Retrieves the isFrequent bit associated with the specified capability
* bit.
*
* Note that only one isFrequent bit, for a single capability
* bit, may be retrieved per method invocation--capability bits cannot
* be ORed together.
*
* @param bit the bit whose value is returned
*
* @return true if the isFrequent bit is set, false if the isFrequent
* bit is clear
*
* @since Java 3D 1.3
*/
public final boolean getCapabilityIsFrequent(int bit) {
return (capabilityIsFrequentBits & (1L << bit)) != 0L;
}
/**
* Sets the isFrequent bit associated with the specified
* capability bit. Setting the isFrequent bit indicates that the
* application may frequently access or modify those attributes
* permitted by the associated capability bit. This can be used
* by Java 3D as a hint to avoid certain optimizations that could
* cause those accesses or modifications to be expensive. By
* default the isFrequent bit associated with each capability bit
* is set.
*
*
* Unlike setCapability, this method may be called on a live scene
* graph object (but not on a compiled object).
*
*
* Note that only one isFrequent bit, for a single capability bit,
* may be set per method invocation--capability bits cannot be ORed
* together.
*
* @param bit the capability bit for which to set the associated
* isFrequent bit
*
* @exception RestrictedAccessException if this object is part of a
* compiled scene graph
*
* @since Java 3D 1.3
*/
public final void setCapabilityIsFrequent(int bit) {
if (isCompiled())
throw new RestrictedAccessException(J3dI18N.getString("SceneGraphObject1"));
capabilityIsFrequentBits |= (1L << bit);
retained.handleFrequencyChange(bit);
}
/**
* Clears the isFrequent bit associated with the specified
* capability bit. Clearing the isFrequent bit indicates that the
* application will infrequently access or modify those attributes
* permitted by the associated capability bit. This can be used
* by Java 3D as a hint to enable certain optimizations that it
* might otherwise avoid, for example, optimizations that could
* cause those accesses or modifications to be expensive.
*
*
* Unlike clearCapability, this method may be called on a live scene
* graph object (but not on a compiled object).
*
*
* Note that only one isFrequent bit, for a single capability bit,
* may be cleared per method invocation--capability bits cannot be ORed
* together.
*
* @param bit the capability bit for which to clear the associated
* isFrequent bit
*
* @exception RestrictedAccessException if this object is part of a
* compiled scene graph
*
* @since Java 3D 1.3
*/
public final void clearCapabilityIsFrequent(int bit) {
if (isCompiled())
throw new RestrictedAccessException(J3dI18N.getString("SceneGraphObject1"));
capabilityIsFrequentBits &= ~(1L << bit);
retained.handleFrequencyChange(bit);
}
/**
* Sets an internal flag which indicates that this scene graph object
* has been compiled.
*/
final void setCompiled() {
this.compiled = true;
this.liveOrCompiled = this.live || this.compiled;
}
/**
* Returns a flag indicating whether the node is part of a scene graph
* that has been compiled. If so, then only those capabilities explicitly
* allowed by the object's capability bits are allowed.
* @return true if node is part of a compiled scene graph, else false
*/
public final boolean isCompiled() {
return this.compiled;
}
/**
* Sets an internal flag which indicates that this scene graph object
* is part of a live scene graph.
*/
final void setLive() {
this.live = true;
this.liveOrCompiled = this.live || this.compiled;
}
/**
* Clears an internal flag which indicates that this scene graph object
* is no longer part of a live scene graph.
*/
final void clearLive() {
this.live = false;
this.liveOrCompiled = this.live || this.compiled;
}
/**
* Returns a flag indicating whether the node is part of a live
* scene graph.
* @return true if node is part of a live scene graph, else false
*/
public final boolean isLive() {
return this.live;
}
/**
* Returns a flag indicating whether the node is part of a live
* scene graph or a compiled scene graph.
* @return true if either live or compiled
*/
final boolean isLiveOrCompiled() {
return liveOrCompiled;
}
final void checkForLiveOrCompiled() {
if (isLiveOrCompiled())
throw new RestrictedAccessException(J3dI18N.getString("SceneGraphObject2"));
}
/**
* Sets the userData field associated with this scene graph object.
* The userData field is a reference to an arbitrary object
* and may be used to store any user-specific data associated
* with this scene graph object--it is not used by the Java 3D API.
* If this object is cloned, the userData field is copied
* to the newly cloned object.
* @param userData a reference to the new userData field
*/
public void setUserData(Object userData) {
this.userData = userData;
}
/**
* Retrieves the userData field from this scene graph object.
* @return the current userData field
*/
public Object getUserData() {
return this.userData;
}
/**
* Callback used to allow a node to check if any scene graph objects
* referenced by that node have been duplicated via a call to
* cloneTree
.
* This method is called by cloneTree
after all nodes in
* the sub-graph have been duplicated. The cloned Leaf
* node and cloned NodeComponent's method
* will be called and the Leaf node/NodeComponent can then look up
* any object references
* by using the getNewObjectReference
method found in the
* NodeReferenceTable
object. If a match is found, a
* reference to the corresponding object in the newly cloned sub-graph
* is returned. If no corresponding reference is found, either a
* DanglingReferenceException is thrown or a reference to the original
* object is returned depending on the value of the
* allowDanglingReferences
parameter passed in the
* cloneTree
call.
*
* NOTE: Applications should not call this method directly.
* It should only be called by the cloneTree method.
*
* @param referenceTable a NodeReferenceTableObject that contains the
* getNewObjectReference
method needed to search for
* new object instances.
* @see NodeReferenceTable
* @see Node#cloneTree
* @see DanglingReferenceException
*/
public void updateNodeReferences(NodeReferenceTable referenceTable) {
}
/**
* Sets the name of this object. Object names are for information
* only.
*
* @param name the new name of this object
*
* @since Java 3D 1.4
*/
public void setName( String name ) {
objectName = name;
}
/**
* Returns the name of this object.
*
* @return the name of this object
*
* @since Java 3D 1.4
*/
public String getName() {
return objectName;
}
/**
* Copies all SceneGraphObject information from
* originalNode
into
* the current node. This method is called from the
* cloneNode
method which is, in turn, called by the
* cloneTree
method.
*
* NOTE: Applications should not call this method directly.
* It should only be called by the cloneNode method.
*
* @param originalNode the original node to duplicate.
*
* @see Group#cloneNode
* @see Node#duplicateNode
* @see Node#cloneTree
* @see NodeComponent#setDuplicateOnCloneTree
*/
protected void duplicateSceneGraphObject(SceneGraphObject originalNode) {
// Duplicate any class specific data here.
capabilityBits = originalNode.capabilityBits;
userData = originalNode.userData;
objectName = originalNode.objectName;
}
/**
* If forceDuplicate
is true
or
* duplicateOnCloneTree
flag is true. This procedure
* will return a clone of originalNode or the value in
* in nodeHashtable
if found. Otherwise return
* originalNode
*
* This method is called from the
* duplicateAttributes
method during cloneNodeComponent.
*
* @param originalNodeComponent 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.
* @param nodeHashtable is used to keep track of mapping between old and
* new node references.
*/
NodeComponent getNodeComponent(NodeComponent originalNodeComponent,
boolean forceDuplicate,
Hashtable hashtable) {
if ((originalNodeComponent != null) &&
(forceDuplicate ||
originalNodeComponent.duplicateChild())) {
NodeComponent nc = (NodeComponent)
hashtable.get(originalNodeComponent);
if (nc == null) {
originalNodeComponent.nodeHashtable = hashtable;
try {
nc = originalNodeComponent.
cloneNodeComponent(forceDuplicate);
} catch (RuntimeException e) {
// must reset nodeHashtable in any case
originalNodeComponent.nodeHashtable = null;
throw e;
}
originalNodeComponent.nodeHashtable = null;
// put link to be shared by other Node
hashtable.put(originalNodeComponent, nc);
} // use the share clone node otherwise
return nc;
} else {
return originalNodeComponent;
}
}
// Internal method to make a prefix out of the name of this object
String getNamePrefix() {
String name = getName();
if (name != null) {
return "[" + name + "] ";
}
return "";
}
/**
* Returns a String representation of this SceneGraphObject.
* If its name is non-null, then it is concatenated with
* super.toString().
*/
@Override
public String toString() {
return getNamePrefix() + super.toString();
}
}