M3G 1.1 -- Jun 22, 2005

javax.microedition.m3g
Class Node

java.lang.Object
  extended byjavax.microedition.m3g.Object3D
      extended byjavax.microedition.m3g.Transformable
          extended byjavax.microedition.m3g.Node
Direct Known Subclasses:
Camera, Group, Light, Mesh, Sprite3D

public abstract class Node
extends Transformable

An abstract base class for all scene graph nodes.

There are five different kinds of nodes:

Node transformation

Each node defines a local coordinate system that can be transformed relative to the coordinate system of the parent node. The transformation from the local coordinate system of a node to the coordinate system of its parent is called the node transformation.

The node transformation consists of four parts: a generic matrix M, a non-uniform scale S, an orientation R and a translation T. The bottom row of M must be equal to (0 0 0 1). The methods to manipulate the individual components are defined in the base class, Transformable.

To transform a point from a node's local coordinates to its parent's coordinates, the point is multiplied by the transformation components in the order that they are listed above. Formally, a homogeneous vector p = (x, y, z, 1), representing a 3D point in the local coordinate system, is transformed into p' = (x', y', z', 1) in the parent coordinate system as follows:

The translation, orientation and scale components of the node transformation can be animated independently from each other. The matrix component is not animatable at all; it can only be changed using the setTransform method.

Node alignment

A node may be aligned with respect to a selected reference node (or nodes). This means that the aligned node is, upon request, automatically oriented so that its coordinate system matches the reference node's coordinate system in the specified way. A common use case for node alignment is to create "billboards" that are always facing the camera; another is to make the camera always point at a certain object.

When a node is aligned, its original orientation component R is overwritten with an aligned orientation A. (The aligned orientation is computed as specified below, in the Implementation Guidelines section.) The other components of the node transformation are not affected by alignment. The transformation from the local coordinate system of an aligned node to its parent node's coordinate system is, therefore,

The application must explicitly call the align method on a node (or any of its ancestors) when it requires the alignments of that node and its descendants to be computed. This is typically done once per frame, before rendering. Rendering operations do not resolve any alignments; they simply use whatever orientation each node has at that time. The same holds true for getTransformTo and any other methods whose results depend on the orientation.

The alignment reference node(s) and the method of alignment are selected with setAlignment. This does not yet compute the new aligned orientation, but merely specifies how that is to be done. Optionally, the reference node may be left unspecified (null) until when align is called; the reference node is then supplied as a parameter to align. This is very useful for billboards, because otherwise the application would have to call setAlignment separately for every billboard in the scene whenever the camera is changed.

Inherited node properties

Besides the node transformation, there are three node properties whose effective values are in some manner influenced by the ancestors of each node. These properties are the alpha factor, the rendering enable flag, and the picking enable flag.

The alpha factor allows (groups of) Mesh and Sprite3D objects to be faded in and out in a convenient way, provided that certain preconditions related to their Appearance are met. The alpha factor is defined for each Node, and its value is between [0, 1]. The effective alpha factor for an object is obtained by multiplying its local alpha factor with the alpha factors of its ancestors. The alpha factor is ignored for Light and Camera nodes.

When rendering a Mesh, its effective alpha factor is multiplied with the alpha component of the diffuse color in each of the Material objects associated with that Mesh. In absence of a Material object, the alpha factor is applied to the alpha channel of the VertexBuffer color array, or if the color array is null, the default color alpha component. When rendering a Sprite3D, its effective alpha factor is multiplied with the alpha channel of the sprite image. Note that for both meshes and sprites, only the alpha values are ever modified. The alpha factor alone is therefore not sufficient for a fade-in/fade-out effect. Instead, the texture blending mode, the framebuffer blending mode, and the alpha threshold must all be set appropriately. For meshes, setting texture blending to MODULATE, framebuffer blending to ALPHA, and alpha threshold to zero will often produce the desired result. Sprites should use a non-zero alpha threshold and ALPHA blending in CompositingMode.

The enable flags for rendering and picking allow (groups of) mesh and sprite objects to be made "invisible" from the point of view of rendering and picking, respectively. The effective enable status of a node is the logical AND of the enable flags on that node and all its ancestors. Therefore, setting the enable flag of a node to true does not guarantee that the node will be rendered or picked. Rather, if any of its ancestors are disabled, the node will be ignored regardless of its own enable flag.

Note that the scope of a Node is not an inherited property; see below for more information.

Scoping

The scope of a Node is an integer bitmask that allows scene graph nodes to form conceptual groups independent of the scene graph hierarchy. In other words, nodes that are in a particular Group are not necessarily in the same scope. Formally, two nodes A and B are defined to be in the same scope if the bitwise AND of their scopes is non-zero:

Scopes are not hierarchic in any way. In particular, the scope of a Group or SkinnedMesh node is not propagated to or inherited by its children. After all, scopes are intended to be separate from the scene hierarchy.

Scoping serves three purposes:

The default scope is -1, implying that all nodes are in the same scope. By default, all objects are therefore visible to all cameras, and are lit by all light sources.

Instantiation

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

Implementation guidelines

The alignment rotation A is computed relative to the initial coordinate system A defined by the T component of the node transformation alone. All other transformation components of the node being aligned are ignored.

Conceptually, alignment is composed of two cumulative rotations: the shortest rotation Rz that takes the initial Z axis to the Z alignment target vector, followed by the rotation Ry about the resulting Z vector that minimizes the angle between the resulting Y axis and the Y alignment target vector. If alignment is set for one axis only, that rotation is performed like the initial Z rotation.

Formally, let us denote by tZ and tY the Z and Y alignment target vectors, transformed from their respective reference nodes to A; note that axis targets transform as vectors, and origin targets as points. The axis for the first rotation Rz is then the cross product of the local Z axis of A and the target vector:

and the rotation angle can be computed via the dot product of the two. Rotating by Rz takes us to a new coordinate frame B where tY is expressed as:

The axis for the second rotation RY is the local Z axis of B, and the angle is the angle between the local Y axis and the projection of tY' on the XY plane. The final alignment rotation A is then:

There are two cases where a rotation axis is undefined. Firstly, if either target vector coincides with the axis that it is a target for, the respective rotation must be substituted with an identity rotation. Secondly, if the target vector and the axis are opposite, the exact rotation path (that is, the resultant direction of the other two axes) is implementation dependent, but must be deterministic. Note that the latter only matters for unconstrained (single-axis) alignment.

See Also:
Binary format

Field Summary
static int NONE
          Specifies for the setAlignment method that no alignment should be done for the specified axis.
static int ORIGIN
          Specifies the origin of the reference node as an orientation reference for the setAlignment method.
static int X_AXIS
          Specifies the X axis of the reference node as an orientation reference for the setAlignment method.
static int Y_AXIS
          Specifies the Y axis of the reference node as an orientation reference for the setAlignment method.
static int Z_AXIS
          Specifies the Z axis of the reference node as an orientation reference for the setAlignment method.
 
Method Summary
 void align(Node reference)
          Applies alignments to this Node and its descendants.
 Node getAlignmentReference(int axis)
          Returns the alignment reference node for the given axis.
 int getAlignmentTarget(int axis)
          Returns the alignment target for the given axis.
 float getAlphaFactor()
          Retrieves the alpha factor of this Node.
 Node getParent()
          Returns the scene graph parent of this node.
 int getScope()
          Retrieves the scope of this Node.
 boolean getTransformTo(Node target, Transform transform)
          Gets the composite transformation from this node to the given node.
 boolean isPickingEnabled()
          Retrieves the picking enable flag of this Node.
 boolean isRenderingEnabled()
          Retrieves the rendering enable flag of this Node.
 void setAlignment(Node zRef, int zTarget, Node yRef, int yTarget)
          Sets this node to align with the given other node(s), or disables alignment.
 void setAlphaFactor(float alphaFactor)
          Sets the alpha factor for this Node.
 void setPickingEnable(boolean enable)
          Sets the picking enable flag of this Node.
 void setRenderingEnable(boolean enable)
          Sets the rendering enable flag of this Node.
 void setScope(int scope)
          Sets the scope of this node.
 
Methods inherited from class javax.microedition.m3g.Transformable
getCompositeTransform, getOrientation, getScale, getTransform, getTranslation, postRotate, preRotate, scale, setOrientation, setScale, setTransform, setTranslation, translate
 
Methods inherited from class javax.microedition.m3g.Object3D
addAnimationTrack, animate, duplicate, find, getAnimationTrack, getAnimationTrackCount, getReferences, getUserID, getUserObject, removeAnimationTrack, setUserID, setUserObject
   

Field Detail

NONE

public static final int NONE

Specifies for the setAlignment method that no alignment should be done for the specified axis.

See Also:
Constant Field Values

ORIGIN

public static final int ORIGIN

Specifies the origin of the reference node as an orientation reference for the setAlignment method.

See Also:
Constant Field Values

X_AXIS

public static final int X_AXIS

Specifies the X axis of the reference node as an orientation reference for the setAlignment method.

See Also:
Constant Field Values

Y_AXIS

public static final int Y_AXIS

Specifies the Y axis of the reference node as an orientation reference for the setAlignment method.

See Also:
Constant Field Values

Z_AXIS

public static final int Z_AXIS

Specifies the Z axis of the reference node as an orientation reference for the setAlignment method.

See Also:
Constant Field Values
Method Detail

setRenderingEnable

public void setRenderingEnable(boolean enable)

Sets the rendering enable flag of this Node. The effective rendering enable status for this node is the logical AND of the enable flags on this node and all its ancestors. Therefore, the node is disabled if any of its ancestors are. The node's own status has an effect only if all the ancestors are enabled.

If the effective status is true, this node is enabled for rendering; otherwise, it is disabled. Sprite3D, Mesh and Light nodes are turned on and off with this setting, but on Camera nodes it is ignored.

Parameters:
enable - true to enable rendering; false to disable

setPickingEnable

public void setPickingEnable(boolean enable)

Sets the picking enable flag of this Node. The effective picking enable status for this node is the logical AND of the enable flags on this node and all its ancestors. Therefore, the node is disabled if any of its ancestors are. The node's own status has an effect only if all the ancestors are enabled.

If the effective status is true, this node is enabled for picking; otherwise, it is disabled. This setting is ignored for Lights and Cameras, because they are unpickable in any case.

Parameters:
enable - true to enable picking; false to disable

setScope

public void setScope(int scope)

Sets the scope of this node. The scope is used to limit the set of nodes that are taken into account in rendering, lighting and picking. See the class description for more information.

Parameters:
scope - the new scope for this node
See Also:
getScope

setAlphaFactor

public void setAlphaFactor(float alphaFactor)

Sets the alpha factor for this Node. This can be used to fade groups of meshes and sprites in and out. The alpha factor has no effect on Light and Camera nodes. See the class description for more information.

Parameters:
alphaFactor - the new alpha factor for this node; must be [0, 1]
Throws:
java.lang.IllegalArgumentException - if alphaFactor is negative or greater than 1.0
See Also:
getAlphaFactor

isRenderingEnabled

public boolean isRenderingEnabled()

Retrieves the rendering enable flag of this Node. Note that this is not the effective rendering enable status, but only the local status of this Node.

Returns:
the rendering enable flag of this Node
See Also:
setRenderingEnable

isPickingEnabled

public boolean isPickingEnabled()

Retrieves the picking enable flag of this Node. Note that this is not the effective picking enable status, but only the local status of this Node.

Returns:
the picking enable flag of this Node
See Also:
setPickingEnable

getScope

public int getScope()

Retrieves the scope of this Node.

Returns:
the current scope of this Node
See Also:
setScope

getAlphaFactor

public float getAlphaFactor()

Retrieves the alpha factor of this Node. Note that this is not the effective alpha factor, but only the local alpha factor of this Node. To put it another way, the alpha factors of any ancestors to this Node are not multiplied in.

Returns:
the alpha factor of this node; [0, 1]
See Also:
setAlphaFactor

getParent

public Node getParent()

Returns the scene graph parent of this node.

Returns:
reference to the parent node, or null if there is no parent

getTransformTo

public boolean getTransformTo(Node target,
                              Transform transform)

Gets the composite transformation from this node to the given node. The composite transformation is defined to be such that it transforms a point in the local coordinate system of this node to the coordinate system of the given node. For example, the composite transformation from this node to its parent is equal to the node transformation of this node. Similarly, the composite transformation from this node to its child is equal to the inverse of the node transformation of the child.

If there is no path from this node to the given node, this method returns false. On the other hand, if there is a path but the transformation cannot be computed due to a singular transformation, an ArithmeticException is thrown. Beware that a transformation that is invertible in one implementation may not be invertible in another, because of different arithmetic accuracy. To be safe, avoid matrix elements with very small or very large absolute values. See also the package description.

Parameters:
target - transformation target node
transform - transform object to receive the transformation; if there is no path to the target node, the contents of the object are left undefined
Returns:
true if the returned transformation is valid; false if there is no path from this node to the target node
Throws:
java.lang.NullPointerException - if target is null
java.lang.NullPointerException - if transform is null
java.lang.ArithmeticException - if the inverse of a transformation along the path is required, but can not be computed

align

public final void align(Node reference)

Applies alignments to this Node and its descendants.

The aligned orientation for this node and all its descendants are calculated in an undefined order. The rare case where there are chains of dependencies between aligned objects is therefore not necessarily taken into account.

The orientation component of the node transformation of each aligned node is overwritten with the aligned orientation. The pre-existing orientation is not preserved.

A reference node can be passed in to this method, in order to allow alignment of objects to a common reference that is determined at run time. This is usually used to align items to the active camera, for use as billboards or impostors. Since the active camera can change, a reference to it cannot be directly encoded in the scene graph. Instead, it is passed in as an argument to this method.

See the class description and setAlignment for more information on how to set up and apply alignments.

Parameters:
reference - a node to serve as a common alignment reference for nodes that have no fixed reference in either or both axes, or null to use this node as the common reference
Throws:
java.lang.IllegalArgumentException - if reference is not in the same scene graph as this node
java.lang.IllegalStateException - if the zRef or yRef node of any aligned node is not in the same scene graph as the aligned node
java.lang.IllegalStateException - if any node is aligned to itself or its descendant (note: this applies to null alignment references, as well)
java.lang.ArithmeticException - if a transformation required in the alignment computations cannot be computed

setAlignment

public void setAlignment(Node zRef,
                         int zTarget,
                         Node yRef,
                         int yTarget)

Sets this node to align with the given other node(s), or disables alignment. Alignment can be used, for example, for automatic "look at" behavior for the camera or a spot light, and to create "billboards" that are always facing the active camera directly.

Alignment can be set or disabled for one or both of the Y and Z axes. If it is set for both, the Z alignment is applied first, followed by the Y alignment. The Y alignment is constrained by the Z alignment. If alignment is set for one axis only, it is unconstrained.

Alignment can be disabled for either or both axes by setting the respective alignment targets to NONE. If both alignments are disabled, the orientation is left at its present state. The original unaligned orientation is not restored.

Parameters:
zRef - the node to use as reference for aligning the Z axis of this node, or null to use instead the reference node passed as an argument to the align method
zTarget - the axis of zRef to align the Z axis of this node with, or ORIGIN to have the Z axis point at the origin of zRef, or NONE to not align the Z axis at all
yRef - the Y axis equivalent of zRef
yTarget - the Y axis equivalent of zTarget
Throws:
java.lang.IllegalArgumentException - if yTarget or zTarget is not one of the symbolic constants listed above
java.lang.IllegalArgumentException - if (zRef == yRef) && (zTarget == yTarget != NONE)
java.lang.IllegalArgumentException - if zRef or yRef is this Node
See Also:
align, getAlignmentTarget, getAlignmentReference
Example:
Common use cases for node alignment.
setAlignment(null, Node.NONE, null, Node.NONE);         // Disabled
 setAlignment(null, Node.Z_AXIS, null, Node.Y_AXIS);     // "Sprite"
 setAlignment(null, Node.ORIGIN, world, Node.Y_AXIS);    // Billboard
 setAlignment(target, Node.ORIGIN, target, Node.NONE);   // Target light
 setAlignment(target, Node.ORIGIN, world, Node.Y_AXIS);  // Target camera
  
 // NOTE 1:
 // The billboard alignment example requires that world space "up"
 // is Y and billboard space "up" is Z, so that the Z alignment is
 // constrained by the Y alignment and not vice versa. Otherwise,
 // the billboard will not stand upright as the camera passes from
 // above or below; instead, it will lean over and eventually lie
 // flat on the ground. The M component of the billboard's node
 // transformation can be used to rotate the billboard into the
 // right orientation; the R component can not, because it gets
 // overwritten by the aligned orientation. Another option is to
 // use an extra Group node.
 
 // NOTE 2:
 // A camera or light is always facing towards its negative Z axis
 // in its local coordinate system. To make the target camera and
 // light alignments work as expected, the Z axis must be made to
 // point in the opposite direction. This can be done by rotating
 // the node 180 degrees about its local Y axis. This, in turn,
 // can be done as described in Note 1 (above), or somewhat more
 // conveniently, using the scale (S) component:
 
 camera.scale(-1, 1, -1);    // rotate 180 degrees about the Y axis

getAlignmentTarget

public int getAlignmentTarget(int axis)
Returns the alignment target for the given axis.

Parameters:
axis - the node axis to query the target for; one of Y_AXIS and Z_AXIS
Returns:
the alignment target; one of the symbolic constants allowed for the zTarget and yTarget parameters of setAlignment
Throws:
java.lang.IllegalArgumentException - if axis is not one of the symbolic constants listed for axis above
Since:
M3G 1.1
See Also:
setAlignment, align

getAlignmentReference

public Node getAlignmentReference(int axis)
Returns the alignment reference node for the given axis.

Note that alignment reference nodes are not returned in a call to getReferences.

Parameters:
axis - the node axis to query the reference node for; one of Y_AXIS and Z_AXIS
Returns:
the alignment reference node
Throws:
java.lang.IllegalArgumentException - if axis is not one of the symbolic constants listed for axis above
Since:
M3G 1.1
See Also:
setAlignment, align

M3G 1.1 -- Jun 22, 2005

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