com.jme.scene
Class MorphingTriMesh

java.lang.Object
  extended by com.jme.scene.Spatial
      extended by com.jme.scene.Geometry
          extended by com.jme.scene.TriMesh
              extended by com.jme.scene.MorphingTriMesh
All Implemented Interfaces:
MorphingGeometry, ListenableStringFloatMap.FloatListener, Savable, java.io.Serializable

public class MorphingTriMesh
extends TriMesh
implements MorphingGeometry

A MorphingGeometry implementation for TriMesh component morph Geometries.

Only component TriMeshes of mode Triangles are supported.

The base morph must have >= vertexes as the other morphs.

TODO: Optimize the instantiation procedure. It's pretty complicated to get to reconstitute or instantiate local and delegated influences properly without invoking expensive but unnecessary forceMorphs.

Author:
Blaine Simpson (blaine dot simpson at admc dot com)
See Also:
#MorphingGeometry, Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class com.jme.scene.TriMesh
TriMesh.Mode
 
Nested classes/interfaces inherited from class com.jme.scene.Spatial
Spatial.CullHint, Spatial.LightCombineMode, Spatial.NormalsMode, Spatial.TextureCombineMode
 
Field Summary
protected  boolean autoMorph
           
protected  TriMesh baseMorph
           
protected  java.util.Map<TriMesh,java.nio.FloatBuffer> extrapolatedNormBuf
           
protected  java.util.Map<TriMesh,java.nio.FloatBuffer> extrapolatedVertBuf
           
protected  ListenableStringFloatMap localMorphInfluencesMap
          This one is persisted with this MorphingTriMesh instance
protected  ListenableStringFloatMap morphInfluencesMap
          This one may be a reference to a remotely managed map
protected  java.util.List<java.lang.String> morphKeys
           
protected  java.util.List<TriMesh> morphs
           
protected  boolean needExtrapolation
           
(package private) static long serialVersionUID
           
 
Fields inherited from class com.jme.scene.TriMesh
indexBuffer, mode, triangleQuantity
 
Fields inherited from class com.jme.scene.Geometry
binormalBuf, bound, castsShadows, colorBuf, compVect, defaultColor, displayListID, enabled, fogBuf, hasDirtyVertices, normBuf, states, tangentBuf, texBuf, vboInfo, vertBuf, vertQuantity
 
Fields inherited from class com.jme.scene.Spatial
collisionBits, cullHint, frustrumIntersects, geometricalControllers, lightCombineMode, localRotation, localScale, localTranslation, LOCKED_BOUNDS, LOCKED_BRANCH, LOCKED_MESH_DATA, LOCKED_NONE, LOCKED_SHADOWS, LOCKED_TRANSFORMS, lockedMode, name, normalsMode, parent, queueDistance, renderQueueMode, renderStateList, textureCombineMode, worldBound, worldRotation, worldScale, worldTranslation, zOrder
 
Constructor Summary
MorphingTriMesh()
          Constructor for internal use only.
MorphingTriMesh(TriMesh baseMorph)
          Normal constructor.
 
Method Summary
 void addMorph(java.lang.String morphKey, Geometry morphGeo)
          Add a component Geometry morph with same quantity of vertexes as the base morph.
 boolean delegateInfluences()
          If we have an influences map before you invoke this method (either local or remote), it will be retained unless we successfully find delegate to another (in which case 'yes' will be returned).
 void draw(Renderer r)
          draw calls super to set the render state then passes itself to the renderer.
protected  void enforceEquality(java.lang.String label, java.nio.FloatBuffer fb1, java.nio.FloatBuffer fb2)
           
protected  void extrapolateMorphBuffers()
          Extrapolate component morph FloatBuffers to match the size of the base Morph geometry.
 void floatChanged(StringFloatMap sfm)
           
 void forceMorph()
          Unconditionally merges the relevant floats from FloabBuffers of the component morphs.
 ListenableStringFloatMap getMorphInfluencesMap()
           
protected  java.nio.FloatBuffer getMorphNormBuffer(TriMesh m)
           
protected  java.nio.FloatBuffer getMorphVertBuffer(TriMesh m)
           
 SkinNode getSkinNode()
           
 void initBase()
          Replaces data other than merge data, by copying from the virgin base morph TriMesh.
protected  java.nio.FloatBuffer mergeBuffers(java.nio.FloatBuffer baseBuffer, java.util.List<java.nio.FloatBuffer> morphBuffers, float[] influences)
          Assumes that influence.length == morphBuffers.size() - 1
 void morph()
          Morphs (verb) if any of the morphs (noun) or any of the morph influence values have changed.
 void read(JMEImporter e)
           
 void setAutoMorph(boolean autoMorph)
          Causes morph merges to automatically occur as needed during update loops.
 void setMorphInfluences(java.util.Map<? extends java.lang.String,? extends java.lang.Float> m)
          Assign morph influence values.
 void setMorphInfluencesMap(ListenableStringFloatMap m)
          Set a local morph influences map.
 void setSingleMorphInfluence(java.lang.String morphKey, float influence)
          Use setMorphInfluences if you want to change multiple floats, to avoid unnecessary listener callbacks.
 void updateGeometricState(float time, boolean initiator)
          updateGeometricState updates all the geometry information for the node.
 void write(JMEExporter e)
           
 
Methods inherited from class com.jme.scene.TriMesh
clearBuffers, findCollisions, findTriangleCollision, findTrianglePick, getIndexBuffer, getMaxIndex, getMeshAsTriangles, getMeshAsTrianglesVertices, getMode, getTriangle, getTriangle, getTriangleCount, getTriangleIndices, getVertIndex, hasCollision, hasTriangleCollision, hasTriangleCollision, randomPointOnTriangles, recalcTriangleQuantity, reconstruct, setIndexBuffer, setMode, setTriangleQuantity
 
Methods inherited from class com.jme.scene.Geometry
addTextureCoordinates, addTextureCoordinates, applyRenderState, checkTextureCoordinates, clearTextureBuffers, copyTextureCoordinates, copyTextureCoordinates, findPick, getBinormalBuffer, getColorBuffer, getDefaultColor, getDisplayListID, getFogBuffer, getLightState, getModelBound, getNormalBuffer, getNumberOfUnits, getTangentBuffer, getTextureCoords, getTextureCoords, getVBOInfo, getVertexBuffer, getVertexCount, getWorldCoords, getWorldNormals, hasDirtyVertices, isCastsShadows, lockMeshes, postdraw, predraw, randomVertex, reconstruct, resizeTextureIds, rotateNormals, rotatePoints, scaleTextureCoordinates, scaleTextureCoordinates, setBinormalBuffer, setCastsShadows, setColorBuffer, setDefaultColor, setDisplayListID, setFogCoordBuffer, setHasDirtyVertices, setLightState, setModelBound, setNormalBuffer, setRandomColors, setSolidColor, setTangentBuffer, setTextureCoords, setTextureCoords, setTextureCoords, setVBOInfo, setVertexBuffer, setVertexCount, sortLights, translatePoints, translatePoints, unlockMeshes, updateModelBound, updateWorldBound
 
Methods inherited from class com.jme.scene.Spatial
addController, calculateCollisions, calculateCollisions, calculatePick, calculatePick, clearControllers, clearRenderState, clearRenderState, findCollisions, findPick, getClassTag, getCollisionMask, getController, getControllerCount, getControllers, getCullHint, getLastFrustumIntersection, getLightCombineMode, getLocalCullHint, getLocalLightCombineMode, getLocalNormalsMode, getLocalRenderQueueMode, getLocalRotation, getLocalScale, getLocalTextureCombineMode, getLocalToWorldMatrix, getLocalTranslation, getLocks, getName, getNormalsMode, getParent, getRenderQueueMode, getRenderState, getRenderState, getTextureCombineMode, getUserData, getWorldBound, getWorldRotation, getWorldScale, getWorldTranslation, getZOrder, hasAncestor, hasCollision, isCollidable, isCollidable, localToWorld, lock, lock, lockBounds, lockBranch, lockMeshes, lockShadows, lockTransforms, lookAt, matches, matches, onDraw, propagateBoundToRoot, propagateStatesFromRoot, removeController, removeController, removeFromParent, removeUserData, rotateUpTo, setCollisionMask, setCullHint, setIsCollidable, setLastFrustumIntersection, setLightCombineMode, setLocalRotation, setLocalRotation, setLocalScale, setLocalScale, setLocalTranslation, setLocalTranslation, setLocks, setLocks, setName, setNormalsMode, setParent, setRenderQueueMode, setRenderState, setTextureCombineMode, setUserData, setZOrder, setZOrder, toString, unlock, unlock, unlockBounds, unlockBranch, unlockMeshes, unlockShadows, unlockTransforms, updateRenderState, updateRenderState, updateWorldData, updateWorldRotation, updateWorldScale, updateWorldTranslation, updateWorldVectors, updateWorldVectors, worldToLocal
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface com.jme.util.export.Savable
getClassTag
 

Field Detail

serialVersionUID

static final long serialVersionUID
See Also:
Constant Field Values

extrapolatedVertBuf

protected java.util.Map<TriMesh,java.nio.FloatBuffer> extrapolatedVertBuf

extrapolatedNormBuf

protected java.util.Map<TriMesh,java.nio.FloatBuffer> extrapolatedNormBuf

morphs

protected java.util.List<TriMesh> morphs

morphKeys

protected java.util.List<java.lang.String> morphKeys

baseMorph

protected TriMesh baseMorph

needExtrapolation

protected boolean needExtrapolation

morphInfluencesMap

protected ListenableStringFloatMap morphInfluencesMap
This one may be a reference to a remotely managed map


localMorphInfluencesMap

protected ListenableStringFloatMap localMorphInfluencesMap
This one is persisted with this MorphingTriMesh instance


autoMorph

protected boolean autoMorph
Constructor Detail

MorphingTriMesh

public MorphingTriMesh()
Constructor for internal use only.


MorphingTriMesh

public MorphingTriMesh(TriMesh baseMorph)
Normal constructor. For local influence control, you should run

     morphingTriMesh.addMorph(...);... // anytime before morph()ing
     morphingTriMesh.setMorphInfluencesMap(
             new ListenableStringFloatMap());
     morphingTriMesh.setMorphInfluences(...);
     morphingTriMesh.morph();
 
before attaching to a live scene. For remote influence control, if you know there is an available ancestor Node MorphInfluencesMapProvider, run

     morphingTriMesh.addMorph(...);... // anytime before morph()ing
     morphingTriMesh.delegateInfluences();
     morphingTriMesh.morph();
 
between attaching to the scene and rendering (like in a single update() run).

If you want to delegate but aren't certain a capable ancestor is at-hand, then run


     morphingTriMesh.addMorph(...);... // anytime before morph()ing
     morphingTriMesh.setMorphInfluencesMap(
             new ListenableStringFloatMap());
     morphingTriMesh.setMorphInfluences(...);
     morphingTriMesh.delegateInfluences();
     morphingTriMesh.morph();
 
In this case, the local morphingInfluencesMap that you set up will be overridden if the following delegateInfluences() call finds a provider.

Method Detail

getMorphVertBuffer

protected java.nio.FloatBuffer getMorphVertBuffer(TriMesh m)
Returns:
the extrapolated vertexBuffer for the specified Morph, if one was generated. Otherwise, return the traditional vert buffer for it.

getMorphNormBuffer

protected java.nio.FloatBuffer getMorphNormBuffer(TriMesh m)
Returns:
the extrapolated normBuffer for the specified Morph, if one was generated. Otherwise, return the traditional norm buffer for it.

getMorphInfluencesMap

public ListenableStringFloatMap getMorphInfluencesMap()
Specified by:
getMorphInfluencesMap in interface MorphingGeometry
Returns:
The morph influences map controlling the MorphingGeometry. It may be a non-local (delegated) influences map.
See Also:
#MorphingGeometry#getMorphInfluencesMap()

setMorphInfluencesMap

public void setMorphInfluencesMap(ListenableStringFloatMap m)
Description copied from interface: MorphingGeometry
Set a local morph influences map. If there were an influences map in use before (local or remote), it will be removed or disassociated-from first.

Specified by:
setMorphInfluencesMap in interface MorphingGeometry
See Also:
#MorphingGeometry#setMorphInfluencesMap(ListenableStringFloatMap)

setSingleMorphInfluence

public void setSingleMorphInfluence(java.lang.String morphKey,
                                    float influence)
Description copied from interface: MorphingGeometry
Use setMorphInfluences if you want to change multiple floats, to avoid unnecessary listener callbacks.

Specified by:
setSingleMorphInfluence in interface MorphingGeometry
See Also:
#MorphingGeometry#setSingleMorphInfluence(String, float)

setMorphInfluences

public void setMorphInfluences(java.util.Map<? extends java.lang.String,? extends java.lang.Float> m)
Description copied from interface: MorphingGeometry
Assign morph influence values.

Specified by:
setMorphInfluences in interface MorphingGeometry
See Also:
#MorphingGeometry#setMorphInfluences( Map)

delegateInfluences

public boolean delegateInfluences()
Description copied from interface: MorphingGeometry
If we have an influences map before you invoke this method (either local or remote), it will be retained unless we successfully find delegate to another (in which case 'yes' will be returned).

Specified by:
delegateInfluences in interface MorphingGeometry
Returns:
true if we successfully fetched a new influences map from a provider.
See Also:
#MorphingGeometry#delegateInfluences()

addMorph

public void addMorph(java.lang.String morphKey,
                     Geometry morphGeo)
Description copied from interface: MorphingGeometry
Add a component Geometry morph with same quantity of vertexes as the base morph. Do not use this method to set the base morph.

Specified by:
addMorph in interface MorphingGeometry
Parameters:
morphGeo - Must be a TriMesh instance.
morphKey - Key in the influences map for the influence for this morph.
See Also:
#MorphingGeometry#addMorph(String, Geometry)

enforceEquality

protected void enforceEquality(java.lang.String label,
                               java.nio.FloatBuffer fb1,
                               java.nio.FloatBuffer fb2)

initBase

public void initBase()
Replaces data other than merge data, by copying from the virgin base morph TriMesh.


morph

public void morph()
Description copied from interface: MorphingGeometry
Morphs (verb) if any of the morphs (noun) or any of the morph influence values have changed. This method should only be called from an update thread.

Specified by:
morph in interface MorphingGeometry
See Also:
#MorphingGeometry#morph()

forceMorph

public void forceMorph()
Description copied from interface: MorphingGeometry
Unconditionally merges the relevant floats from FloabBuffers of the component morphs. This method should only be called from an update thread.

Specified by:
forceMorph in interface MorphingGeometry
See Also:
#MorphingGeometry#forceMorph()

getSkinNode

public SkinNode getSkinNode()
Specified by:
getSkinNode in interface MorphingGeometry
Returns:
Grandparent SkinNode IFF this MorphingGeometry is a currently- attached Skin geometry.
See Also:
MorphingGeometry.getSkinNode()

mergeBuffers

protected java.nio.FloatBuffer mergeBuffers(java.nio.FloatBuffer baseBuffer,
                                            java.util.List<java.nio.FloatBuffer> morphBuffers,
                                            float[] influences)
Assumes that influence.length == morphBuffers.size() - 1

Returns:
null if all the input buffers are null.

write

public void write(JMEExporter e)
           throws java.io.IOException
Specified by:
write in interface Savable
Overrides:
write in class TriMesh
Throws:
java.io.IOException

read

public void read(JMEImporter e)
          throws java.io.IOException
Specified by:
read in interface Savable
Overrides:
read in class TriMesh
Throws:
java.io.IOException

floatChanged

public void floatChanged(StringFloatMap sfm)
Specified by:
floatChanged in interface ListenableStringFloatMap.FloatListener

draw

public void draw(Renderer r)
Description copied from class: TriMesh
draw calls super to set the render state then passes itself to the renderer. LOGIC: 1. If we're not RenderQueue calling draw goto 2, if we are, goto 3 2. If we are supposed to use queue, add to queue and RETURN, else 3 3. call super draw 4. tell renderer to draw me.

Overrides:
draw in class TriMesh
Parameters:
r - the renderer to display
See Also:
Spatial.draw(com.jme.renderer.Renderer)

setAutoMorph

public void setAutoMorph(boolean autoMorph)
Description copied from interface: MorphingGeometry
Causes morph merges to automatically occur as needed during update loops.

Specified by:
setAutoMorph in interface MorphingGeometry
See Also:
#MorphingGeometry#setAutoMorph(boolean)

updateGeometricState

public void updateGeometricState(float time,
                                 boolean initiator)
Description copied from class: Spatial
updateGeometricState updates all the geometry information for the node.

Overrides:
updateGeometricState in class Spatial
Parameters:
time - the frame time.
initiator - true if this node started the update process.

extrapolateMorphBuffers

protected void extrapolateMorphBuffers()
Extrapolate component morph FloatBuffers to match the size of the base Morph geometry. This will be called automatically by forceMorph(), but in many cases it would be better to call this explicitly ahead-of-time rather than pausing a frame cycle mid-game.



Copyright 2003-2009 jMonkeyEngine