|
M3G 1.1 -- Jun 22, 2005 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object javax.microedition.m3g.Object3D javax.microedition.m3g.Transformable javax.microedition.m3g.Node javax.microedition.m3g.Mesh javax.microedition.m3g.MorphingMesh
A scene graph node that represents a vertex morphing polygon mesh.
MorphingMesh is equivalent to an ordinary Mesh, except that the vertices that are rendered are computed as a weighted linear combination of the base VertexBuffer and a number of morph target VertexBuffers. The resultant mesh is only used for rendering, and is not exposed to the application. The structure of a MorphingMesh object is shown in the figure below.
All morph targets must have the same properties: The same types of arrays, the same number of vertices in each array, the same number of components per vertex, and the same component size. For example, it is prohibited for one morph target to contain vertex coordinates and texture coordinates, if some other target only contains vertex coordinates. Similarly, having 2D texture coordinates in one morph target and 3D texture coordinates in another is not allowed.
The base mesh must be a "superset" of the morph targets. If an array with certain type and dimensions exists in the morph targets, a similar array must also exist in the base mesh, but not vice versa. It is illegal, for example, for the morph targets to have per-vertex colors and 8-bit coordinates if the base mesh has 16-bit coordinates and/or no colors.
Only the VertexBuffer default color and the arrays that are present in the morph targets are actually morphed. The other arrays, as well as the scale and bias values, are copied from the base mesh. Scale and bias values of the morph targets are ignored.
Denoting the base mesh with B, the morph targets with Ti, and the weights corresponding to the morph targets with wi, the resultant mesh R is computed as follows:
Any values for the weights wi are accepted, including negative values. The sum of the weights is similarly unconstrained. This allows having, for example, a model of a face with a neutral expression as the base mesh, and two morph targets where one is the base mesh but with a smiling mouth and the other with raised eyebrows. Now, setting the first weight to 1.0 makes the face smile, -0.5 could make it frown, and so on, while the eyebrow raising and lowering can be driven independent of the mouth movements.
Setting up the morph weights such that the individual weights as well as their sum are between [0, 1] ensures that the resultant mesh never grows beyond the convex hull of the base mesh and the targets. That, on the other hand, guarantees that no arithmetic overflows will occur and the results are as expected.
If the application chooses to set up the weights such that they or their sum is not in the [0, 1] interval, it should by some other means ensure that the morphed attributes of the resultant mesh will fit into the original numeric range, that is, in the same number of bits that are used in the base mesh and the morph targets. The available range for the results can be either [0, 255] or [0, 65535], for 8-bit and 16-bit components respectively. If the values do not, however, fit in that range, the results are undefined when rendering or picking.
Any intermediate values produced during morphing are subject to the dynamic range constraints that are specified in the package description. In other words, individual weights can be very large or small, as long as the resultant mesh fits in the 8/16-bit range.
The VertexBuffer scale and bias for the resultant mesh are taken from the base mesh as such, without interpolation, because correct interpolation between (integer) values that are in different (floating point) scales would require the interpolants to be first multiplied with the scale factor, and only then interpolated. This involves several floating point operations per vertex attribute, which would make morphing of anything but the most trivial meshes prohibitively expensive on current mobile hardware, for very little benefit. Note also that interpolating the scale terms separately from the values would not produce the correct results.
Any special cases and exceptions that are defined for Mesh also apply for MorphingMesh. An extra exception case is introduced due to the requirement that morph targets must be "subsets" of the base mesh, and that they must all have the same set of vertex attributes with the same dimensions, as specified above. This requirement cannot be enforced until when the morphing is actually done, that is, when rendering or picking.
Field Summary |
Fields inherited from class javax.microedition.m3g.Node |
NONE, ORIGIN, X_AXIS, Y_AXIS, Z_AXIS |
Constructor Summary | |
MorphingMesh(VertexBuffer base,
VertexBuffer[] targets,
IndexBuffer[] submeshes,
Appearance[] appearances)
Constructs a new MorphingMesh with the given base mesh and morph targets. |
|
MorphingMesh(VertexBuffer base,
VertexBuffer[] targets,
IndexBuffer submesh,
Appearance appearance)
Constructs a new MorphingMesh with the given base mesh and morph targets. |
Method Summary | |
VertexBuffer |
getMorphTarget(int index)
Returns the morph target VertexBuffer at the given index. |
int |
getMorphTargetCount()
Returns the number of morph targets in this MorphingMesh. |
void |
getWeights(float[] weights)
Gets the current morph target weights for this mesh. |
void |
setWeights(float[] weights)
Sets the weights for all morph targets in this mesh. |
Methods inherited from class javax.microedition.m3g.Mesh |
getAppearance, getIndexBuffer, getSubmeshCount, getVertexBuffer, setAppearance |
Methods inherited from class javax.microedition.m3g.Node |
align, getAlignmentReference, getAlignmentTarget, getAlphaFactor, getParent, getScope, getTransformTo, isPickingEnabled, isRenderingEnabled, setAlignment, setAlphaFactor, setPickingEnable, setRenderingEnable, setScope |
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 |
Constructor Detail |
public MorphingMesh(VertexBuffer base, VertexBuffer[] targets, IndexBuffer submesh, Appearance appearance)
Constructs a new MorphingMesh with the given base mesh and morph targets. Except for the morph targets, the behavior of this constructor is identical to the corresponding constructor in Mesh; refer to that for more information.
The morph target weights are initially set to zero, meaning that the resultant mesh is equal to the base mesh. The behavior of a newly constructed MorphingMesh is therefore equivalent to an ordinary Mesh.
base
- a VertexBuffer representing the base meshtargets
- a VertexBuffer array representing the morph targetssubmesh
- an IndexBuffer defining the triangle strips to drawappearance
- an Appearance to use for this mesh, or null
java.lang.NullPointerException
- if base
is null
java.lang.NullPointerException
- if targets
is null
java.lang.NullPointerException
- if submesh
is null
java.lang.NullPointerException
- if any element in targets
is null
java.lang.IllegalArgumentException
- if targets
is emptypublic MorphingMesh(VertexBuffer base, VertexBuffer[] targets, IndexBuffer[] submeshes, Appearance[] appearances)
Constructs a new MorphingMesh with the given base mesh and morph targets. Except for the morph targets, the behavior of this constructor is identical to the corresponding constructor in Mesh; refer to that for more information.
The morph target weights are initially set to zero, meaning that the resultant mesh is equal to the base mesh. The behavior of a newly constructed MorphingMesh is therefore equivalent to an ordinary Mesh.
base
- a VertexBuffer representing the base meshtargets
- a VertexBuffer array representing the morph targetssubmeshes
- an IndexBuffer array defining the submeshes to drawappearances
- an Appearance array parallel to
submeshes
, or null
java.lang.NullPointerException
- if base
is null
java.lang.NullPointerException
- if targets
is null
java.lang.NullPointerException
- if submeshes
is null
java.lang.NullPointerException
- if any element in
targets
is null
java.lang.NullPointerException
- if any element in
submeshes
is null
java.lang.IllegalArgumentException
- if targets
is empty
java.lang.IllegalArgumentException
- if submeshes
is empty
java.lang.IllegalArgumentException
- if (appearances != null) && (appearances.length <
submeshes.length)
Method Detail |
public VertexBuffer getMorphTarget(int index)
Returns the morph target VertexBuffer at the given index.
index
- the index of the morph target to get
index
java.lang.IndexOutOfBoundsException
- if (index < 0) ||
(index >= getMorphTargetCount)
Mesh.getVertexBuffer
public int getMorphTargetCount()
Returns the number of morph targets in this MorphingMesh.
public void setWeights(float[] weights)
Sets the weights for all morph targets in this mesh. The number of weights copied in is the number of target vertex buffers, as specified at construction time. The source array must have at least that many elements. See the class description for more information.
weights
- weight factors for all morph targets
java.lang.NullPointerException
- if weights
is null
java.lang.IllegalArgumentException
- if weights.length <
getMorphTargetCount
getWeights
public void getWeights(float[] weights)
Gets the current morph target weights for this mesh.
weights
- array to be populated with the morph target weights
java.lang.NullPointerException
- if weights
is null
java.lang.IllegalArgumentException
- if weights.length <
getMorphTargetCount
setWeights
|
M3G 1.1 -- Jun 22, 2005 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |