diff --git a/engine/src/core/com/jme3/animation/SkeletonControl.java b/engine/src/core/com/jme3/animation/SkeletonControl.java index f77bfe604..f193a8f2d 100644 --- a/engine/src/core/com/jme3/animation/SkeletonControl.java +++ b/engine/src/core/com/jme3/animation/SkeletonControl.java @@ -36,10 +36,17 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab * The skelrton of the model */ private Skeleton skeleton; + /** * List of targets which this controller effects. */ - Mesh[] targets; + private Mesh[] targets; + + /** + * Used to track when a mesh was updated. Meshes are only updated + * if they are visible in at least one camera. + */ + private boolean wasMeshUpdated = false; public SkeletonControl() { } @@ -50,21 +57,43 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab } @Override - protected void controlUpdate(float tpf) { - resetToBind(); // reset morph meshes to bind pose + protected void controlRender(RenderManager rm, ViewPort vp) { + if (!wasMeshUpdated){ + resetToBind(); // reset morph meshes to bind pose - Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices(); + Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices(); - // if hardware skinning is supported, the matrices and weight buffer - // will be sent by the SkinningShaderLogic object assigned to the shader - for (int i = 0; i < targets.length; i++) { - // only update targets with bone-vertex assignments - if (targets[i].getBuffer(Type.BoneIndex) != null) { - softwareSkinUpdate(targets[i], offsetMatrices); + // if hardware skinning is supported, the matrices and weight buffer + // will be sent by the SkinningShaderLogic object assigned to the shader + for (int i = 0; i < targets.length; i++) { + // only update targets with bone-vertex assignments + if (targets[i].getBuffer(Type.BoneIndex) != null) { + softwareSkinUpdate(targets[i], offsetMatrices); + } } + + wasMeshUpdated = true; } } + @Override + protected void controlUpdate(float tpf) { + wasMeshUpdated = false; + +// resetToBind(); // reset morph meshes to bind pose +// +// Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices(); +// +// // if hardware skinning is supported, the matrices and weight buffer +// // will be sent by the SkinningShaderLogic object assigned to the shader +// for (int i = 0; i < targets.length; i++) { +// // only update targets with bone-vertex assignments +// if (targets[i].getBuffer(Type.BoneIndex) != null) { +// softwareSkinUpdate(targets[i], offsetMatrices); +// } +// } + } + void resetToBind() { for (int i = 0; i < targets.length; i++) { Mesh mesh = targets[i]; @@ -92,6 +121,70 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab } } + public Control cloneForSpatial(Spatial spatial) { + Node clonedNode = (Node) spatial; + AnimControl ctrl = spatial.getControl(AnimControl.class); + SkeletonControl clone = new SkeletonControl(); + clone.setSpatial(clonedNode); + + clone.skeleton = ctrl.getSkeleton(); + Mesh[] meshes = new Mesh[targets.length]; + for (int i = 0; i < meshes.length; i++) { + meshes[i] = ((Geometry) clonedNode.getChild(i)).getMesh(); + } + for (int i = meshes.length; i < clonedNode.getQuantity(); i++) { + // go through attachment nodes, apply them to correct bone + Spatial child = clonedNode.getChild(i); + if (child instanceof Node) { + Node clonedAttachNode = (Node) child; + Bone originalBone = (Bone) clonedAttachNode.getUserData("AttachedBone"); + + if (originalBone != null) { + Bone clonedBone = clone.skeleton.getBone(originalBone.getName()); + + clonedAttachNode.setUserData("AttachedBone", clonedBone); + clonedBone.setAttachmentsNode(clonedAttachNode); + } + } + } + clone.targets = meshes; + return clone; + } + + /** + * + * @param boneName the name of the bone + * @return the node attached to this bone + */ + public Node getAttachmentsNode(String boneName) { + Bone b = skeleton.getBone(boneName); + if (b == null) { + throw new IllegalArgumentException("Given bone name does not exist " + + "in the skeleton."); + } + + Node n = b.getAttachmentsNode(); + Node model = (Node) spatial; + model.attachChild(n); + return n; + } + + public Skeleton getSkeleton() { + return skeleton; + } + + public void setSkeleton(Skeleton skeleton) { + this.skeleton = skeleton; + } + + public Mesh[] getTargets() { + return targets; + } + + public void setTargets(Mesh[] targets) { + this.targets = targets; + } + private void softwareSkinUpdate(Mesh mesh, Matrix4f[] offsetMatrices) { int maxWeightsPerVert = mesh.getMaxNumWeights(); if (maxWeightsPerVert <= 0) @@ -186,79 +279,6 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab // mesh.updateBound(); } - final void reset() { - resetToBind(); - } - - @Override - protected void controlRender(RenderManager rm, ViewPort vp) { - } - - public Control cloneForSpatial(Spatial spatial) { - Node clonedNode = (Node) spatial; - AnimControl ctrl = spatial.getControl(AnimControl.class); - SkeletonControl clone = new SkeletonControl(); - clone.setSpatial(clonedNode); - - clone.skeleton = ctrl.getSkeleton(); - Mesh[] meshes = new Mesh[targets.length]; - for (int i = 0; i < meshes.length; i++) { - meshes[i] = ((Geometry) clonedNode.getChild(i)).getMesh(); - } - for (int i = meshes.length; i < clonedNode.getQuantity(); i++) { - // go through attachment nodes, apply them to correct bone - Spatial child = clonedNode.getChild(i); - if (child instanceof Node) { - Node clonedAttachNode = (Node) child; - Bone originalBone = (Bone) clonedAttachNode.getUserData("AttachedBone"); - - if (originalBone != null) { - Bone clonedBone = clone.skeleton.getBone(originalBone.getName()); - - clonedAttachNode.setUserData("AttachedBone", clonedBone); - clonedBone.setAttachmentsNode(clonedAttachNode); - } - } - } - clone.targets = meshes; - return clone; - - } - - /** - * - * @param boneName the name of the bone - * @return the node attached to this bone - */ - public Node getAttachmentsNode(String boneName) { - Bone b = skeleton.getBone(boneName); - if (b == null) { - throw new IllegalArgumentException("Given bone name does not exist " - + "in the skeleton."); - } - - Node n = b.getAttachmentsNode(); - Node model = (Node) spatial; - model.attachChild(n); - return n; - } - - public Skeleton getSkeleton() { - return skeleton; - } - - public void setSkeleton(Skeleton skeleton) { - this.skeleton = skeleton; - } - - public Mesh[] getTargets() { - return targets; - } - - public void setTargets(Mesh[] targets) { - this.targets = targets; - } - @Override public void write(JmeExporter ex) throws IOException { super.write(ex); diff --git a/engine/src/core/com/jme3/renderer/RenderManager.java b/engine/src/core/com/jme3/renderer/RenderManager.java index 053e1f2ac..cb9518778 100644 --- a/engine/src/core/com/jme3/renderer/RenderManager.java +++ b/engine/src/core/com/jme3/renderer/RenderManager.java @@ -435,7 +435,6 @@ public class RenderManager { for (int i = 0; i < gl.size(); i++) { renderGeometry(gl.get(i)); } - } /**