Przeglądaj źródła

Improve MorphTrack API (#1608)

* Improve MorphTrack API

The MorphTrack's current API has some inconsistencies with TransformTrack's API and some limitations as well (no ability to get/set the desired number of morph targets). This patch makes MorphTrack's API consistent with TransformTrack's API and adds a getter/setter for the number of morph targets.

* Set weights with number of morph targets

* Important invariants must hold between the number of frames, the number of weights, and the number of morph targets, so we're requiring setting the weights at the same time that the number of morph targets are set.
* Javadoc tweaks

* Fixed build error

* Improved morph weight invariants checks

* Removed superfluous assert.

* Improved exception types & docs

* Doc cleanup

* MorphTrack: clarify the javadoc

* TransformTrack: revert out-of-scope changes

* reformat modified sourcecode (per issue 1098)

Co-authored-by: Stephen Gold <[email protected]>
Daniel Perano 4 lat temu
rodzic
commit
84d7d3bb2d

+ 56 - 9
jme3-core/src/main/java/com/jme3/anim/MorphTrack.java

@@ -88,6 +88,31 @@ public class MorphTrack implements AnimTrack<float[]> {
         return weights;
     }
 
+    /**
+     * Set the weights for this morph track. Note that the number of weights
+     * must equal the number of frames times the number of morph targets.
+     *
+     * @param weights  the weights of the morphs for each frame (alias created
+     *                 -- do not modify after passing it to this setter)
+     *
+     * @throws IllegalStateException if this track does not have times set
+     * @throws IllegalArgumentException if weights is an empty array or if
+     *         the number of weights violates the frame count constraint
+     */
+    public void setKeyframesWeight(float[] weights) {
+        if (times == null) {
+            throw new IllegalStateException("MorphTrack doesn't have any time for key frames, please call setTimes first");
+        }
+        if (weights.length == 0) {
+            throw new IllegalArgumentException("MorphTrack with no weight keyframes!");
+        }
+        if (times.length * nbMorphTargets != weights.length) {
+            throw new IllegalArgumentException("weights.length must equal nbMorphTargets * times.length");
+        }
+
+        this.weights = weights;
+    }
+
     /**
      * returns the arrays of time for this track
      *
@@ -102,10 +127,11 @@ public class MorphTrack implements AnimTrack<float[]> {
      *
      * @param times  the keyframes times (alias created -- do not modify after
      *               passing it to this setter)
+     * @throws IllegalArgumentException if times is empty
      */
     public void setTimes(float[] times) {
         if (times.length == 0) {
-            throw new RuntimeException("TransformTrack with no keyframes!");
+            throw new IllegalArgumentException("TransformTrack with no keyframes!");
         }
         this.times = times;
         length = times[times.length - 1] - times[0];
@@ -113,7 +139,8 @@ public class MorphTrack implements AnimTrack<float[]> {
 
 
     /**
-     * Set the weight for this morph track
+     * Sets the times and weights for this morph track. Note that the number of weights
+     * must equal the number of frames times the number of morph targets.
      *
      * @param times    a float array with the time of each frame (alias created
      *                 -- do not modify after passing it to this setter)
@@ -121,16 +148,37 @@ public class MorphTrack implements AnimTrack<float[]> {
      *                 -- do not modify after passing it to this setter)
      */
     public void setKeyframes(float[] times, float[] weights) {
-        setTimes(times);
+        if (times != null) {
+            setTimes(times);
+        }
         if (weights != null) {
-            if (times == null) {
-                throw new RuntimeException("MorphTrack doesn't have any time for key frames, please call setTimes first");
-            }
+            setKeyframesWeight(weights);
+        }
+    }
 
-            this.weights = weights;
+    /**
+     * @return the number of morph targets
+     */
+    public int getNbMorphTargets() {
+        return nbMorphTargets;
+    }
 
-            assert times.length == weights.length;
+    /**
+     * Sets the number of morph targets and the corresponding weights.
+     * Note that the number of weights must equal the number of frames times the number of morph targets.
+     *
+     * @param weights        the weights for each frame (alias created
+     *                       -- do not modify after passing it to this setter)
+     * @param nbMorphTargets the desired number of morph targets
+     * @throws IllegalArgumentException if the number of weights and the new
+     *         number of morph targets violate the frame count constraint
+     */
+    public void setNbMorphTargets(float[] weights, int nbMorphTargets) {
+        if (times.length * nbMorphTargets != weights.length) {
+            throw new IllegalArgumentException("weights.length must equal nbMorphTargets * times.length");
         }
+        this.nbMorphTargets = nbMorphTargets;
+        setKeyframesWeight(weights);
     }
 
     @Override
@@ -250,5 +298,4 @@ public class MorphTrack implements AnimTrack<float[]> {
         // Note: interpolator, times, and weights are not cloned
     }
 
-
 }