addionnal javadoc for com.jme3.animation

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7636 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 14 years ago
parent 15e099e160
commit 4c18882032
  1. 57
      engine/src/core/com/jme3/animation/BoneAnimation.java
  2. 63
      engine/src/core/com/jme3/animation/BoneTrack.java
  3. 71
      engine/src/core/com/jme3/animation/CompactArray.java
  4. 27
      engine/src/core/com/jme3/animation/CompactQuaternionArray.java
  5. 8
      engine/src/core/com/jme3/animation/CompactVector3Array.java
  6. 37
      engine/src/core/com/jme3/animation/Skeleton.java
  7. 55
      engine/src/core/com/jme3/animation/SkeletonControl.java
  8. 23
      engine/src/core/com/jme3/animation/Track.java
  9. 6
      engine/src/core/com/jme3/post/FilterPostProcessor.java

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.animation; package com.jme3.animation;
import com.jme3.export.JmeExporter; import com.jme3.export.JmeExporter;
@ -43,12 +42,13 @@ import java.util.BitSet;
/** /**
* Bone animation updates each of its tracks with the skeleton and time * Bone animation updates each of its tracks with the skeleton and time
* to apply the animation. * to apply the animation.
*
* @author Kirill Vainer
*/ */
public final class BoneAnimation implements Savable { public final class BoneAnimation implements Savable {
private String name; private String name;
private float length; private float length;
private BoneTrack[] tracks; private BoneTrack[] tracks;
/** /**
@ -57,7 +57,7 @@ public final class BoneAnimation implements Savable {
* @param name The name of the bone animation. * @param name The name of the bone animation.
* @param length Length in seconds of the bone animation. * @param length Length in seconds of the bone animation.
*/ */
public BoneAnimation(String name, float length){ public BoneAnimation(String name, float length) {
this.name = name; this.name = name;
this.length = length; this.length = length;
} }
@ -65,43 +65,55 @@ public final class BoneAnimation implements Savable {
/** /**
* Serialization-only. Do not use. * Serialization-only. Do not use.
*/ */
public BoneAnimation(){ public BoneAnimation() {
} }
public String getName(){ /**
* Returns the animation name
* @return
*/
public String getName() {
return name; return name;
} }
public float getLength(){ /**
* returns the animation length (in seconds)
* @return
*/
public float getLength() {
return length; return length;
} }
public void setTracks(BoneTrack[] tracks){ /**
* Sets the bone tracks to this bone animation
* @see BoneTrack
* @param tracks
*/
public void setTracks(BoneTrack[] tracks) {
this.tracks = tracks; this.tracks = tracks;
} }
public BoneTrack[] getTracks(){ /**
* returns the bone tracks of this animation
* @see BoneTrack
* @return
*/
public BoneTrack[] getTracks() {
return tracks; return tracks;
} }
void setTime(float time, Skeleton skeleton, float weight, BitSet affectedBones){ void setTime(float time, Skeleton skeleton, float weight, BitSet affectedBones) {
for (int i = 0; i < tracks.length; i++){ for (int i = 0; i < tracks.length; i++) {
if (affectedBones == null if (affectedBones == null
|| affectedBones.get(tracks[i].getTargetBoneIndex())) || affectedBones.get(tracks[i].getTargetBoneIndex())) {
tracks[i].setTime(time, skeleton, weight); tracks[i].setTime(time, skeleton, weight);
}
} }
} }
// void setTime(float time, Skeleton skeleton, float weight, ArrayList<Integer> affectedBones){ @Override
// for (int i = 0; i < tracks.length; i++){ public String toString() {
// if (affectedBones == null return "BoneAnim[name=" + name + ", length=" + length + "]";
// || affectedBones.contains(tracks[i].getTargetBoneIndex()))
// tracks[i].setTime(time, skeleton, weight);
// }
// }
public String toString(){
return "BoneAnim[name="+name+", length="+length+"]";
} }
public void write(JmeExporter e) throws IOException { public void write(JmeExporter e) throws IOException {
@ -117,10 +129,9 @@ public final class BoneAnimation implements Savable {
length = in.readFloat("length", 0f); length = in.readFloat("length", 0f);
Savable[] sav = in.readSavableArray("tracks", null); Savable[] sav = in.readSavableArray("tracks", null);
if (sav != null){ if (sav != null) {
tracks = new BoneTrack[sav.length]; tracks = new BoneTrack[sav.length];
System.arraycopy(sav, 0, tracks, 0, sav.length); System.arraycopy(sav, 0, tracks, 0, sav.length);
} }
} }
} }

@ -42,6 +42,8 @@ import java.io.IOException;
/** /**
* Contains a list of transforms and times for each keyframe. * Contains a list of transforms and times for each keyframe.
*
* @author Kirill Vainer
*/ */
public final class BoneTrack implements Savable { public final class BoneTrack implements Savable {
@ -56,7 +58,6 @@ public final class BoneTrack implements Savable {
private CompactQuaternionArray rotations; private CompactQuaternionArray rotations;
private CompactVector3Array scales; private CompactVector3Array scales;
private float[] times; private float[] times;
// temp vectors for interpolation // temp vectors for interpolation
private transient final Vector3f tempV = new Vector3f(); private transient final Vector3f tempV = new Vector3f();
private transient final Quaternion tempQ = new Quaternion(); private transient final Quaternion tempQ = new Quaternion();
@ -71,40 +72,85 @@ public final class BoneTrack implements Savable {
public BoneTrack() { public BoneTrack() {
} }
/**
* Creates a bone track for the given bone index
* @param targetBoneIndex the bone index
* @param times a float array with the time of each frame
* @param translations the translation of the bone for each frame
* @param rotations the rontation of the bone for each frame
*/
public BoneTrack(int targetBoneIndex, float[] times, Vector3f[] translations, Quaternion[] rotations) { public BoneTrack(int targetBoneIndex, float[] times, Vector3f[] translations, Quaternion[] rotations) {
this.targetBoneIndex = targetBoneIndex; this.targetBoneIndex = targetBoneIndex;
this.setKeyframes(times, translations, rotations); this.setKeyframes(times, translations, rotations);
} }
/**
* Creates a bone track for the given bone index
* @param targetBoneIndex the bone index
* @param times a float array with the time of each frame
* @param translations the translation of the bone for each frame
* @param rotations the rontation of the bone for each frame
* @param scales the scale of the bone for each frame
*/
public BoneTrack(int targetBoneIndex, float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) { public BoneTrack(int targetBoneIndex, float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) {
this(targetBoneIndex, times, translations, rotations); this(targetBoneIndex, times, translations, rotations);
this.setKeyframes(times, translations, rotations); this.setKeyframes(times, translations, rotations);
} }
/**
* Creates a bone track for the given bone index
* @param targetBoneIndex the bone's index
*/
public BoneTrack(int targetBoneIndex) { public BoneTrack(int targetBoneIndex) {
this.targetBoneIndex = targetBoneIndex; this.targetBoneIndex = targetBoneIndex;
} }
/**
* returns the bone index of this bone track
* @return
*/
public int getTargetBoneIndex() { public int getTargetBoneIndex() {
return targetBoneIndex; return targetBoneIndex;
} }
/**
* return the array of rotations of this track
* @return
*/
public Quaternion[] getRotations() { public Quaternion[] getRotations() {
return rotations.toObjectArray(); return rotations.toObjectArray();
} }
/**
* returns the array of scales for this track
* @return
*/
public Vector3f[] getScales() { public Vector3f[] getScales() {
return scales == null ? null : scales.toObjectArray(); return scales == null ? null : scales.toObjectArray();
} }
/**
* returns the arrays of time for this track
* @return
*/
public float[] getTimes() { public float[] getTimes() {
return times; return times;
} }
/**
* returns the array of translations of this track
* @return
*/
public Vector3f[] getTranslations() { public Vector3f[] getTranslations() {
return translations.toObjectArray(); return translations.toObjectArray();
} }
/**
* Set the translations and rotations for this bone track
* @param times a float array with the time of each frame
* @param translations the translation of the bone for each frame
* @param rotations the rontation of the bone for each frame
*/
public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations) { public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations) {
if (times.length == 0) { if (times.length == 0) {
throw new RuntimeException("BoneTrack with no keyframes!"); throw new RuntimeException("BoneTrack with no keyframes!");
@ -121,6 +167,13 @@ public final class BoneTrack implements Savable {
this.rotations.freeze(); this.rotations.freeze();
} }
/**
* Set the translations, rotations and scales for this bone track
* @param times a float array with the time of each frame
* @param translations the translation of the bone for each frame
* @param rotations the rontation of the bone for each frame
* @param scales the scale of the bone for each frame
*/
public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) { public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) {
this.setKeyframes(times, translations, rotations); this.setKeyframes(times, translations, rotations);
assert times.length == scales.length; assert times.length == scales.length;
@ -132,9 +185,14 @@ public final class BoneTrack implements Savable {
} }
/** /**
*
* Modify the bone which this track modifies in the skeleton to contain * Modify the bone which this track modifies in the skeleton to contain
* the correct animation transforms for a given time. * the correct animation transforms for a given time.
* The transforms can be interpolated in some method from the keyframes. * The transforms can be interpolated in some method from the keyframes.
*
* @param time the current time of the animation
* @param skeleton the skeleton to which the bone belong
* @param weight the weight of the animation
*/ */
public void setTime(float time, Skeleton skeleton, float weight) { public void setTime(float time, Skeleton skeleton, float weight) {
Bone target = skeleton.getBone(targetBoneIndex); Bone target = skeleton.getBone(targetBoneIndex);
@ -181,10 +239,7 @@ public final class BoneTrack implements Savable {
} }
if (weight != 1f) { if (weight != 1f) {
// tempQ.slerp(Quaternion.IDENTITY, 1f - weight);
// tempV.multLocal(weight);
target.blendAnimTransforms(tempV, tempQ, scales != null ? tempS : null, weight); target.blendAnimTransforms(tempV, tempQ, scales != null ? tempS : null, weight);
// target.setAnimTransforms(tempV, tempQ);
} else { } else {
target.setAnimTransforms(tempV, tempQ, scales != null ? tempS : null); target.setAnimTransforms(tempV, tempQ, scales != null ? tempS : null);
} }

@ -29,15 +29,12 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.animation; package com.jme3.animation;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* Object is indexed and stored in primitive float[] * Object is indexed and stored in primitive float[]
* @author Lim, YongHoon * @author Lim, YongHoon
@ -45,12 +42,14 @@ import java.util.Map;
*/ */
public abstract class CompactArray<T> { public abstract class CompactArray<T> {
private Map<T,Integer> indexPool = new HashMap<T, Integer>(); private Map<T, Integer> indexPool = new HashMap<T, Integer>();
protected int[] index; protected int[] index;
protected float[] array; protected float[] array;
private boolean invalid; private boolean invalid;
/**
* Creates a compact array
*/
public CompactArray() { public CompactArray() {
} }
@ -70,8 +69,9 @@ public abstract class CompactArray<T> {
* @param objArray * @param objArray
*/ */
public void add(T... objArray) { public void add(T... objArray) {
if (objArray == null || objArray.length == 0) if (objArray == null || objArray.length == 0) {
return; return;
}
invalid = true; invalid = true;
int base = 0; int base = 0;
if (index == null) { if (index == null) {
@ -87,21 +87,21 @@ public abstract class CompactArray<T> {
index = tmp; index = tmp;
//index = Arrays.copyOf(index, base+objArray.length); //index = Arrays.copyOf(index, base+objArray.length);
} }
for (int j=0; j < objArray.length; j++) { for (int j = 0; j < objArray.length; j++) {
T obj = objArray[j]; T obj = objArray[j];
if (obj == null) { if (obj == null) {
index[base+j] = -1; index[base + j] = -1;
} else { } else {
Integer i = indexPool.get(obj); Integer i = indexPool.get(obj);
if (i == null) { if (i == null) {
i = indexPool.size(); i = indexPool.size();
indexPool.put(obj, i); indexPool.put(obj, i);
} }
index[base+j] = i; index[base + j] = i;
} }
} }
} }
/** /**
* release objects. * release objects.
* add() method call is not allowed anymore. * add() method call is not allowed anymore.
@ -120,22 +120,35 @@ public abstract class CompactArray<T> {
serialize(j, value); serialize(j, value);
} }
/**
* returns the object for the given index
* @param index the index
* @param store an object to store the result
* @return
*/
public final T get(int index, T store) { public final T get(int index, T store) {
serialize(); serialize();
int j = getCompactIndex(index); int j = getCompactIndex(index);
return deserialize(j, store); return deserialize(j, store);
} }
/**
* return a float array of serialized data
* @return
*/
public final float[] getSerializedData() { public final float[] getSerializedData() {
serialize(); serialize();
return array; return array;
} }
/**
* serialize this compact array
*/
public final void serialize() { public final void serialize() {
if (invalid) { if (invalid) {
int newSize = indexPool.size()*getTupleSize(); int newSize = indexPool.size() * getTupleSize();
if (array == null || Array.getLength(array) < newSize) { if (array == null || Array.getLength(array) < newSize) {
array = ensureCapacity(array, newSize); array = ensureCapacity(array, newSize);
for (Map.Entry<T, Integer> entry : indexPool.entrySet()) { for (Map.Entry<T, Integer> entry : indexPool.entrySet()) {
int i = entry.getValue(); int i = entry.getValue();
T obj = entry.getKey(); T obj = entry.getKey();
@ -153,6 +166,12 @@ public abstract class CompactArray<T> {
return Array.getLength(getSerializedData()); return Array.getLength(getSerializedData());
} }
/**
* Ensure the capacity for the given array and the given size
* @param arr the array
* @param size the size
* @return
*/
protected float[] ensureCapacity(float[] arr, int size) { protected float[] ensureCapacity(float[] arr, int size) {
if (arr == null) { if (arr == null) {
return new float[size]; return new float[size];
@ -166,37 +185,43 @@ public abstract class CompactArray<T> {
} }
} }
/**
* retrun an array of indices for the given objects
* @param objArray
* @return
*/
public final int[] getIndex(T... objArray) { public final int[] getIndex(T... objArray) {
int[] index = new int[objArray.length]; int[] index = new int[objArray.length];
for (int i = 0; i < index.length; i++) { for (int i = 0; i < index.length; i++) {
T obj = objArray[i]; T obj = objArray[i];
index[i] = obj!=null? indexPool.get(obj): -1; index[i] = obj != null ? indexPool.get(obj) : -1;
} }
return index; return index;
} }
/** /**
* returns the corresponding index in the compact array
* @param objIndex * @param objIndex
* @return object index in the compacted object array * @return object index in the compacted object array
*/ */
public int getCompactIndex(int objIndex) { public int getCompactIndex(int objIndex) {
return index!=null ? index[objIndex]: objIndex; return index != null ? index[objIndex] : objIndex;
} }
/** /**
* @return uncompressed object size * @return uncompressed object size
*/ */
public final int getTotalObjectSize() { public final int getTotalObjectSize() {
assert getSerializedSize()%getTupleSize() == 0; assert getSerializedSize() % getTupleSize() == 0;
return index!=null? index.length: getSerializedSize()/getTupleSize(); return index != null ? index.length : getSerializedSize() / getTupleSize();
} }
/** /**
* @return compressed object size * @return compressed object size
*/ */
public final int getCompactObjectSize() { public final int getCompactObjectSize() {
assert getSerializedSize()%getTupleSize() == 0; assert getSerializedSize() % getTupleSize() == 0;
return getSerializedSize()/getTupleSize(); return getSerializedSize() / getTupleSize();
} }
/** /**
@ -205,12 +230,12 @@ public abstract class CompactArray<T> {
*/ */
public final T[] toObjectArray() { public final T[] toObjectArray() {
try { try {
T[] compactArr = (T[]) Array.newInstance(getElementClass(), getSerializedSize()/getTupleSize()); T[] compactArr = (T[]) Array.newInstance(getElementClass(), getSerializedSize() / getTupleSize());
for (int i = 0; i < compactArr.length; i++) { for (int i = 0; i < compactArr.length; i++) {
compactArr[i] = getElementClass().newInstance(); compactArr[i] = getElementClass().newInstance();
deserialize(i, compactArr[i]); deserialize(i, compactArr[i]);
} }
T[] objArr = (T[]) Array.newInstance(getElementClass(), getTotalObjectSize()); T[] objArr = (T[]) Array.newInstance(getElementClass(), getTotalObjectSize());
for (int i = 0; i < objArr.length; i++) { for (int i = 0; i < objArr.length; i++) {
int compactIndex = getCompactIndex(i); int compactIndex = getCompactIndex(i);
@ -222,7 +247,6 @@ public abstract class CompactArray<T> {
} }
} }
/** /**
* serialize object * serialize object
* @param compactIndex compacted object index * @param compactIndex compacted object index
@ -241,7 +265,6 @@ public abstract class CompactArray<T> {
* serialized size of one object element * serialized size of one object element
*/ */
protected abstract int getTupleSize(); protected abstract int getTupleSize();
protected abstract Class<T> getElementClass();
protected abstract Class<T> getElementClass();
} }

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.animation; package com.jme3.animation;
import java.io.IOException; import java.io.IOException;
@ -48,9 +47,17 @@ import com.jme3.math.Quaternion;
*/ */
public class CompactQuaternionArray extends CompactArray<Quaternion> implements Savable { public class CompactQuaternionArray extends CompactArray<Quaternion> implements Savable {
/**
* creates a compact quaternion array
*/
public CompactQuaternionArray() { public CompactQuaternionArray() {
} }
/**
* creates a compact quaternion array
* @param dataArray the data array
* @param index the indices array
*/
public CompactQuaternionArray(float[] dataArray, int[] index) { public CompactQuaternionArray(float[] dataArray, int[] index) {
super(dataArray, index); super(dataArray, index);
} }
@ -64,7 +71,7 @@ public class CompactQuaternionArray extends CompactArray<Quaternion> implements
protected final Class<Quaternion> getElementClass() { protected final Class<Quaternion> getElementClass() {
return Quaternion.class; return Quaternion.class;
} }
@Override @Override
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
serialize(); serialize();
@ -72,27 +79,27 @@ public class CompactQuaternionArray extends CompactArray<Quaternion> implements
out.write(array, "array", null); out.write(array, "array", null);
out.write(index, "index", null); out.write(index, "index", null);
} }
@Override @Override
public void read(JmeImporter im) throws IOException { public void read(JmeImporter im) throws IOException {
InputCapsule in = im.getCapsule(this); InputCapsule in = im.getCapsule(this);
array = in.readFloatArray("array", null); array = in.readFloatArray("array", null);
index = in.readIntArray("index", null); index = in.readIntArray("index", null);
} }
@Override @Override
protected void serialize(int i, Quaternion store) { protected void serialize(int i, Quaternion store) {
int j = i*getTupleSize(); int j = i * getTupleSize();
array[j] = store.getX(); array[j] = store.getX();
array[j+1] = store.getY(); array[j + 1] = store.getY();
array[j+2] = store.getZ(); array[j + 2] = store.getZ();
array[j+3] = store.getW(); array[j + 3] = store.getW();
} }
@Override @Override
protected Quaternion deserialize(int i, Quaternion store) { protected Quaternion deserialize(int i, Quaternion store) {
int j = i*getTupleSize(); int j = i * getTupleSize();
store.set(array[j], array[j+1], array[j+2], array[j+3]); store.set(array[j], array[j + 1], array[j + 2], array[j + 3]);
return store; return store;
} }
} }

@ -47,9 +47,17 @@ import com.jme3.math.Vector3f;
*/ */
public class CompactVector3Array extends CompactArray<Vector3f> implements Savable { public class CompactVector3Array extends CompactArray<Vector3f> implements Savable {
/**
* Creates a compact vector array
*/
public CompactVector3Array() { public CompactVector3Array() {
} }
/**
* creates a compact vector array
* @param dataArray the data array
* @param index the indices
*/
public CompactVector3Array(float[] dataArray, int[] index) { public CompactVector3Array(float[] dataArray, int[] index) {
super(dataArray, index); super(dataArray, index);
} }

@ -163,6 +163,9 @@ public final class Skeleton implements Savable {
} }
} }
/**
* Reset the skeleton to bind pose and updates the bones
*/
public final void resetAndUpdate() { public final void resetAndUpdate() {
for (int i = rootBones.length - 1; i >= 0; i--) { for (int i = rootBones.length - 1; i >= 0; i--) {
Bone rootBone = rootBones[i]; Bone rootBone = rootBones[i];
@ -171,14 +174,28 @@ public final class Skeleton implements Savable {
} }
} }
/**
* returns the array of all root bones of this skeleton
* @return
*/
public Bone[] getRoots() { public Bone[] getRoots() {
return rootBones; return rootBones;
} }
/**
* return a bone for the given index
* @param index
* @return
*/
public Bone getBone(int index) { public Bone getBone(int index) {
return boneList[index]; return boneList[index];
} }
/**
* returns the bone with the given name
* @param name
* @return
*/
public Bone getBone(String name) { public Bone getBone(String name) {
for (int i = 0; i < boneList.length; i++) { for (int i = 0; i < boneList.length; i++) {
if (boneList[i].getName().equals(name)) { if (boneList[i].getName().equals(name)) {
@ -189,6 +206,11 @@ public final class Skeleton implements Savable {
return null; return null;
} }
/**
* returns the bone index of the given bone
* @param bone
* @return
*/
public int getBoneIndex(Bone bone) { public int getBoneIndex(Bone bone) {
for (int i = 0; i < boneList.length; i++) { for (int i = 0; i < boneList.length; i++) {
if (boneList[i] == bone) { if (boneList[i] == bone) {
@ -199,8 +221,13 @@ public final class Skeleton implements Savable {
return -1; return -1;
} }
/**
* returns the bone index of the bone that has the given name
* @param name
* @return
*/
public int getBoneIndex(String name) { public int getBoneIndex(String name) {
for (int i = 0; i < boneList.length; i++) { for (int i = 0; i < boneList.length; i++) {
if (boneList[i].getName().equals(name)) { if (boneList[i].getName().equals(name)) {
return i; return i;
} }
@ -209,6 +236,10 @@ public final class Skeleton implements Savable {
return -1; return -1;
} }
/**
* Compute the skining matrices for each bone of the skeleton that would be used to transform vertices of associated meshes
* @return
*/
public Matrix4f[] computeSkinningMatrices() { public Matrix4f[] computeSkinningMatrices() {
TempVars vars = TempVars.get(); TempVars vars = TempVars.get();
assert vars.lock(); assert vars.lock();
@ -219,6 +250,10 @@ public final class Skeleton implements Savable {
return skinningMatrixes; return skinningMatrixes;
} }
/**
* returns the number of bones of this skeleton
* @return
*/
public int getBoneCount() { public int getBoneCount() {
return boneList.length; return boneList.length;
} }

@ -27,30 +27,38 @@ import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
/** /**
* * The Skeleton control deforms a model according to a skeleton,
* @author Nehon * It handles the computation of the deformtation matrices and performs the transformations on the mesh
*
* @author Rémy Bouquet Based on AnimControl by Kirill Vainer
*/ */
public class SkeletonControl extends AbstractControl implements Savable, Cloneable { public class SkeletonControl extends AbstractControl implements Savable, Cloneable {
/** /**
* The skelrton of the model * The skeleton of the model
*/ */
private Skeleton skeleton; private Skeleton skeleton;
/** /**
* List of targets which this controller effects. * List of targets which this controller effects.
*/ */
private Mesh[] targets; private Mesh[] targets;
/** /**
* Used to track when a mesh was updated. Meshes are only updated * Used to track when a mesh was updated. Meshes are only updated
* if they are visible in at least one camera. * if they are visible in at least one camera.
*/ */
private boolean wasMeshUpdated = false; private boolean wasMeshUpdated = false;
/**
* for serialization only
*/
public SkeletonControl() { public SkeletonControl() {
} }
/**
* Creates a skeleton control
* @param targets the meshes controled by the skeleton
* @param skeleton the skeleton
*/
public SkeletonControl(Mesh[] targets, Skeleton skeleton) { public SkeletonControl(Mesh[] targets, Skeleton skeleton) {
this.skeleton = skeleton; this.skeleton = skeleton;
this.targets = targets; this.targets = targets;
@ -58,7 +66,7 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
@Override @Override
protected void controlRender(RenderManager rm, ViewPort vp) { protected void controlRender(RenderManager rm, ViewPort vp) {
if (!wasMeshUpdated){ if (!wasMeshUpdated) {
resetToBind(); // reset morph meshes to bind pose resetToBind(); // reset morph meshes to bind pose
Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices(); Matrix4f[] offsetMatrices = skeleton.computeSkinningMatrices();
@ -71,7 +79,7 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
softwareSkinUpdate(targets[i], offsetMatrices); softwareSkinUpdate(targets[i], offsetMatrices);
} }
} }
wasMeshUpdated = true; wasMeshUpdated = true;
} }
} }
@ -79,19 +87,7 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
@Override @Override
protected void controlUpdate(float tpf) { protected void controlUpdate(float tpf) {
wasMeshUpdated = false; 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() { void resetToBind() {
@ -169,26 +165,43 @@ public class SkeletonControl extends AbstractControl implements Savable, Cloneab
return n; return n;
} }
/**
* returns the skeleton of this control
* @return
*/
public Skeleton getSkeleton() { public Skeleton getSkeleton() {
return skeleton; return skeleton;
} }
/**
* sets the skeleton for this control
* @param skeleton
*/
public void setSkeleton(Skeleton skeleton) { public void setSkeleton(Skeleton skeleton) {
this.skeleton = skeleton; this.skeleton = skeleton;
} }
/**
* retuns the targets meshes of this ocntrol
* @return
*/
public Mesh[] getTargets() { public Mesh[] getTargets() {
return targets; return targets;
} }
/**
* sets the target meshes of this control
* @param targets
*/
public void setTargets(Mesh[] targets) { public void setTargets(Mesh[] targets) {
this.targets = targets; this.targets = targets;
} }
private void softwareSkinUpdate(Mesh mesh, Matrix4f[] offsetMatrices) { private void softwareSkinUpdate(Mesh mesh, Matrix4f[] offsetMatrices) {
int maxWeightsPerVert = mesh.getMaxNumWeights(); int maxWeightsPerVert = mesh.getMaxNumWeights();
if (maxWeightsPerVert <= 0) if (maxWeightsPerVert <= 0) {
throw new IllegalStateException("Max weights per vert is incorrectly set!"); throw new IllegalStateException("Max weights per vert is incorrectly set!");
}
int fourMinusMaxWeights = 4 - maxWeightsPerVert; int fourMinusMaxWeights = 4 - maxWeightsPerVert;

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package com.jme3.animation; package com.jme3.animation;
import com.jme3.export.JmeExporter; import com.jme3.export.JmeExporter;
@ -46,21 +45,35 @@ public abstract class Track implements Savable {
protected int targetMeshIndex; protected int targetMeshIndex;
public Track(int targetMeshIndex){ /**
* build a track for a an index
* @param targetMeshIndex
*/
public Track(int targetMeshIndex) {
this.targetMeshIndex = targetMeshIndex; this.targetMeshIndex = targetMeshIndex;
} }
public int getTargetMeshIndex(){ /**
* return the mesh index
* @return
*/
public int getTargetMeshIndex() {
return targetMeshIndex; return targetMeshIndex;
} }
/**
* sets time for this track
* @param time
* @param targets
* @param weight
*/
public abstract void setTime(float time, Mesh[] targets, float weight); public abstract void setTime(float time, Mesh[] targets, float weight);
public void write(JmeExporter ex) throws IOException{ public void write(JmeExporter ex) throws IOException {
ex.getCapsule(this).write(targetMeshIndex, "meshIndex", 0); ex.getCapsule(this).write(targetMeshIndex, "meshIndex", 0);
} }
public void read(JmeImporter im) throws IOException{ public void read(JmeImporter im) throws IOException {
targetMeshIndex = im.getCapsule(this).readInt("meshIndex", 0); targetMeshIndex = im.getCapsule(this).readInt("meshIndex", 0);
} }
} }

@ -123,11 +123,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
* @param filter * @param filter
*/ */
public void removeFilter(Filter filter) { public void removeFilter(Filter filter) {
for (Iterator<Filter> it = filters.iterator(); it.hasNext();) { filters.remove(filter);
if (it.next() == filter) {
it.remove();
}
}
filter.cleanup(renderer); filter.cleanup(renderer);
updateLastFilterIndex(); updateLastFilterIndex();
} }

Loading…
Cancel
Save