M3G 1.1 -- Jun 22, 2005

javax.microedition.m3g
Class Object3D

java.lang.Object
  extended byjavax.microedition.m3g.Object3D
Direct Known Subclasses:
AnimationController, AnimationTrack, Appearance, Background, CompositingMode, Fog, Image2D, IndexBuffer, KeyframeSequence, Material, PolygonMode, Transformable, 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, other 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 IDs 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 reachable from 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.

An object O is defined to be reachable from itself and from all objects that have a chain of direct references to it. The parent reference and the alignment references in a Node do not count as direct references.

The operation of find is illustrated in the figure below.

Associated user data

Object3D has an attribute called the user object. The user object may contain any arbitrary Object, whose interpretation and usage are entirely up to each application. The user object is held by reference, and its contents are never accessed by the implementation.

If an Object3D is loaded from a file by the Loader, the user object may contain a Hashtable that stores byte array values keyed by Integers. This is the case when one or more user parameters are associated with the serialized Object3D; see also the file format specification. If there are no user parameters, the user object is initially set to null.

A typical example of using this type of persistent user data is to include application parameters inside a scene graph, 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 it directly with the Object3D that represents the character.

Instantiation

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

See Also:
Binary format

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 Object3Ds that are reachable from this Object3D.
 Object3D duplicate()
          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.
 java.lang.Object getUserObject()
          Retrieves the user object that is currently associated with this Object3D.
 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.
 void setUserObject(java.lang.Object userObject)
          Associates an arbitrary, application specific Object with this Object3D.
   

Method Detail

animate

public final int animate(int time)

Updates all animated properties in this Object3D and all Object3Ds that are reachable from this Object3D. Objects that are not reachable are not affected. See the class description for the definition of reachability.

Animated properties are set to their interpolated values pertaining to the time given as a parameter. The pre-existing values of the target properties are overwritten with the animated values, discarding the pre-existing values. The original values are not restored even if the animation is terminated.

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 time unit is. Milliseconds are often used by convention, but any other unit is 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 should be increased by 50 between successive calls, assuming a time unit of one millisecond.

Even though strictly increasing values of time are often used, this is not a requirement. The application can pass in any time value. To put it another way, the animation system supports random access. This allows the application to, for example, rewind or restart the animations easily.

In order to allow the application to throttle the frame rate depending on the characteristics 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 for this or any reachable Object3D
Throws:
java.lang.IllegalStateException - if any active animation violates the constraints defined in KeyframeSequence
See Also:
KeyframeSequence, AnimationController, AnimationTrack

duplicate

public final Object3D duplicate()

Creates a duplicate of this Object3D.

Duplication has no effect on this object or any other existing object; it merely creates one or more new objects.

As a general rule, a duplicate object will have exactly the same properties as the original object, including attribute values, references to other objects, and any other contained data. However, if this object is a Node, duplication is done as follows:

  1. This Node is always copied. The parent of the duplicate Node is set to null.
  2. Any descendants of this Node are themselves duplicated; this includes the skeleton group of a SkinnedMesh. Any other referenced objects are not duplicated.
  3. If any Node in the duplicate set of Nodes refers to any Node in the original set, then that reference is updated to the corresponding Node in the duplicate set. All other references are left as they are, even if this results in a scene graph branch that is in an illegal state.

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

Duplication is not supported for user defined classes. That is, if the application extends any class defined in this API, any instances of that class will be treated by this method as instances of the base class. For example, duplicating an instance of MonsterMesh (derived from Mesh) will produce just a Mesh instance, not a MonsterMesh instance.

This method is similar to the clone method that is available on the higher end Java platforms, such as J2SE and J2ME/CDC. This method is likely to be deprecated once the proper java.lang.Object.clone method becomes available also on CLDC.

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

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. See the class description for the definition of reachability.

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

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.

The parent reference and the alignment references in a Node do not count as direct references, and are hence not returned. Also, null references are never returned.

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 != null) && (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...
           traverseDescendants(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)

setUserObject

public void setUserObject(java.lang.Object userObject)

Associates an arbitrary, application specific Object with this Object3D. The given user object replaces any previously set object. See the class description for more information.

The user object is stored by reference. Its contents are never accessed by the implementation, but the reference is copied in the duplicate operation.

Parameters:
userObject - the Object to associate with this Object3D, or null to remove any existing association
See Also:
getUserObject

getUserObject

public java.lang.Object getUserObject()

Retrieves the user object that is currently associated with this Object3D. If an Object3D is constructed by the Loader, the user object may initially be a Hashtable containing persistent user data in the form of byte arrays keyed by Integers.

Returns:
the current user object associated with this Object3D
See Also:
setUserObject

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.

Parameters:
animationTrack - a compatible animation track to attach to this object
Throws:
java.lang.NullPointerException - if animationTrack is null
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 < 0 || index >= 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, or is null, 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

M3G 1.1 -- Jun 22, 2005

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