Various fixes, added support for model instancing.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4035 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -43,6 +43,7 @@ import com.samskivert.util.ObserverList;
|
|||||||
|
|
||||||
import com.jme.math.Quaternion;
|
import com.jme.math.Quaternion;
|
||||||
import com.jme.math.Vector3f;
|
import com.jme.math.Vector3f;
|
||||||
|
import com.jme.renderer.CloneCreator;
|
||||||
import com.jme.scene.Controller;
|
import com.jme.scene.Controller;
|
||||||
import com.jme.scene.Spatial;
|
import com.jme.scene.Spatial;
|
||||||
|
|
||||||
@@ -89,6 +90,25 @@ public class Model extends ModelNode
|
|||||||
/** The animation transforms (one transform per target per frame). */
|
/** The animation transforms (one transform per target per frame). */
|
||||||
public transient Transform[][] transforms;
|
public transient Transform[][] transforms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebinds this animation for a prototype instance.
|
||||||
|
*
|
||||||
|
* @param pnodes a mapping from prototype nodes to instance nodes
|
||||||
|
*/
|
||||||
|
public Animation rebind (HashMap pnodes)
|
||||||
|
{
|
||||||
|
Animation anim = new Animation();
|
||||||
|
anim.frameRate = frameRate;
|
||||||
|
anim.repeatType = repeatType;
|
||||||
|
anim.transforms = transforms;
|
||||||
|
anim.transformTargets = new Spatial[transformTargets.length];
|
||||||
|
for (int ii = 0; ii < transformTargets.length; ii++) {
|
||||||
|
anim.transformTargets[ii] =
|
||||||
|
(Spatial)pnodes.get(transformTargets[ii]);
|
||||||
|
}
|
||||||
|
return anim;
|
||||||
|
}
|
||||||
|
|
||||||
private void writeObject (ObjectOutputStream out)
|
private void writeObject (ObjectOutputStream out)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
@@ -234,7 +254,8 @@ public class Model extends ModelNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an animation to the model's library.
|
* Adds an animation to the model's library. This should only be called by
|
||||||
|
* the model compiler.
|
||||||
*/
|
*/
|
||||||
public void addAnimation (String name, Animation anim)
|
public void addAnimation (String name, Animation anim)
|
||||||
{
|
{
|
||||||
@@ -249,6 +270,9 @@ public class Model extends ModelNode
|
|||||||
*/
|
*/
|
||||||
public String[] getAnimations ()
|
public String[] getAnimations ()
|
||||||
{
|
{
|
||||||
|
if (_prototype != null) {
|
||||||
|
return _prototype.getAnimations();
|
||||||
|
}
|
||||||
return (_anims == null) ? new String[0] :
|
return (_anims == null) ? new String[0] :
|
||||||
_anims.keySet().toArray(new String[_anims.size()]);
|
_anims.keySet().toArray(new String[_anims.size()]);
|
||||||
}
|
}
|
||||||
@@ -261,17 +285,21 @@ public class Model extends ModelNode
|
|||||||
if (_anim != null) {
|
if (_anim != null) {
|
||||||
stopAnimation();
|
stopAnimation();
|
||||||
}
|
}
|
||||||
_anim = _anims.get(name);
|
Animation anim = _anims.get(name);
|
||||||
if (_anim == null) {
|
if (anim != null) {
|
||||||
Log.warning("Requested unknown animation [name=" +
|
startAnimation(name, anim);
|
||||||
name + "].");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_animName = name;
|
if (_prototype != null) {
|
||||||
_fidx = 0;
|
Animation panim = _prototype._anims.get(name);
|
||||||
_nidx = 1;
|
if (panim != null) {
|
||||||
_fdir = +1;
|
_anims.put(name, anim = panim.rebind(_pnodes));
|
||||||
_elapsed = 0f;
|
startAnimation(name, anim);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.warning("Requested unknown animation [name=" +
|
||||||
|
name + "].");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -353,6 +381,55 @@ public class Model extends ModelNode
|
|||||||
_props = (Properties)in.readObject();
|
_props = (Properties)in.readObject();
|
||||||
_anims = (HashMap<String, Animation>)in.readObject();
|
_anims = (HashMap<String, Animation>)in.readObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a new instance of this model.
|
||||||
|
*/
|
||||||
|
public Model createInstance ()
|
||||||
|
{
|
||||||
|
if (_prototype != null) {
|
||||||
|
return _prototype.createInstance();
|
||||||
|
}
|
||||||
|
if (_ccreator == null) {
|
||||||
|
// allow adding and removing properties at any time
|
||||||
|
_ccreator = new CloneCreator(this) {
|
||||||
|
public void addProperty (String name) {
|
||||||
|
props.put(name, Boolean.TRUE);
|
||||||
|
}
|
||||||
|
public void removeProperty (String name) {
|
||||||
|
props.remove(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_ccreator.addProperty("vertices");
|
||||||
|
_ccreator.addProperty("colors");
|
||||||
|
_ccreator.addProperty("normals");
|
||||||
|
_ccreator.addProperty("texcoords");
|
||||||
|
_ccreator.addProperty("vboinfo");
|
||||||
|
_ccreator.addProperty("indices");
|
||||||
|
_ccreator.addProperty("obbtree");
|
||||||
|
_ccreator.addProperty("displaylistid");
|
||||||
|
_ccreator.addProperty("bound");
|
||||||
|
}
|
||||||
|
return (Model)_ccreator.createCopy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public Spatial putClone (Spatial store, CloneCreator properties)
|
||||||
|
{
|
||||||
|
Model mstore;
|
||||||
|
if (store == null) {
|
||||||
|
mstore = new Model(getName(), _props);
|
||||||
|
} else {
|
||||||
|
mstore = (Model)store;
|
||||||
|
}
|
||||||
|
super.putClone(mstore, properties);
|
||||||
|
mstore._prototype = this;
|
||||||
|
if (_anims != null) {
|
||||||
|
mstore._anims = new HashMap<String, Animation>();
|
||||||
|
}
|
||||||
|
mstore._pnodes = properties.originalToCopy;
|
||||||
|
return mstore;
|
||||||
|
}
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
public void updateWorldData (float time)
|
public void updateWorldData (float time)
|
||||||
@@ -364,6 +441,19 @@ public class Model extends ModelNode
|
|||||||
// update children
|
// update children
|
||||||
super.updateWorldData(time);
|
super.updateWorldData(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the supplied animation.
|
||||||
|
*/
|
||||||
|
protected void startAnimation (String name, Animation anim)
|
||||||
|
{
|
||||||
|
_anim = anim;
|
||||||
|
_animName = name;
|
||||||
|
_fidx = 0;
|
||||||
|
_nidx = 1;
|
||||||
|
_fdir = +1;
|
||||||
|
_elapsed = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the model's state according to the current animation.
|
* Updates the model's state according to the current animation.
|
||||||
@@ -415,6 +505,18 @@ public class Model extends ModelNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A reference to the prototype, or <code>null</code> if this is a
|
||||||
|
* prototype. */
|
||||||
|
protected Model _prototype;
|
||||||
|
|
||||||
|
/** For prototype models, a customized clone creator used to generate
|
||||||
|
* instances. */
|
||||||
|
protected CloneCreator _ccreator;
|
||||||
|
|
||||||
|
/** For instances, maps prototype nodes to their corresponding instance
|
||||||
|
* nodes. */
|
||||||
|
protected HashMap _pnodes;
|
||||||
|
|
||||||
/** The model properties. */
|
/** The model properties. */
|
||||||
protected Properties _props;
|
protected Properties _props;
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,12 @@ import com.jme.bounding.BoundingBox;
|
|||||||
import com.jme.bounding.BoundingSphere;
|
import com.jme.bounding.BoundingSphere;
|
||||||
import com.jme.math.Quaternion;
|
import com.jme.math.Quaternion;
|
||||||
import com.jme.math.Vector3f;
|
import com.jme.math.Vector3f;
|
||||||
|
import com.jme.renderer.CloneCreator;
|
||||||
import com.jme.renderer.Renderer;
|
import com.jme.renderer.Renderer;
|
||||||
|
import com.jme.scene.SharedMesh;
|
||||||
|
import com.jme.scene.Spatial;
|
||||||
import com.jme.scene.TriMesh;
|
import com.jme.scene.TriMesh;
|
||||||
|
import com.jme.scene.VBOInfo;
|
||||||
import com.jme.scene.state.AlphaState;
|
import com.jme.scene.state.AlphaState;
|
||||||
import com.jme.scene.state.CullState;
|
import com.jme.scene.state.CullState;
|
||||||
import com.jme.scene.state.TextureState;
|
import com.jme.scene.state.TextureState;
|
||||||
@@ -155,6 +159,26 @@ public class ModelMesh extends TriMesh
|
|||||||
_textureBufferSize = (textures == null) ? 0 : textures.capacity();
|
_textureBufferSize = (textures == null) ? 0 : textures.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public Spatial putClone (Spatial store, CloneCreator properties)
|
||||||
|
{
|
||||||
|
ModelMesh mstore;
|
||||||
|
if (store == null) {
|
||||||
|
mstore = new ModelMesh(getName());
|
||||||
|
} else {
|
||||||
|
mstore = (ModelMesh)store;
|
||||||
|
}
|
||||||
|
super.putClone(mstore, properties);
|
||||||
|
if (properties.isSet("displaylistid")) {
|
||||||
|
mstore.batch.setDisplayListID(getDisplayListID());
|
||||||
|
}
|
||||||
|
if (properties.isSet("bound")) {
|
||||||
|
mstore.setModelBound(getModelBound());
|
||||||
|
}
|
||||||
|
mstore._texture = _texture;
|
||||||
|
return mstore;
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited from interface Externalizable
|
// documentation inherited from interface Externalizable
|
||||||
public void writeExternal (ObjectOutput out)
|
public void writeExternal (ObjectOutput out)
|
||||||
throws IOException
|
throws IOException
|
||||||
@@ -199,6 +223,20 @@ public class ModelMesh extends TriMesh
|
|||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface ModelSpatial
|
||||||
|
public void lockStaticMeshes (
|
||||||
|
Renderer renderer, boolean useVBOs, boolean useDisplayLists)
|
||||||
|
{
|
||||||
|
if (useVBOs && renderer.supportsVBO()) {
|
||||||
|
VBOInfo vboinfo = new VBOInfo(true);
|
||||||
|
vboinfo.setVBOIndexEnabled(true);
|
||||||
|
setVBOInfo(vboinfo);
|
||||||
|
|
||||||
|
} else if (useDisplayLists) {
|
||||||
|
lockMeshes(renderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited from interface ModelSpatial
|
// documentation inherited from interface ModelSpatial
|
||||||
public void resolveTextures (TextureProvider tprov)
|
public void resolveTextures (TextureProvider tprov)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import java.util.ArrayList;
|
|||||||
import com.jme.math.Matrix4f;
|
import com.jme.math.Matrix4f;
|
||||||
import com.jme.math.Quaternion;
|
import com.jme.math.Quaternion;
|
||||||
import com.jme.math.Vector3f;
|
import com.jme.math.Vector3f;
|
||||||
|
import com.jme.renderer.CloneCreator;
|
||||||
|
import com.jme.renderer.Renderer;
|
||||||
import com.jme.scene.Node;
|
import com.jme.scene.Node;
|
||||||
import com.jme.scene.Spatial;
|
import com.jme.scene.Spatial;
|
||||||
|
|
||||||
@@ -70,17 +72,6 @@ public class ModelNode extends Node
|
|||||||
return _modelTransform;
|
return _modelTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface ModelSpatial
|
|
||||||
public void setReferenceTransforms ()
|
|
||||||
{
|
|
||||||
updateWorldVectors();
|
|
||||||
for (Object child : getChildren()) {
|
|
||||||
if (child instanceof ModelSpatial) {
|
|
||||||
((ModelSpatial)child).setReferenceTransforms();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
public void updateWorldVectors ()
|
public void updateWorldVectors ()
|
||||||
{
|
{
|
||||||
@@ -96,6 +87,19 @@ public class ModelNode extends Node
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public Spatial putClone (Spatial store, CloneCreator properties)
|
||||||
|
{
|
||||||
|
ModelNode mstore;
|
||||||
|
if (store == null) {
|
||||||
|
mstore = new ModelNode(getName());
|
||||||
|
} else {
|
||||||
|
mstore = (ModelNode)store;
|
||||||
|
}
|
||||||
|
super.putClone(mstore, properties);
|
||||||
|
return mstore;
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited from interface Externalizable
|
// documentation inherited from interface Externalizable
|
||||||
public void writeExternal (ObjectOutput out)
|
public void writeExternal (ObjectOutput out)
|
||||||
throws IOException
|
throws IOException
|
||||||
@@ -121,6 +125,29 @@ public class ModelNode extends Node
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface ModelSpatial
|
||||||
|
public void setReferenceTransforms ()
|
||||||
|
{
|
||||||
|
updateWorldVectors();
|
||||||
|
for (Object child : getChildren()) {
|
||||||
|
if (child instanceof ModelSpatial) {
|
||||||
|
((ModelSpatial)child).setReferenceTransforms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface ModelSpatial
|
||||||
|
public void lockStaticMeshes (
|
||||||
|
Renderer renderer, boolean useVBOs, boolean useDisplayLists)
|
||||||
|
{
|
||||||
|
for (Object child : getChildren()) {
|
||||||
|
if (child instanceof ModelSpatial) {
|
||||||
|
((ModelSpatial)child).lockStaticMeshes(renderer, useVBOs,
|
||||||
|
useDisplayLists);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// documentation inherited from interface ModelSpatial
|
// documentation inherited from interface ModelSpatial
|
||||||
public void resolveTextures (TextureProvider tprov)
|
public void resolveTextures (TextureProvider tprov)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ import java.io.IOException;
|
|||||||
import java.nio.MappedByteBuffer;
|
import java.nio.MappedByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.jme.math.Matrix4f;
|
import com.jme.math.Matrix4f;
|
||||||
|
import com.jme.renderer.Renderer;
|
||||||
|
import com.jme.scene.Spatial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains method common to both {@link ModelNode}s and {@link ModelMesh}es.
|
* Contains method common to both {@link ModelNode}s and {@link ModelMesh}es.
|
||||||
@@ -39,6 +43,17 @@ public interface ModelSpatial
|
|||||||
*/
|
*/
|
||||||
public void setReferenceTransforms ();
|
public void setReferenceTransforms ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively compiles any static meshes to vertex buffer objects (VBOs)
|
||||||
|
* or display lists.
|
||||||
|
*
|
||||||
|
* @param useVBOs if true, use VBOs if the graphics card supports them
|
||||||
|
* @param useDisplayLists if true and not using VBOs, compile static
|
||||||
|
* objects to display lists
|
||||||
|
*/
|
||||||
|
public void lockStaticMeshes (
|
||||||
|
Renderer renderer, boolean useVBOs, boolean useDisplayLists);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively resolves texture references using the given provider.
|
* Recursively resolves texture references using the given provider.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -30,8 +30,14 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.jme.math.Matrix4f;
|
import com.jme.math.Matrix4f;
|
||||||
import com.jme.math.Vector3f;
|
import com.jme.math.Vector3f;
|
||||||
|
import com.jme.renderer.CloneCreator;
|
||||||
|
import com.jme.renderer.Renderer;
|
||||||
|
import com.jme.scene.Spatial;
|
||||||
|
import com.jme.scene.VBOInfo;
|
||||||
import com.jme.util.geom.BufferUtils;
|
import com.jme.util.geom.BufferUtils;
|
||||||
|
|
||||||
import com.threerings.jme.Log;
|
import com.threerings.jme.Log;
|
||||||
@@ -60,6 +66,24 @@ public class SkinMesh extends ModelMesh
|
|||||||
/** The inverses of the bones' mesh space reference transforms. */
|
/** The inverses of the bones' mesh space reference transforms. */
|
||||||
public transient Matrix4f[] invRefTransforms;
|
public transient Matrix4f[] invRefTransforms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebinds this weight group for a prototype instance.
|
||||||
|
*
|
||||||
|
* @param pnodes a mapping from prototype nodes to instance nodes
|
||||||
|
*/
|
||||||
|
public WeightGroup rebind (HashMap pnodes)
|
||||||
|
{
|
||||||
|
WeightGroup group = new WeightGroup();
|
||||||
|
group.indices = indices;
|
||||||
|
group.weights = weights;
|
||||||
|
group.invRefTransforms = invRefTransforms;
|
||||||
|
group.bones = new ModelNode[bones.length];
|
||||||
|
for (int ii = 0; ii < bones.length; ii++) {
|
||||||
|
group.bones[ii] = (ModelNode)pnodes.get(bones[ii]);
|
||||||
|
}
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = 1;
|
private static final long serialVersionUID = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +131,32 @@ public class SkinMesh extends ModelMesh
|
|||||||
setNormalBuffer(BufferUtils.clone(_onbuf = getNormalBuffer()));
|
setNormalBuffer(BufferUtils.clone(_onbuf = getNormalBuffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public Spatial putClone (Spatial store, CloneCreator properties)
|
||||||
|
{
|
||||||
|
SkinMesh mstore;
|
||||||
|
if (store == null) {
|
||||||
|
mstore = new SkinMesh(getName());
|
||||||
|
} else {
|
||||||
|
mstore = (SkinMesh)store;
|
||||||
|
}
|
||||||
|
properties.removeProperty("vertices");
|
||||||
|
properties.removeProperty("normals");
|
||||||
|
properties.removeProperty("displaylistid");
|
||||||
|
super.putClone(mstore, properties);
|
||||||
|
properties.addProperty("vertices");
|
||||||
|
properties.addProperty("normals");
|
||||||
|
properties.addProperty("displaylistid");
|
||||||
|
mstore._weightGroups = new WeightGroup[_weightGroups.length];
|
||||||
|
for (int ii = 0; ii < _weightGroups.length; ii++) {
|
||||||
|
mstore._weightGroups[ii] =
|
||||||
|
_weightGroups[ii].rebind(properties.originalToCopy);
|
||||||
|
}
|
||||||
|
mstore._ovbuf = _ovbuf;
|
||||||
|
mstore._onbuf = _onbuf;
|
||||||
|
return mstore;
|
||||||
|
}
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
public void writeExternal (ObjectOutput out)
|
public void writeExternal (ObjectOutput out)
|
||||||
throws IOException
|
throws IOException
|
||||||
@@ -138,6 +188,20 @@ public class SkinMesh extends ModelMesh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // documentation inherited
|
||||||
|
public void lockStaticMeshes (
|
||||||
|
Renderer renderer, boolean useVBOs, boolean useDisplayLists)
|
||||||
|
{
|
||||||
|
// we can use VBOs for color, texture, and indices
|
||||||
|
if (useVBOs && renderer.supportsVBO()) {
|
||||||
|
VBOInfo vboinfo = new VBOInfo(false);
|
||||||
|
vboinfo.setVBOColorEnabled(true);
|
||||||
|
vboinfo.setVBOTextureEnabled(true);
|
||||||
|
vboinfo.setVBOIndexEnabled(true);
|
||||||
|
setVBOInfo(vboinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override // documentation inherited
|
@Override // documentation inherited
|
||||||
public void updateWorldVectors ()
|
public void updateWorldVectors ()
|
||||||
{
|
{
|
||||||
@@ -197,9 +261,9 @@ public class SkinMesh extends ModelMesh
|
|||||||
xform = _transforms[kk];
|
xform = _transforms[kk];
|
||||||
weight = weights[ww++];
|
weight = weights[ww++];
|
||||||
_vertex.addLocal(
|
_vertex.addLocal(
|
||||||
xform.mult(_overtex, _tmp).mult(weight));
|
xform.mult(_overtex, _tmp).multLocal(weight));
|
||||||
_normal.addLocal(
|
_normal.addLocal(
|
||||||
xform.multAcross(_onormal, _tmp).mult(weight));
|
xform.multAcross(_onormal, _tmp).multLocal(weight));
|
||||||
}
|
}
|
||||||
BufferUtils.setInBuffer(_vertex, vbuf, idx);
|
BufferUtils.setInBuffer(_vertex, vbuf, idx);
|
||||||
BufferUtils.setInBuffer(_normal, nbuf, idx);
|
BufferUtils.setInBuffer(_normal, nbuf, idx);
|
||||||
|
|||||||
@@ -258,13 +258,20 @@ public class ModelDef
|
|||||||
/** A vertex influenced by a number of bones. */
|
/** A vertex influenced by a number of bones. */
|
||||||
public static class SkinVertex extends Vertex
|
public static class SkinVertex extends Vertex
|
||||||
{
|
{
|
||||||
/** The bones influencing the vertex. */
|
/** The bones influencing the vertex, mapped by name. */
|
||||||
public ArrayList<BoneWeight> boneWeights = new ArrayList<BoneWeight>();
|
public HashMap<String, BoneWeight> boneWeights =
|
||||||
|
new HashMap<String, BoneWeight>();
|
||||||
|
|
||||||
public void addBoneWeight (BoneWeight weight)
|
public void addBoneWeight (BoneWeight weight)
|
||||||
{
|
{
|
||||||
if (weight.weight > 0f) {
|
if (weight.weight == 0f) {
|
||||||
boneWeights.add(weight);
|
return;
|
||||||
|
}
|
||||||
|
BoneWeight bweight = boneWeights.get(weight.bone);
|
||||||
|
if (bweight != null) {
|
||||||
|
bweight.weight += weight.weight;
|
||||||
|
} else {
|
||||||
|
boneWeights.put(weight.bone, weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,10 +279,13 @@ public class ModelDef
|
|||||||
public HashSet<ModelNode> getBones (HashMap<String, Spatial> nodes)
|
public HashSet<ModelNode> getBones (HashMap<String, Spatial> nodes)
|
||||||
{
|
{
|
||||||
HashSet<ModelNode> bones = new HashSet<ModelNode>();
|
HashSet<ModelNode> bones = new HashSet<ModelNode>();
|
||||||
for (BoneWeight bweight : boneWeights) {
|
for (String bone : boneWeights.keySet()) {
|
||||||
Spatial node = nodes.get(bweight.bone);
|
Spatial node = nodes.get(bone);
|
||||||
if (node instanceof ModelNode) {
|
if (node instanceof ModelNode) {
|
||||||
bones.add((ModelNode)node);
|
bones.add((ModelNode)node);
|
||||||
|
} else {
|
||||||
|
Log.warning("Missing or invalid bone for bone weight " +
|
||||||
|
"[bone=" + bone + "].");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bones;
|
return bones;
|
||||||
@@ -284,13 +294,8 @@ public class ModelDef
|
|||||||
/** Returns the weight of the given bone. */
|
/** Returns the weight of the given bone. */
|
||||||
public float getWeight (ModelNode bone)
|
public float getWeight (ModelNode bone)
|
||||||
{
|
{
|
||||||
String name = bone.getName();
|
BoneWeight bweight = boneWeights.get(bone.getName());
|
||||||
for (BoneWeight bweight : boneWeights) {
|
return (bweight == null) ? 0f : bweight.weight;
|
||||||
if (bweight.bone.equals(name)) {
|
|
||||||
return bweight.weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -360,6 +360,7 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
_ctx.getGeometry().detachChild(_model);
|
_ctx.getGeometry().detachChild(_model);
|
||||||
}
|
}
|
||||||
_ctx.getGeometry().attachChild(_model = model);
|
_ctx.getGeometry().attachChild(_model = model);
|
||||||
|
_model.lockStaticMeshes(_ctx.getRenderer(), true, true);
|
||||||
|
|
||||||
// resolve the textures from the file's directory
|
// resolve the textures from the file's directory
|
||||||
final File dir = file.getParentFile();
|
final File dir = file.getParentFile();
|
||||||
|
|||||||
Reference in New Issue
Block a user