diff --git a/jme3-core/src/main/java/com/jme3/anim/SingleLayerInfluenceMask.java b/jme3-core/src/main/java/com/jme3/anim/SingleLayerInfluenceMask.java index 935cb99abd..0b2bd0f723 100644 --- a/jme3-core/src/main/java/com/jme3/anim/SingleLayerInfluenceMask.java +++ b/jme3-core/src/main/java/com/jme3/anim/SingleLayerInfluenceMask.java @@ -31,8 +31,14 @@ */ package com.jme3.anim; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; import com.jme3.scene.Spatial; +import java.io.IOException; + /** * Mask that excludes joints from participating in the layer * if a higher layer is using those joints in an animation. @@ -41,88 +47,83 @@ */ public class SingleLayerInfluenceMask extends ArmatureMask { - private final String layer; - private final AnimComposer anim; - private final SkinningControl skin; - private boolean checkUpperLayers = true; - + private String layer; + private AnimComposer anim; + /** - * @param layer The layer this mask is targeted for. It is important - * that this match the name of the layer this mask is (or will be) part of. You - * can use {@link makeLayer} to ensure this. - * @param spatial Spatial containing necessary controls ({@link AnimComposer} and {@link SkinningControl}) + * Serialization only. */ - public SingleLayerInfluenceMask(String layer, Spatial spatial) { - super(); - this.layer = layer; - anim = spatial.getControl(AnimComposer.class); - skin = spatial.getControl(SkinningControl.class); - } + public SingleLayerInfluenceMask() {} + /** * @param layer The layer this mask is targeted for. It is important * that this match the name of the layer this mask is (or will be) part of. You - * can use {@link makeLayer} to ensure this. - * @param anim anim composer this mask is assigned to - * @param skin skinning control complimenting the anim composer. + * can use {@link #makeLayer(AnimComposer)} to ensure this. */ - public SingleLayerInfluenceMask(String layer, AnimComposer anim, SkinningControl skin) { + public SingleLayerInfluenceMask(String layer) { super(); this.layer = layer; - this.anim = anim; - this.skin = skin; } /** * Makes a layer from this mask. + * + * @param anim AnimComposer to use + * @return this instance */ - public void makeLayer() { - anim.makeLayer(layer, this); + public SingleLayerInfluenceMask makeLayer(AnimComposer anim) { + this.anim = anim; + if (this.anim != null) { + anim.makeLayer(layer, this); + } + return this; } - + /** - * Adds all joints to this mask. - * @return this.instance + * Makes a layer from this mask. + * + * @return this instance */ - public SingleLayerInfluenceMask addAll() { - for (Joint j : skin.getArmature().getJointList()) { - super.addBones(skin.getArmature(), j.getName()); - } + public SingleLayerInfluenceMask makeLayer() { + anim.makeLayer(layer, this); return this; } /** - * Adds the given joint and all its children to this mask. - * @param joint + * Adds all joints to this mask. + * + * @param armature * @return this instance */ - public SingleLayerInfluenceMask addFromJoint(String joint) { - super.addFromJoint(skin.getArmature(), joint); + public SingleLayerInfluenceMask addAll(Armature armature) { + for (Joint j : armature.getJointList()) { + super.addBones(armature, j.getName()); + } return this; } /** * Adds the given joints to this mask. + * * @param joints * @return this instance */ - public SingleLayerInfluenceMask addJoints(String... joints) { - super.addBones(skin.getArmature(), joints); + public SingleLayerInfluenceMask addJoints(Armature armature, String... joints) { + super.addBones(armature, joints); return this; } - + /** - * Makes this mask check if each joint is being used by a higher layer - * before it uses them. - *

Not checking is more efficient, but checking can avoid some - * interpolation issues between layers. Default=true - * @param check - * @return this instance + * Sets the AnimComposer used by this mask to determine joint use. + *

If null, joint use check will be skipped and any higher that may + * have been using the joint may be overriden.

+ * + * @param anim */ - public SingleLayerInfluenceMask setCheckUpperLayers(boolean check) { - checkUpperLayers = check; - return this; + public void setAnimComposer(AnimComposer anim) { + this.anim = anim; } - + /** * Get the layer this mask is targeted for. *

It is extremely important that this value match the actual layer @@ -133,7 +134,7 @@ public SingleLayerInfluenceMask setCheckUpperLayers(boolean check) { public String getTargetLayer() { return layer; } - + /** * Get the {@link AnimComposer} this mask is for. * @return anim composer @@ -142,27 +143,11 @@ public AnimComposer getAnimComposer() { return anim; } - /** - * Get the {@link SkinningControl} this mask is for. - * @return skinning control - */ - public SkinningControl getSkinningControl() { - return skin; - } - - /** - * Returns true if this mask is checking upper layers for joint use. - * @return - */ - public boolean isCheckUpperLayers() { - return checkUpperLayers; - } - @Override public boolean contains(Object target) { - return simpleContains(target) && (!checkUpperLayers || !isAffectedByUpperLayers(target)); + return simpleContains(target) && (anim == null || !isAffectedByUpperLayers(target)); } - + private boolean simpleContains(Object target) { return super.contains(target); } @@ -192,26 +177,30 @@ else if (lyr.getMask().contains(target)) { } return false; } - - /** - * Creates an {@code SingleLayerInfluenceMask} for all joints. - * @param layer layer the returned mask is, or will be, be assigned to - * @param spatial spatial containing anim composer and skinning control - * @return new mask - */ - public static SingleLayerInfluenceMask all(String layer, Spatial spatial) { - return new SingleLayerInfluenceMask(layer, spatial).addAll(); + + @Override + public void write(JmeExporter ex) throws IOException { + super.write(ex); + OutputCapsule out = ex.getCapsule(this); + out.write(layer, "layer", null); + } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + InputCapsule in = im.getCapsule(this); + layer = in.readString("layer", null); } /** * Creates an {@code SingleLayerInfluenceMask} for all joints. * @param layer layer the returned mask is, or will be, assigned to * @param anim anim composer - * @param skin skinning control + * @param armature armature * @return new mask */ - public static SingleLayerInfluenceMask all(String layer, AnimComposer anim, SkinningControl skin) { - return new SingleLayerInfluenceMask(layer, anim, skin).addAll(); + public static SingleLayerInfluenceMask all(String layer, AnimComposer anim, Armature armature) { + return new SingleLayerInfluenceMask(layer).makeLayer(anim).addAll(armature); } } diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestSingleLayerInfluenceMask.java b/jme3-examples/src/main/java/jme3test/model/anim/TestSingleLayerInfluenceMask.java index 6ab0902f52..04698952e7 100644 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestSingleLayerInfluenceMask.java +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestSingleLayerInfluenceMask.java @@ -118,11 +118,9 @@ private void setupModel() { skin = model.getControl(SkinningControl.class); if (useSLIMask) { - SingleLayerInfluenceMask walkLayer = new SingleLayerInfluenceMask("idleLayer", anim, skin); - walkLayer.addAll(); + SingleLayerInfluenceMask walkLayer = SingleLayerInfluenceMask.all("idleLayer", anim, skin.getArmature()); walkLayer.makeLayer(); - SingleLayerInfluenceMask danceLayer = new SingleLayerInfluenceMask("danceLayer", anim, skin); - danceLayer.addAll(); + SingleLayerInfluenceMask danceLayer = SingleLayerInfluenceMask.all("danceLayer", anim, skin.getArmature()); danceLayer.makeLayer(); } else { anim.makeLayer("idleLayer", ArmatureMask.createMask(skin.getArmature(), "Root"));