Added support for model variants: subconfigurations with different
textures, etc., that share the same mesh and animations. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@49 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -23,6 +23,9 @@ m.mode_flipbook = Flipbook
|
|||||||
m.mode_morph = Morph
|
m.mode_morph = Morph
|
||||||
m.mode_skin = Skin
|
m.mode_skin = Skin
|
||||||
|
|
||||||
|
m.model_variant = Model Variant
|
||||||
|
m.variant_default = Default
|
||||||
|
|
||||||
m.load_title = Select Model to Load
|
m.load_title = Select Model to Load
|
||||||
m.load_filter = Model Files (*.properties, *.dat)
|
m.load_filter = Model Files (*.properties, *.dat)
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import com.jme.bounding.BoundingVolume;
|
import com.jme.bounding.BoundingVolume;
|
||||||
@@ -53,9 +54,12 @@ import com.jme.scene.Node;
|
|||||||
import com.jme.scene.Spatial;
|
import com.jme.scene.Spatial;
|
||||||
|
|
||||||
import com.samskivert.util.ObserverList;
|
import com.samskivert.util.ObserverList;
|
||||||
|
import com.samskivert.util.PropertiesUtil;
|
||||||
import com.samskivert.util.RandomUtil;
|
import com.samskivert.util.RandomUtil;
|
||||||
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.jme.Log;
|
import com.threerings.jme.Log;
|
||||||
|
import com.threerings.jme.util.SpatialVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base node for models.
|
* The base node for models.
|
||||||
@@ -400,6 +404,14 @@ public class Model extends ModelNode
|
|||||||
initInstance();
|
initInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the names of the model's variant configurations.
|
||||||
|
*/
|
||||||
|
public String[] getVariantNames ()
|
||||||
|
{
|
||||||
|
return StringUtil.parseStringArray(_props.getProperty("variants", ""));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an animation to the model's library. This should only be called by
|
* Adds an animation to the model's library. This should only be called by
|
||||||
* the model compiler.
|
* the model compiler.
|
||||||
@@ -716,6 +728,39 @@ public class Model extends ModelNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new prototype using the given variant configuration.
|
||||||
|
* Use {@link #createInstance} on the returned prototype to create
|
||||||
|
* additional instances of the variant.
|
||||||
|
*/
|
||||||
|
public Model createPrototype (String variant)
|
||||||
|
{
|
||||||
|
if (_prototype != null) {
|
||||||
|
return _prototype.createPrototype(variant);
|
||||||
|
}
|
||||||
|
// create an instance and rebind all animations
|
||||||
|
final Model prototype = createInstance();
|
||||||
|
for (Map.Entry<String, Animation> entry : _anims.entrySet()) {
|
||||||
|
prototype._anims.put(entry.getKey(),
|
||||||
|
entry.getValue().rebind(prototype._pnodes));
|
||||||
|
}
|
||||||
|
prototype._prototype = null;
|
||||||
|
prototype._pnodes = null;
|
||||||
|
|
||||||
|
// reconfigure meshes with new variant type
|
||||||
|
if (variant != null) {
|
||||||
|
prototype._props = PropertiesUtil.getFilteredProperties(
|
||||||
|
_props, variant);
|
||||||
|
new SpatialVisitor<ModelMesh>(ModelMesh.class) {
|
||||||
|
public void visit (ModelMesh mesh) {
|
||||||
|
mesh.reconfigure(PropertiesUtil.getFilteredProperties(
|
||||||
|
prototype._props, mesh.getParent().getName()));
|
||||||
|
}
|
||||||
|
}.traverse(prototype);
|
||||||
|
}
|
||||||
|
return prototype;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a new instance of this model.
|
* Creates and returns a new instance of this model.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.jme.scene.state.ZBufferState;
|
|||||||
import com.jme.system.DisplaySystem;
|
import com.jme.system.DisplaySystem;
|
||||||
import com.jme.util.geom.BufferUtils;
|
import com.jme.util.geom.BufferUtils;
|
||||||
|
|
||||||
|
import com.samskivert.util.PropertiesUtil;
|
||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.jme.Log;
|
import com.threerings.jme.Log;
|
||||||
@@ -86,6 +87,16 @@ public class ModelMesh extends TriMesh
|
|||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconfigures this model with a new set of (sub-)properties. Textures
|
||||||
|
* must be (re-)resolved after calling this method.
|
||||||
|
*/
|
||||||
|
public void reconfigure (Properties props)
|
||||||
|
{
|
||||||
|
configure(_solid, _textureKey, _transparent, props);
|
||||||
|
setRenderStates();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures this mesh based on the given parameters and (sub-)properties.
|
* Configures this mesh based on the given parameters and (sub-)properties.
|
||||||
*
|
*
|
||||||
@@ -97,23 +108,23 @@ public class ModelMesh extends TriMesh
|
|||||||
public void configure (
|
public void configure (
|
||||||
boolean solid, String texture, boolean transparent, Properties props)
|
boolean solid, String texture, boolean transparent, Properties props)
|
||||||
{
|
{
|
||||||
|
_textureKey = texture;
|
||||||
_textures = (texture == null) ? null : StringUtil.parseStringArray(
|
_textures = (texture == null) ? null : StringUtil.parseStringArray(
|
||||||
props.getProperty(texture, texture));
|
props.getProperty(texture, texture));
|
||||||
_sphereMapped = Boolean.parseBoolean(
|
Properties tprops = PropertiesUtil.getFilteredProperties(
|
||||||
getSubProperty(props, texture, "sphere_map"));
|
props, texture);
|
||||||
_filterMode = "nearest".equals(
|
_sphereMapped = Boolean.parseBoolean(tprops.getProperty("sphere_map"));
|
||||||
getSubProperty(props, texture, "filter")) ?
|
_filterMode = "nearest".equals(tprops.getProperty("filter")) ?
|
||||||
Texture.FM_NEAREST : Texture.FM_LINEAR;
|
Texture.FM_NEAREST : Texture.FM_LINEAR;
|
||||||
_mipMapMode = getMipMapMode(
|
_mipMapMode = getMipMapMode(tprops.getProperty("mipmap"));
|
||||||
getSubProperty(props, texture, "mipmap"));
|
_emissiveMap = tprops.getProperty("emissive");
|
||||||
_emissiveMap = getSubProperty(props, texture, "emissive");
|
|
||||||
_solid = solid;
|
_solid = solid;
|
||||||
_transparent = transparent;
|
_transparent = transparent;
|
||||||
String threshold = getSubProperty(props, texture, "alpha_threshold");
|
String threshold = tprops.getProperty("alpha_threshold");
|
||||||
_alphaThreshold = (threshold == null) ?
|
_alphaThreshold = (threshold == null) ?
|
||||||
DEFAULT_ALPHA_THRESHOLD : Float.parseFloat(threshold);
|
DEFAULT_ALPHA_THRESHOLD : Float.parseFloat(threshold);
|
||||||
_translucent = _transparent && Boolean.parseBoolean(
|
_translucent = _transparent &&
|
||||||
getSubProperty(props, texture, "translucent"));
|
Boolean.parseBoolean(tprops.getProperty("translucent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,26 +155,7 @@ public class ModelMesh extends TriMesh
|
|||||||
storeOriginalBuffers();
|
storeOriginalBuffers();
|
||||||
|
|
||||||
// initialize the model if we're displaying
|
// initialize the model if we're displaying
|
||||||
if (DisplaySystem.getDisplaySystem() == null) {
|
setRenderStates();
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_backCull == null) {
|
|
||||||
initSharedStates();
|
|
||||||
}
|
|
||||||
if (_solid) {
|
|
||||||
setRenderState(_backCull);
|
|
||||||
}
|
|
||||||
if (_transparent) {
|
|
||||||
setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
|
|
||||||
if (_translucent) {
|
|
||||||
setRenderState(_blendAlpha);
|
|
||||||
setRenderState(_overlayZBuffer);
|
|
||||||
} else if (_alphaThreshold == DEFAULT_ALPHA_THRESHOLD) {
|
|
||||||
setRenderState(_defaultTestAlpha);
|
|
||||||
} else {
|
|
||||||
setRenderState(createTestAlpha(_alphaThreshold));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -308,6 +300,7 @@ public class ModelMesh extends TriMesh
|
|||||||
mbatch.setModelBound(properties.isSet("bound") ?
|
mbatch.setModelBound(properties.isSet("bound") ?
|
||||||
batch.getModelBound() : batch.getModelBound().clone(null));
|
batch.getModelBound() : batch.getModelBound().clone(null));
|
||||||
}
|
}
|
||||||
|
mstore._textureKey = _textureKey;
|
||||||
if (_textures != null && _textures.length > 1) {
|
if (_textures != null && _textures.length > 1) {
|
||||||
int tidx = properties.random % _textures.length;
|
int tidx = properties.random % _textures.length;
|
||||||
mstore._textures = new String[] { _textures[tidx] };
|
mstore._textures = new String[] { _textures[tidx] };
|
||||||
@@ -352,6 +345,7 @@ public class ModelMesh extends TriMesh
|
|||||||
out.writeInt(_colorBufferSize);
|
out.writeInt(_colorBufferSize);
|
||||||
out.writeInt(_textureBufferSize);
|
out.writeInt(_textureBufferSize);
|
||||||
out.writeInt(_indexBufferSize);
|
out.writeInt(_indexBufferSize);
|
||||||
|
out.writeObject(_textureKey);
|
||||||
out.writeObject(_textures);
|
out.writeObject(_textures);
|
||||||
out.writeBoolean(_sphereMapped);
|
out.writeBoolean(_sphereMapped);
|
||||||
out.writeInt(_filterMode);
|
out.writeInt(_filterMode);
|
||||||
@@ -377,6 +371,7 @@ public class ModelMesh extends TriMesh
|
|||||||
_colorBufferSize = in.readInt();
|
_colorBufferSize = in.readInt();
|
||||||
_textureBufferSize = in.readInt();
|
_textureBufferSize = in.readInt();
|
||||||
_indexBufferSize = in.readInt();
|
_indexBufferSize = in.readInt();
|
||||||
|
_textureKey = (String)in.readObject();
|
||||||
_textures = (String[])in.readObject();
|
_textures = (String[])in.readObject();
|
||||||
_sphereMapped = in.readBoolean();
|
_sphereMapped = in.readBoolean();
|
||||||
_filterMode = in.readInt();
|
_filterMode = in.readInt();
|
||||||
@@ -445,6 +440,8 @@ public class ModelMesh extends TriMesh
|
|||||||
}
|
}
|
||||||
if (_tstates[0] != null) {
|
if (_tstates[0] != null) {
|
||||||
setRenderState(_tstates[0]);
|
setRenderState(_tstates[0]);
|
||||||
|
} else {
|
||||||
|
clearRenderState(RenderState.RS_TEXTURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,6 +614,34 @@ public class ModelMesh extends TriMesh
|
|||||||
FloatBuffer.wrap(_vbuf = new float[vbuf.capacity()]).put(vbuf);
|
FloatBuffer.wrap(_vbuf = new float[vbuf.capacity()]).put(vbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the model's render states (excluding the texture state, which is
|
||||||
|
* set by {@link #resolveTextures}) according to its configuration.
|
||||||
|
*/
|
||||||
|
protected void setRenderStates ()
|
||||||
|
{
|
||||||
|
if (DisplaySystem.getDisplaySystem() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_backCull == null) {
|
||||||
|
initSharedStates();
|
||||||
|
}
|
||||||
|
if (_solid) {
|
||||||
|
setRenderState(_backCull);
|
||||||
|
}
|
||||||
|
if (_transparent) {
|
||||||
|
setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
|
||||||
|
if (_translucent) {
|
||||||
|
setRenderState(_blendAlpha);
|
||||||
|
setRenderState(_overlayZBuffer);
|
||||||
|
} else if (_alphaThreshold == DEFAULT_ALPHA_THRESHOLD) {
|
||||||
|
setRenderState(_defaultTestAlpha);
|
||||||
|
} else {
|
||||||
|
setRenderState(createTestAlpha(_alphaThreshold));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locks the transform and bounds of this mesh on the assumption that its
|
* Locks the transform and bounds of this mesh on the assumption that its
|
||||||
* position will not change.
|
* position will not change.
|
||||||
@@ -627,17 +652,6 @@ public class ModelMesh extends TriMesh
|
|||||||
_transformLocked = true;
|
_transformLocked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a sub-property from the given set, falling back on the main
|
|
||||||
* property if the sub-property is not specified.
|
|
||||||
*/
|
|
||||||
protected static String getSubProperty (
|
|
||||||
Properties props, String prefix, String property)
|
|
||||||
{
|
|
||||||
return props.getProperty(prefix + "." + property,
|
|
||||||
props.getProperty(property));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mip-map mode corresponding to the given string
|
* Returns the mip-map mode corresponding to the given string
|
||||||
* (defaulting to {@link Texture#MM_LINEAR_LINEAR}).
|
* (defaulting to {@link Texture#MM_LINEAR_LINEAR}).
|
||||||
@@ -876,6 +890,10 @@ public class ModelMesh extends TriMesh
|
|||||||
/** The type of bounding volume that this mesh should use. */
|
/** The type of bounding volume that this mesh should use. */
|
||||||
protected int _boundingType;
|
protected int _boundingType;
|
||||||
|
|
||||||
|
/** The name of the texture specified in the model file, which acts as a
|
||||||
|
* property key and a default value. */
|
||||||
|
protected String _textureKey;
|
||||||
|
|
||||||
/** The name of this model's textures, or <code>null</code> for none. */
|
/** The name of this model's textures, or <code>null</code> for none. */
|
||||||
protected String[] _textures;
|
protected String[] _textures;
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ public class ModelDef
|
|||||||
public Spatial getSpatial (Properties props)
|
public Spatial getSpatial (Properties props)
|
||||||
{
|
{
|
||||||
if (_spatial == null) {
|
if (_spatial == null) {
|
||||||
_spatial = createSpatial(new NodeProperties(props, name));
|
_spatial = createSpatial(
|
||||||
|
PropertiesUtil.getFilteredProperties(props, name));
|
||||||
setTransform();
|
setTransform();
|
||||||
}
|
}
|
||||||
return _spatial;
|
return _spatial;
|
||||||
@@ -541,34 +542,4 @@ public class ModelDef
|
|||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A wrapper for the model properties providing access to the properties
|
|
||||||
* of a node within the model. */
|
|
||||||
protected static class NodeProperties extends Properties
|
|
||||||
{
|
|
||||||
public NodeProperties (Properties mprops, String name)
|
|
||||||
{
|
|
||||||
_mprops = mprops;
|
|
||||||
_prefix = name + ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override // documentation inherited
|
|
||||||
public String getProperty (String key)
|
|
||||||
{
|
|
||||||
return getProperty(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override // documentation inherited
|
|
||||||
public String getProperty (String key, String defaultValue)
|
|
||||||
{
|
|
||||||
return _mprops.getProperty(_prefix + key,
|
|
||||||
_mprops.getProperty(key, defaultValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The properties of the model. */
|
|
||||||
protected Properties _mprops;
|
|
||||||
|
|
||||||
/** The node prefix. */
|
|
||||||
protected String _prefix;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ import com.jmex.effects.particles.ParticleGeometry;
|
|||||||
import com.samskivert.swing.GroupLayout;
|
import com.samskivert.swing.GroupLayout;
|
||||||
import com.samskivert.swing.Spacer;
|
import com.samskivert.swing.Spacer;
|
||||||
import com.samskivert.util.Config;
|
import com.samskivert.util.Config;
|
||||||
|
import com.samskivert.util.ObjectUtil;
|
||||||
import com.samskivert.util.StringUtil;
|
import com.samskivert.util.StringUtil;
|
||||||
|
|
||||||
import com.threerings.resource.ResourceManager;
|
import com.threerings.resource.ResourceManager;
|
||||||
@@ -230,6 +231,9 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
view.add(_normals);
|
view.add(_normals);
|
||||||
view.addSeparator();
|
view.addSeparator();
|
||||||
|
|
||||||
|
_vmenu = new JMenu(_msg.get("m.model_variant"));
|
||||||
|
view.add(_vmenu);
|
||||||
|
|
||||||
JMenu amode = new JMenu(_msg.get("m.animation_mode"));
|
JMenu amode = new JMenu(_msg.get("m.animation_mode"));
|
||||||
final JRadioButtonMenuItem flipbook =
|
final JRadioButtonMenuItem flipbook =
|
||||||
new JRadioButtonMenuItem(_msg.get("m.mode_flipbook")),
|
new JRadioButtonMenuItem(_msg.get("m.mode_flipbook")),
|
||||||
@@ -252,6 +256,7 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mgroup.add(flipbook);
|
mgroup.add(flipbook);
|
||||||
mgroup.add(morph);
|
mgroup.add(morph);
|
||||||
mgroup.add(skin);
|
mgroup.add(skin);
|
||||||
@@ -591,11 +596,82 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
if (_model != null) {
|
if (_model != null) {
|
||||||
_ctx.getGeometry().detachChild(_model);
|
_ctx.getGeometry().detachChild(_model);
|
||||||
}
|
}
|
||||||
_ctx.getGeometry().attachChild(_model = model);
|
_ctx.getGeometry().attachChild(_model = _omodel = model);
|
||||||
_model.setAnimationMode(_animMode);
|
_model.setAnimationMode(_animMode);
|
||||||
_model.lockStaticMeshes(_ctx.getRenderer(), true, true);
|
_model.lockStaticMeshes(_ctx.getRenderer(), true, true);
|
||||||
|
|
||||||
// resolve the textures from the file's directory
|
// load the model's textures
|
||||||
|
resolveModelTextures(file);
|
||||||
|
|
||||||
|
// recenter the camera
|
||||||
|
_model.updateGeometricState(0f, true);
|
||||||
|
((OrbitCameraHandler)_camhand).recenter();
|
||||||
|
|
||||||
|
// configure the variant menu
|
||||||
|
_variant = null;
|
||||||
|
_vmenu.removeAll();
|
||||||
|
ButtonGroup vgroup = new ButtonGroup() {
|
||||||
|
public void setSelected (ButtonModel model, boolean b) {
|
||||||
|
super.setSelected(model, b);
|
||||||
|
String variant = model.getActionCommand();
|
||||||
|
if (b && !ObjectUtil.equals(variant, _variant)) {
|
||||||
|
setVariant(model.getActionCommand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
JRadioButtonMenuItem def = new JRadioButtonMenuItem(
|
||||||
|
_msg.get("m.variant_default"));
|
||||||
|
def.setActionCommand(null);
|
||||||
|
vgroup.add(def);
|
||||||
|
_vmenu.add(def);
|
||||||
|
for (String variant : _model.getVariantNames()) {
|
||||||
|
JRadioButtonMenuItem vitem = new JRadioButtonMenuItem(variant);
|
||||||
|
vitem.setActionCommand(variant);
|
||||||
|
vgroup.add(vitem);
|
||||||
|
_vmenu.add(vitem);
|
||||||
|
}
|
||||||
|
vgroup.setSelected(def.getModel(), true);
|
||||||
|
|
||||||
|
// configure the animation panel
|
||||||
|
String[] anims = _model.getAnimationNames();
|
||||||
|
if (anims.length == 0) {
|
||||||
|
_animctrls.setVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_model.addAnimationObserver(_animobs);
|
||||||
|
_animctrls.setVisible(true);
|
||||||
|
DefaultComboBoxModel abmodel = new DefaultComboBoxModel(anims);
|
||||||
|
_animbox.setModel(abmodel);
|
||||||
|
updateAnimationSpeed();
|
||||||
|
|
||||||
|
// if there are any sequences, add those as well
|
||||||
|
String[] seqs = StringUtil.parseStringArray(
|
||||||
|
_model.getProperties().getProperty("sequences", ""));
|
||||||
|
for (String seq : seqs) {
|
||||||
|
abmodel.addElement(seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switches to the named variant.
|
||||||
|
*/
|
||||||
|
protected void setVariant (String variant)
|
||||||
|
{
|
||||||
|
_model.stopAnimation();
|
||||||
|
_ctx.getGeometry().detachChild(_model);
|
||||||
|
_ctx.getGeometry().attachChild(
|
||||||
|
_model = _omodel.createPrototype(variant));
|
||||||
|
_model.addAnimationObserver(_animobs);
|
||||||
|
updateAnimationSpeed();
|
||||||
|
resolveModelTextures(_loaded);
|
||||||
|
_variant = variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the textures from the file's directory.
|
||||||
|
*/
|
||||||
|
protected void resolveModelTextures (File file)
|
||||||
|
{
|
||||||
final File dir = file.getParentFile();
|
final File dir = file.getParentFile();
|
||||||
_model.resolveTextures(new TextureProvider() {
|
_model.resolveTextures(new TextureProvider() {
|
||||||
public TextureState getTexture (String name) {
|
public TextureState getTexture (String name) {
|
||||||
@@ -625,29 +701,6 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
new HashMap<String, TextureState>();
|
new HashMap<String, TextureState>();
|
||||||
});
|
});
|
||||||
_model.updateRenderState();
|
_model.updateRenderState();
|
||||||
|
|
||||||
// recenter the camera
|
|
||||||
_model.updateGeometricState(0f, true);
|
|
||||||
((OrbitCameraHandler)_camhand).recenter();
|
|
||||||
|
|
||||||
// configure the animation panel
|
|
||||||
String[] anims = _model.getAnimationNames();
|
|
||||||
if (anims.length == 0) {
|
|
||||||
_animctrls.setVisible(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_model.addAnimationObserver(_animobs);
|
|
||||||
_animctrls.setVisible(true);
|
|
||||||
DefaultComboBoxModel abmodel = new DefaultComboBoxModel(anims);
|
|
||||||
_animbox.setModel(abmodel);
|
|
||||||
updateAnimationSpeed();
|
|
||||||
|
|
||||||
// if there are any sequences, add those as well
|
|
||||||
String[] seqs = StringUtil.parseStringArray(
|
|
||||||
_model.getProperties().getProperty("sequences", ""));
|
|
||||||
for (String seq : seqs) {
|
|
||||||
abmodel.addElement(seq);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -731,6 +784,9 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
/** The viewer frame. */
|
/** The viewer frame. */
|
||||||
protected JFrame _frame;
|
protected JFrame _frame;
|
||||||
|
|
||||||
|
/** The variant menu. */
|
||||||
|
protected JMenu _vmenu;
|
||||||
|
|
||||||
/** Debug view switches. */
|
/** Debug view switches. */
|
||||||
protected JCheckBoxMenuItem _pivots, _bounds, _normals;
|
protected JCheckBoxMenuItem _pivots, _bounds, _normals;
|
||||||
|
|
||||||
@@ -758,6 +814,9 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
/** The desired animation mode. */
|
/** The desired animation mode. */
|
||||||
protected Model.AnimationMode _animMode;
|
protected Model.AnimationMode _animMode;
|
||||||
|
|
||||||
|
/** The desired variant. */
|
||||||
|
protected String _variant;
|
||||||
|
|
||||||
/** The light rotation dialog. */
|
/** The light rotation dialog. */
|
||||||
protected RotateLightDialog _rldialog;
|
protected RotateLightDialog _rldialog;
|
||||||
|
|
||||||
@@ -770,6 +829,9 @@ public class ModelViewer extends JmeCanvasApp
|
|||||||
/** The currently loaded model. */
|
/** The currently loaded model. */
|
||||||
protected Model _model;
|
protected Model _model;
|
||||||
|
|
||||||
|
/** The original model (before switching to a variant). */
|
||||||
|
protected Model _omodel;
|
||||||
|
|
||||||
/** Reused to draw pivot axes. */
|
/** Reused to draw pivot axes. */
|
||||||
protected Line _axes;
|
protected Line _axes;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user