|
@@ -43,13 +43,15 @@ import com.jme3.scene.VertexBuffer.Type;
|
|
import com.jme3.scene.control.AbstractControl;
|
|
import com.jme3.scene.control.AbstractControl;
|
|
import com.jme3.scene.control.Control;
|
|
import com.jme3.scene.control.Control;
|
|
import com.jme3.shader.VarType;
|
|
import com.jme3.shader.VarType;
|
|
|
|
+import com.jme3.util.SafeArrayList;
|
|
import com.jme3.util.TempVars;
|
|
import com.jme3.util.TempVars;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.nio.Buffer;
|
|
import java.nio.Buffer;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.FloatBuffer;
|
|
-import java.util.ArrayList;
|
|
|
|
|
|
+import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.HashSet;
|
|
|
|
+import java.util.Set;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
@@ -69,7 +71,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
/**
|
|
/**
|
|
* List of targets which this controller effects.
|
|
* List of targets which this controller effects.
|
|
*/
|
|
*/
|
|
- private Mesh[] targets;
|
|
|
|
|
|
+ private SafeArrayList<Mesh> targets = new SafeArrayList<Mesh>(Mesh.class);
|
|
/**
|
|
/**
|
|
* Used to track when a mesh was updated. Meshes are only updated if they
|
|
* Used to track when a mesh was updated. Meshes are only updated if they
|
|
* are visible in at least one camera.
|
|
* are visible in at least one camera.
|
|
@@ -105,7 +107,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
/**
|
|
/**
|
|
* Material references used for hardware skinning
|
|
* Material references used for hardware skinning
|
|
*/
|
|
*/
|
|
- private Material[] materials;
|
|
|
|
|
|
+ private Set<Material> materials = new HashSet<Material>();
|
|
|
|
|
|
/**
|
|
/**
|
|
* Serialization only. Do not use.
|
|
* Serialization only. Do not use.
|
|
@@ -211,15 +213,15 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
@Deprecated
|
|
@Deprecated
|
|
SkeletonControl(Mesh[] targets, Skeleton skeleton) {
|
|
SkeletonControl(Mesh[] targets, Skeleton skeleton) {
|
|
this.skeleton = skeleton;
|
|
this.skeleton = skeleton;
|
|
- this.targets = targets;
|
|
|
|
|
|
+ this.targets = new SafeArrayList<Mesh>(Mesh.class, Arrays.asList(targets));
|
|
}
|
|
}
|
|
|
|
|
|
private boolean isMeshAnimated(Mesh mesh) {
|
|
private boolean isMeshAnimated(Mesh mesh) {
|
|
return mesh.getBuffer(Type.BindPosePosition) != null;
|
|
return mesh.getBuffer(Type.BindPosePosition) != null;
|
|
}
|
|
}
|
|
|
|
|
|
- private void findTargets(Node node, ArrayList<Mesh> targets, HashSet<Material> materials) {
|
|
|
|
- Mesh sharedMesh = null;
|
|
|
|
|
|
+ private void findTargets(Node node) {
|
|
|
|
+ Mesh sharedMesh = null;
|
|
|
|
|
|
for (Spatial child : node.getChildren()) {
|
|
for (Spatial child : node.getChildren()) {
|
|
if (child instanceof Geometry) {
|
|
if (child instanceof Geometry) {
|
|
@@ -248,7 +250,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (child instanceof Node) {
|
|
} else if (child instanceof Node) {
|
|
- findTargets((Node) child, targets, materials);
|
|
|
|
|
|
+ findTargets((Node) child);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -261,17 +263,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
@Override
|
|
@Override
|
|
public void setSpatial(Spatial spatial) {
|
|
public void setSpatial(Spatial spatial) {
|
|
super.setSpatial(spatial);
|
|
super.setSpatial(spatial);
|
|
- if (spatial != null) {
|
|
|
|
- Node node = (Node) spatial;
|
|
|
|
- HashSet<Material> mats = new HashSet<Material>();
|
|
|
|
- ArrayList<Mesh> meshes = new ArrayList<Mesh>();
|
|
|
|
- findTargets(node, meshes, mats);
|
|
|
|
- targets = meshes.toArray(new Mesh[meshes.size()]);
|
|
|
|
- materials = mats.toArray(new Material[mats.size()]);
|
|
|
|
- } else {
|
|
|
|
- targets = null;
|
|
|
|
- materials = null;
|
|
|
|
- }
|
|
|
|
|
|
+ updateTargetsAndMaterials(spatial);
|
|
}
|
|
}
|
|
|
|
|
|
private void controlRenderSoftware() {
|
|
private void controlRenderSoftware() {
|
|
@@ -279,14 +271,12 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
|
|
|
|
offsetMatrices = skeleton.computeSkinningMatrices();
|
|
offsetMatrices = skeleton.computeSkinningMatrices();
|
|
|
|
|
|
- for (int i = 0; i < targets.length; i++) {
|
|
|
|
|
|
+ for (Mesh mesh : targets) {
|
|
// NOTE: This assumes that code higher up
|
|
// NOTE: This assumes that code higher up
|
|
// Already ensured those targets are animated
|
|
// Already ensured those targets are animated
|
|
// otherwise a crash will happen in skin update
|
|
// otherwise a crash will happen in skin update
|
|
- //if (isMeshAnimated(targets)) {
|
|
|
|
- softwareSkinUpdate(targets[i], offsetMatrices);
|
|
|
|
- //}
|
|
|
|
- }
|
|
|
|
|
|
+ softwareSkinUpdate(mesh, offsetMatrices);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private void controlRenderHardware() {
|
|
private void controlRenderHardware() {
|
|
@@ -336,6 +326,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
@Override
|
|
@Override
|
|
protected void controlUpdate(float tpf) {
|
|
protected void controlUpdate(float tpf) {
|
|
wasMeshUpdated = false;
|
|
wasMeshUpdated = false;
|
|
|
|
+ updateTargetsAndMaterials(spatial);
|
|
}
|
|
}
|
|
|
|
|
|
//only do this for software updates
|
|
//only do this for software updates
|
|
@@ -443,12 +434,12 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
// this.skeleton = skeleton;
|
|
// this.skeleton = skeleton;
|
|
// }
|
|
// }
|
|
/**
|
|
/**
|
|
- * returns the targets meshes of this control
|
|
|
|
|
|
+ * returns a copy of array of the targets meshes of this control
|
|
*
|
|
*
|
|
* @return
|
|
* @return
|
|
*/
|
|
*/
|
|
- public Mesh[] getTargets() {
|
|
|
|
- return targets;
|
|
|
|
|
|
+ public Mesh[] getTargets() {
|
|
|
|
+ return targets.toArray(new Mesh[targets.size()]);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -739,25 +730,35 @@ public class SkeletonControl extends AbstractControl implements Cloneable {
|
|
public void write(JmeExporter ex) throws IOException {
|
|
public void write(JmeExporter ex) throws IOException {
|
|
super.write(ex);
|
|
super.write(ex);
|
|
OutputCapsule oc = ex.getCapsule(this);
|
|
OutputCapsule oc = ex.getCapsule(this);
|
|
- oc.write(targets, "targets", null);
|
|
|
|
oc.write(skeleton, "skeleton", null);
|
|
oc.write(skeleton, "skeleton", null);
|
|
- oc.write(materials, "materials", null);
|
|
|
|
|
|
+ //Targets and materials doesn't need to be saved, th'ay be gathered on each frame
|
|
|
|
+ //oc.write(targets, "targets", null);
|
|
|
|
+ //oc.write(materials, "materials", null);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public void read(JmeImporter im) throws IOException {
|
|
public void read(JmeImporter im) throws IOException {
|
|
super.read(im);
|
|
super.read(im);
|
|
InputCapsule in = im.getCapsule(this);
|
|
InputCapsule in = im.getCapsule(this);
|
|
- Savable[] sav = in.readSavableArray("targets", null);
|
|
|
|
- if (sav != null) {
|
|
|
|
- targets = new Mesh[sav.length];
|
|
|
|
- System.arraycopy(sav, 0, targets, 0, sav.length);
|
|
|
|
- }
|
|
|
|
|
|
+// Savable[] sav = in.readSavableArray("targets", null);
|
|
|
|
+// if (sav != null) {
|
|
|
|
+// targets = new Mesh[sav.length];
|
|
|
|
+// System.arraycopy(sav, 0, targets, 0, sav.length);
|
|
|
|
+// }
|
|
skeleton = (Skeleton) in.readSavable("skeleton", null);
|
|
skeleton = (Skeleton) in.readSavable("skeleton", null);
|
|
- sav = in.readSavableArray("materials", null);
|
|
|
|
- if (sav != null) {
|
|
|
|
- materials = new Material[sav.length];
|
|
|
|
- System.arraycopy(sav, 0, materials, 0, sav.length);
|
|
|
|
|
|
+// sav = in.readSavableArray("materials", null);
|
|
|
|
+// if (sav != null) {
|
|
|
|
+// materials = new Material[sav.length];
|
|
|
|
+// System.arraycopy(sav, 0, materials, 0, sav.length);
|
|
|
|
+// }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updateTargetsAndMaterials(Spatial spatial) {
|
|
|
|
+ targets.clear();
|
|
|
|
+ materials.clear();
|
|
|
|
+ if (spatial != null && spatial instanceof Node) {
|
|
|
|
+ Node node = (Node) spatial;
|
|
|
|
+ findTargets(node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|