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

javax.microedition.m3d
Class Sprite

java.lang.Object
  |
  +--javax.microedition.m3d.Object3D
        |
        +--javax.microedition.m3d.Node
              |
              +--javax.microedition.m3d.Sprite

public class Sprite
extends Node

Sprite is a scene graph node representing a 2-dimensional image that has a 3D position. It is a fast, but functionally restricted alternative to textured geometry. A sprite is rendered as a screen-aligned rectangular array of pixels with a constant depth. The apparent size of a sprite may be specified directly in pixels (an unscaled sprite) or indirectly using the transformation of the Sprite node (a scaled sprite).

The structure of a Sprite object is shown in the figure below.

Sprite image data

The Sprite image is stored as a reference to an Image2D. The image may be in any of the formats defined in Image2D, with or without a palette. The width and height of the image are not limited in any way; in particular, they need not be powers of two. However, there is an implementation defined maximum size for the crop rectangle (the area of the sprite that is actually displayed). This can be queried with Graphics3D.getProperties().

If the referenced Image2D is modified by the application (by rendering into it), or a new Image2D is bound as the sprite image, the modifications are immediately reflected in the Sprite. Be aware, however, that changing or updating the sprite image may trigger time-consuming operations.

Sprite positioning

The position of a sprite on screen is determined by projecting the origin of its coordinate system to screen coordinates. The resulting 2D position is used as the center of the displayed pixel array. If this causes any part of the sprite to be placed off screen, then the sprite is clipped to the viewport as usual (refer to Graphics3D).

The width and height of an unscaled sprite on screen are measured in pixels, and they are equal to the (absolute) width and height of the crop rectangle. The width and height of a scaled sprite on screen are computed as if the sprite were a rectangle with unit-length sides, centered at the origin of its coordinate system, and with alignment set so that the coordinate system is parallel in all axes with the active camera coordinate system.

The depth value of a sprite is constant across the image, and is the depth of the origin of the sprite's coordinate system.

Rendering attributes

The rendering attributes of a sprite are determined by its Appearance, as is the case with Mesh objects. There are a number of properties in Appearance, however, that do not have a meaningful interpretation in this context. Thus, only the CompositingMode and Fog components, as well as the layer index, are taken into account when rendering a sprite. The rest of the components are ignored. This implies, in particular, that lighting does not apply for sprites.

All properties inherited from Object3D, as well as most properties inherited from Node, are applicable for sprites. The only exception is the cumulative per-object alpha factor, which is ignored because it only applies for lighted objects. Also, sprites are always screen-aligned, regardless of their node alignment settings.

Sprite picking

Unscaled sprites are ignored when picking. A scaled sprite, on the other hand, is treated as a unit-size rectangle centered at the origin of the sprite node's coordinate system; exactly as if it were being rendered. When picking from a Camera, the sprite node is aligned in all axes to the coordinate system of that camera, again as if it were being rendered. When picking from a Group, the sprite node is aligned to the given reference node in the same way.

If a sprite is intersected by the pick ray, the pixel in the sprite image at the intersection point will be further tested for transparency. If the pixel is fully transparent, the sprite is not picked and the pick ray will continue towards objects that are further away. If the pixel is not fully transparent, the sprite is picked. The pixel is defined to be fully transparent if and only if it fails the alpha test (see CompositingMode.setAlphaThreshold(float)).

Implementation guidelines

Sprites do not provide any functionality that would not be available otherwise; they can always be substituted with textured geometry. However, the existence of the Sprite primitive acts as a signal to the renderer that a very specific subset of functionality is required. This allows the rendering pipeline to avoid the overhead of transforming and lighting full geometry. It also allows the rasterizer to select an optimized drawing routine to place the pixels on the screen, without the potentially complex interpolation of parameters across the rectangle. This can be used to make sprites very much faster than textured geometry (especially in software) which in turn increases the richness of content that can be offered at the low end.

Sprites can be implemented as textured rectangles. The restriction on the maximum crop rectangle size is in place because otherwise implementations using this method would be forced to downsample larger crop rectangles to the maximum texture size; an expensive operation.

When implementing unscaled sprites with texture mapping, care must be taken that rounding errors (or similar) do not yield unwelcome artifacts, such as pixel columns appearing and disappearing depending on the screen position of the sprite. This is particularly important for text labels.

Filtering of scaled sprites can be implemented with the simple nearest neighbor algorithm, but implementations are free to apply more sophisticated schemes, such as mipmapping. No application control over the filtering behavior is provided, however; if that is required, textured rectangles can be used instead.

The position, width and height of a sprite on screen are worked out from the Sprite node's local coordinate system as follows:

Three reference points O (0,0,0), X (1,0,0) and Y (0,1,0) are first transformed from the local coordinate system into normalized device coordinates. More precisely, each point is first transformed into the camera space, then multiplied with the projection matrix to get into clip space, and finally mapped into normalized device coordinates by dividing the X, Y and Z components by the W component. Note that the W components of the transformed points will be equal, due to the alignment of the Sprite node. As a result, three points O', X' and Y' are obtained.

The position of the center of the sprite in normalized device coordinates is O'. Similarly, the width and height of a scaled sprite are the magnitudes of the two vectors X'-O' and Y'-O', respectively.

See Also:
Binary format

Field Summary
 
Fields inherited from class javax.microedition.m3d.Node
NONE, ORIGIN, X_AXIS, Y_AXIS, Z_AXIS
 
Fields inherited from class javax.microedition.m3d.Object3D
userObject
 
Constructor Summary
Sprite(boolean scaled, Image2D image)
          Constructs a new Sprite with the given scaling mode and image.
 
Method Summary
 Appearance getAppearance()
          Gets the current Appearance of this Sprite.
 int getCropHeight()
          Gets the current cropping rectangle height within the source image.
 int getCropWidth()
          Gets the current cropping rectangle width within the source image.
 int getCropX()
          Gets the current cropping rectangle X offset within the source image.
 int getCropY()
          Gets the current cropping rectangle Y offset within the source image.
 Image2D getImage()
          Gets the current Sprite image..
 boolean isScaled()
          Returns the automatic scaling status of this Sprite.
 void setAppearance(Appearance appearance)
          Sets the Appearance of this Sprite.
 void setCrop(int cropX, int cropY, int width, int height)
          Sets a cropping rectangle within the source image.
 void setImage(Image2D image)
          Sets the image to display.
 
Methods inherited from class javax.microedition.m3d.Node
getAlphaFactor, getOrientation, getParent, getScale, getScopeID, getTransform, getTransformTo, getTranslation, isEnabled, setAlignment, setAlphaFactor, setEnable, setOrientation, setScale, setScopeID, setTransform, setTranslation
 
Methods inherited from class javax.microedition.m3d.Object3D
addAnimationTrack, animate, clone, find, getAnimationTrack, getAnimationTrackCount, getReferences, getUserID, removeAnimationTrack, setUserID
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Sprite

public Sprite(boolean scaled,
              Image2D image)

Constructs a new Sprite with the given scaling mode and image. The scaling mode cannot be changed after construction. The size of an unscaled sprite on the screen is the same as the size of its crop rectangle (both measured in pixels). The size of a scaled sprite on the screen, on the other hand, is equal to the size of a screen-aligned rectangle with unit-length sides, centered at the origin of the sprite node's coordinate system.

The unspecified parameters of the constructed sprite are set as follows:

Parameters:
scaled - true to make this Sprite scaled; false to disable scaling
image - pixel data and image properties to use to draw the sprite
Method Detail

isScaled

public boolean isScaled()

Returns the automatic scaling status of this Sprite. Note that the scaling mode cannot be changed after construction. TODO: Is this method necessary? What can the application do with that information?

Returns:
true if this Sprite is scaled; false if it is unscaled

setAppearance

public void setAppearance(Appearance appearance)

Sets the Appearance of this Sprite. Note that the GeometryMode, Texture and Material components of the Appearance are ignored. If the Appearance is set to null, this Sprite will be disabled when rendering or picking.

Parameters:
appearance - Appearance to set for this Sprite, or null to disable this Sprite
See Also:
getAppearance

getAppearance

public Appearance getAppearance()

Gets the current Appearance of this Sprite.

Returns:
current Appearance of this Sprite
See Also:
setAppearance

setImage

public void setImage(Image2D image)

Sets the image to display. The crop rectangle is reset such that its top left corner is at the top left corner of the image, and its width and height are equal to those of the image. However, if the width (or height) of the image exceeds the implementation defined maximum, the crop rectangle width (or height) is set to that maximum value instead.

Parameters:
image - pixel data and image properties to use to draw the sprite
See Also:
getImage

getImage

public Image2D getImage()

Gets the current Sprite image..

Returns:
the Image2D object used to draw the sprite
See Also:
setImage

setCrop

public void setCrop(int cropX,
                    int cropY,
                    int width,
                    int height)

Sets a cropping rectangle within the source image. This allows a subsection of the image to be used as the source for the pixels of the sprite. This can be used for selection of individual frames of animation, scrolling of captions, or other effects.

The position of the upper left corner of the crop rectangle is given in pixels, relative to the upper left corner of the Image2D. The width and/or height of the crop rectangle may be less than 0, in which case the image data is flipped in the X and/or Y axes, respectively. Note that the crop rectangle remains in the same position within the source image regardless of the signs of the width and height; only the drawing order of the pixels is changed.

No wrapping or clamping of the source image is supported - the crop rectangle must lie completely within the source image. The width and height are limited to an implementation defined maximum value that can be queried from Graphics3D.

Parameters:
cropX - the X position of the top left of the crop rectangle, in pixels
cropY - the Y position of the top left of the crop rectangle, in pixels
width - the required width of the crop rectangle, in pixels
height - the required height of the crop rectangle, in pixels
Throws:
java.lang.IllegalArgumentException - if width or height is zero or its absolute value exceeds the implementation defined maximum
java.lang.IllegalArgumentException - if any part of the crop rectangle falls outside the bounds of the source image

getCropX

public int getCropX()

Gets the current cropping rectangle X offset within the source image.

Returns:
the X offset of the cropping rectangle from the top left corner of the image
See Also:
setCrop

getCropY

public int getCropY()

Gets the current cropping rectangle Y offset within the source image.

Returns:
the Y offset of the cropping rectangle from the top left corner of the image
See Also:
setCrop

getCropWidth

public int getCropWidth()

Gets the current cropping rectangle width within the source image. The width may be negative, in which case the image data is flipped in the X axis.

Returns:
the width of the cropping rectangle
See Also:
setCrop

getCropHeight

public int getCropHeight()

Gets the current cropping rectangle height within the source image. The height may be negative, in which case the image data is flipped in the Y axis.

Returns:
the height of the cropping rectangle
See Also:
setCrop

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

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