159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.animation;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Quaternion;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Arrays;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class represents the track for spatial animation.
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class SpatialTrack implements Track {
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Translations of the track.
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private CompactVector3Array translations;
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Rotations of the track.
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private CompactQuaternionArray rotations;
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Scales of the track.
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private CompactVector3Array scales;
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The times of the animations frames.
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float[] times;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public SpatialTrack() {
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a spatial track for the given track data.
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param times
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            a float array with the time of each frame
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param translations
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the translation of the bone for each frame
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param rotations
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the rotation of the bone for each frame
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scales
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the scale of the bone for each frame
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public SpatialTrack(float[] times, Vector3f[] translations,
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                        Quaternion[] rotations, Vector3f[] scales) {
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setKeyframes(times, translations, rotations, scales);
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Modify the spatial which this track modifies.
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param time
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the current time of the animation
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Spatial spatial = control.getSpatial();
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempV = vars.vect1;
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempS = vars.vect2;
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Quaternion tempQ = vars.quat1;
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempV2 = vars.vect3;
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f tempS2 = vars.vect4;
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Quaternion tempQ2 = vars.quat2;
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int lastFrame = times.length - 1;
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (time < 0 || lastFrame == 0) {
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (rotations != null)
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                rotations.get(0, tempQ);
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (translations != null)
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                translations.get(0, tempV);
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (scales != null) {
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                scales.get(0, tempS);
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else if (time >= times[lastFrame]) {
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (rotations != null)
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                rotations.get(lastFrame, tempQ);
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (translations != null)
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                translations.get(lastFrame, tempV);
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (scales != null) {
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                scales.get(lastFrame, tempS);
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        } else {
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int startFrame = 0;
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            int endFrame = 1;
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // use lastFrame so we never overflow the array
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            for (int i = 0; i < lastFrame && times[i] < time; ++i) {
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                startFrame = i;
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                endFrame = i + 1;
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (rotations != null)
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                rotations.get(startFrame, tempQ);
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (translations != null)
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                translations.get(startFrame, tempV);
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (scales != null) {
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                scales.get(startFrame, tempS);
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (rotations != null)
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                rotations.get(endFrame, tempQ2);
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (translations != null)
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                translations.get(endFrame, tempV2);
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (scales != null) {
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                scales.get(endFrame, tempS2);
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            tempQ.nlerp(tempQ2, blend);
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            tempV.interpolate(tempV2, blend);
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            tempS.interpolate(tempS2, blend);
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (translations != null)
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            spatial.setLocalTranslation(tempV);
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (rotations != null)
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            spatial.setLocalRotation(tempQ);
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (scales != null) {
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            spatial.setLocalScale(tempS);
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the translations, rotations and scales for this track.
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param times
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            a float array with the time of each frame
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param translations
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the translation of the bone for each frame
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param rotations
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the rotation of the bone for each frame
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param scales
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *            the scale of the bone for each frame
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setKeyframes(float[] times, Vector3f[] translations,
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                             Quaternion[] rotations, Vector3f[] scales) {
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (times.length == 0) {
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new RuntimeException("BoneTrack with no keyframes!");
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.times = times;
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (translations != null) {
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assert times.length == translations.length;
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.translations = new CompactVector3Array();
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.translations.add(translations);
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.translations.freeze();
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (rotations != null) {
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assert times.length == rotations.length;
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.rotations = new CompactQuaternionArray();
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.rotations.add(rotations);
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.rotations.freeze();
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (scales != null) {
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            assert times.length == scales.length;
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.scales = new CompactVector3Array();
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.scales.add(scales);
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            this.scales.freeze();
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the array of rotations of this track
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Quaternion[] getRotations() {
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return rotations == null ? null : rotations.toObjectArray();
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the array of scales for this track
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f[] getScales() {
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return scales == null ? null : scales.toObjectArray();
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the arrays of time for this track
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float[] getTimes() {
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return times;
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the array of translations of this track
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f[] getTranslations() {
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return translations == null ? null : translations.toObjectArray();
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the length of the track
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getLength() {
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return times == null ? 0 : times[times.length - 1] - times[0];
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This method creates a clone of the current object.
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return a clone of the current object
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public SpatialTrack clone() {
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int tablesLength = times.length;
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        float[] timesCopy = this.times.clone();
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f[] translationsCopy = this.getTranslations() == null ? null : Arrays.copyOf(this.getTranslations(), tablesLength);
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Quaternion[] rotationsCopy = this.getRotations() == null ? null : Arrays.copyOf(this.getRotations(), tablesLength);
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Vector3f[] scalesCopy = this.getScales() == null ? null : Arrays.copyOf(this.getScales(), tablesLength);
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //need to use the constructor here because of the final fields used in this class
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return new SpatialTrack(timesCopy, translationsCopy, rotationsCopy, scalesCopy);
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void write(JmeExporter ex) throws IOException {
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        OutputCapsule oc = ex.getCapsule(this);
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(translations, "translations", null);
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(rotations, "rotations", null);
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(times, "times", null);
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(scales, "scales", null);
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void read(JmeImporter im) throws IOException {
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        InputCapsule ic = im.getCapsule(this);
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        translations = (CompactVector3Array) ic.readSavable("translations", null);
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        rotations = (CompactQuaternionArray) ic.readSavable("rotations", null);
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        times = ic.readFloatArray("times", null);
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        scales = (CompactVector3Array) ic.readSavable("scales", null);
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
243