JSR-184 Public Review Draft - Apr. 30, 2003.

javax.microedition.m3d
Class Object3D

java.lang.Object
  |
  +--javax.microedition.m3d.Object3D
Direct Known Subclasses:
AnimationController, AnimationTrack, Appearance, Background, CompositingMode, Fog, GeometryMode, Image2D, IndexBuffer, KeyframeSequence, Material, Node, Texture2D, VertexArray, VertexBuffer

public abstract class Object3D
extends java.lang.Object

An abstract base class for all objects that can be part of a 3D world. This includes the world itself, scene graph nodes, animations, textures, and so on. In fact, everything in this API is an Object3D, except for Loader, Transform, RayIntersection, and Graphics3D.

Animation

Animations are applied to an object and its descendants with the animate method in this class. The objects needed for animation and their relationships are shown in the figure below.

Finding objects

Every Object3D can be assigned a user ID, either at authoring stage or at run time with the setUserID method. User ID's are typically used to find a known object in a scene loaded from a data stream. The find method searches through all objects that are connected to this object through a chain of references, and returns the one with the given user ID. If there are multiple objects with the same ID, the implementation may return any one of them. The operation of find is illustrated in the figure below.

Associated user data

Object3D also has a field called userObject. If the Object3D has been constructed by the Loader and the user parameters have been set, the field contains a Hashtable that stores byte array values keyed by Integers. Both the byte arrays and the indices are specific to each application. A typical example of using this type of persistent user data is including application parameters inside the world, such as in multi-level games, where a non-player character may have a series of attributes such as hit strength, armor, initial health, and so on. Although it is possible to have this information in a separate file, it is neater, easier and less error prone to associate this data with the Object3D directly. If there are no user parameters for an Object3D, or an object derived from Object3D is created dynamically by the application, the userObject field is null.

Instantiation

Object3D is an abstract class, and therefore has no public constructor. When a class derived from Object3D is instantiated, the attributes inherited from Object3D will have the following default values:

See Also:
Binary format

Field Summary
 java.lang.Object userObject
          A field for associating any application specific object with this Object3D.
 
Method Summary
 void addAnimationTrack(AnimationTrack animationTrack)
          Adds the given AnimationTrack to this Object3D, potentially changing the order and indices of the previously added tracks.
 int animate(int time)
          Updates all animated properties in this Object3D and all Object3D's that are reachable from this Object3D.
 java.lang.Object clone()
          Creates a duplicate of this Object3D.
 Object3D find(int userID)
          Retrieves an object that has the given user ID and is reachable from this object.
 AnimationTrack getAnimationTrack(int index)
          Gets an AnimationTrack by index.
 int getAnimationTrackCount()
          Gets the number of AnimationTracks currently associated with this Object3D.
 int getReferences(Object3D[] references)
          Returns the number of direct Object3D references in this object, and fills in the objects to the given array.
 int getUserID()
          Gets the user ID of this object.
 void removeAnimationTrack(AnimationTrack animationTrack)
          Removes the given AnimationTrack from this Object3D, potentially changing the order and indices of the remaining tracks.
 void setUserID(int userID)
          Sets the user ID for this object.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

userObject

public java.lang.Object userObject

A field for associating any application specific object with this Object3D. This field is never accessed by the implementation; it only exists for the convenience of the application. If this Object3D is obtained from the Loader, this field may initially hold a Hashtable containing persistent user data in the form of byte arrays keyed by Integers.

Method Detail

clone

public java.lang.Object clone()

Creates a duplicate of this Object3D. The duplicate object will, in general, have all the same properties as this object, including attribute values, object references, and other contained data.

As an exception to the general rule, if duplicating an object reference would create illegal state, the referenced object is duplicated instead. An example of this is cloning a Group: Since it is illegal for a Node to be referenced by two Group nodes (that is, have multiple parents), the children of the Group must also be duplicated. As a counterexample, cloning an Appearance requires none of the component objects to be duplicated, since they can be referenced by multiple Appearance objects.

The Object3D being cloned is always unaffected by cloning. If referenced objects must be cloned, it is the clone object that references the new duplicates, not the original.

Note that the cloned object will also have the same user ID as the original. The application is responsible for assigning the ID's in the first place, so setting the ID of the cloned object to some unique value, if so desired, is also the application's responsibility.

Returns:
a new Object3D that is a clone of this object

getReferences

public int getReferences(Object3D[] references)

Returns the number of direct Object3D references in this object, and fills in the objects to the given array. If the array is null, only the number of references is returned. Duplicate references are explicitly not eliminated, that is, the same object may appear multiple times in the array.

This method is provided to facilitate scene graph traversal, which is otherwise a non-trivial operation; tracking the links from one object to another requires different code for each type of object. Typical usage of this method is to first call it with a null array, then use the number of references returned to allocate or resize the target array, and then call again with the actual target array. This is illustrated in the example below.

Parameters:
references - an array of Object3D references to be filled in, or null to only return the number of references
Returns:
the number of direct Object3D references in this object (note: the number of unique references may be smaller)
Throws:
java.lang.IllegalArgumentException - if references.length < getReferences(null)
Example:
A recursive method to traverse all descendants of an object.
 void traverseDescendants(Object3D obj)
 {
    int numReferences = obj.getReferences(null);
    if (numReferences > 0)
    {
       Object3D[] objArray = new Object3D[numReferences];
       obj.getReferences(objArray);
       for (int i = 0; i < numReferences; i++)
       {
          processObject(objArray[i]);       // process object i...
          traverseDescendents(objArray[i]); // ...and its descendants
       }
    }
 }

setUserID

public void setUserID(int userID)

Sets the user ID for this object.

Parameters:
userID - the ID to set
See Also:
getUserID()

getUserID

public int getUserID()

Gets the user ID of this object.

Returns:
the current user ID
See Also:
setUserID(int)

find

public Object3D find(int userID)

Retrieves an object that has the given user ID and is reachable from this object. If there are multiple objects with the same ID, the implementation may return any one of them.

An object O is reachable from itself and from all objects from which there is a chain of references to it. However, a Node is defined not to be reachable from its children, or from other Nodes that use it as a transform reference (for alignment or skinning).

Parameters:
userID - the user ID to search for
Returns:
the first object encountered that has the given user ID, or null if no matching objects were found

addAnimationTrack

public void addAnimationTrack(AnimationTrack animationTrack)

Adds the given AnimationTrack to this Object3D, potentially changing the order and indices of the previously added tracks. The position at which the track is inserted among the existing tracks is deliberately left undefined. This gives implementations the freedom to select a data structure that best fits their needs, instead of mandating a particular kind of data structure.

The added animation track must be compatible with this Object3D. For example, to animate the diffuse color of a Material, the target property of the AnimationTrack must be DIFFUSE_COLOR. The target property is selected when constructing an AnimationTrack.

Multiple AnimationTracks can target the same property in the same object, in which case the value of the target property is a weighted linear combination of the individual tracks; see AnimationController for more information. Note that all tracks targeting the same property must have the same number of components in their keyframes. This means that, for instance, a track with RGBA keyframes cannot be blended with an RGB track.

Parameters:
animationTrack - a compatible animation track to attach to this object
Throws:
java.lang.IllegalArgumentException - if animationTrack is incompatible with this Object3D
java.lang.IllegalArgumentException - if animationTrack is already attached to this Object3D
java.lang.IllegalArgumentException - if animationTrack is targeting the same property of this Object3D as a previously added AnimationTrack, but does not have the same keyframe size

getAnimationTrack

public AnimationTrack getAnimationTrack(int index)

Gets an AnimationTrack by index. Valid indices range from zero up to the value returned by getAnimationTrackCount minus one. Note that the index of any AnimationTrack may change whenever a track is added to or removed from this Object3D. See addAnimationTrack for more information.

Parameters:
index - index of the AnimationTrack to be retrieved
Returns:
the AnimationTrack at the given index
Throws:
java.lang.IndexOutOfBoundsException - if index is not in [0, N-1], where N is the number of tracks returned by getAnimationTrackCount

removeAnimationTrack

public void removeAnimationTrack(AnimationTrack animationTrack)

Removes the given AnimationTrack from this Object3D, potentially changing the order and indices of the remaining tracks. If the given animation track is not associated with this object, the request to remove it is silently ignored.

Parameters:
animationTrack - the AnimationTrack to detach from this Object3D

getAnimationTrackCount

public int getAnimationTrackCount()

Gets the number of AnimationTracks currently associated with this Object3D.

Returns:
the number of AnimationTracks bound to this Object3D

animate

public int animate(int time)

Updates all animated properties in this Object3D and all Object3D's that are reachable from this Object3D. Objects that are not reachable are not affected. See the find method for the definition of reachability.

Animated properties are set to their interpolated values pertaining to the time given as a parameter. The unit of time used in animation is defined by the application and does not have to correspond to real time in any way. Importantly, the animation system does not need to know what the unit is. Milliseconds are often used by convention, but all other units are equally valid.

If a property is targeted by an AnimationTrack, but the AnimationTrack is not associated with an active AnimationController, the property is not updated.

Typically, the application would call this method once per frame, with strictly increasing values of time. For example, if the application wishes to draw 20 frames per second, the value of time would be increased by 50 (milliseconds) between successive calls. However, this is not a requirement: any values of time are accepted. This allows the application to, for example, rewind or restart the animations.

In order to allow the application to throttle the frame rate depending on the character of the animation, this method returns a validity interval. This is the amount of time for which the active animations on this object are guaranteed to make no changes to the reachable animated objects. For an object with no references to other animatable objects, this is determined solely from its own animation information. Otherwise, it is the minimum of this, and the returned validity interval of all reachable animated objects.

For example, consider a single object with an active animation that starts to change an object's properties only at t=1000. If we call animate() at t=500, the validity interval returned should ideally be 500. The application can, in the absence of external events, then choose not to render another frame for 500 time units. This estimate of validity must be conservative, so it is acceptable (but not friendly) for an implementation to always return 0 from this method.

If no animations are active on this object, the fact that a conservative estimate is required permits any interval to be returned, but it is strongly recommended that the value in this case should correspond to the maximum positive integer.

Parameters:
time - world time to update the animations to
Returns:
validity interval; the number of time units until this method needs to be called again
Throws:
java.lang.IllegalStateException - if there are invalid KeyframeSequences connected to any of the Object3D's that are to be animated
See Also:
AnimationController, AnimationTrack

JSR-184 Public Review Draft - Apr. 30, 2003.

Copyright © 2003 Nokia Corporation. See the Copyright Notice for details.