Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package com.jme3.animation;
     34 
     35 import com.jme3.export.*;
     36 import com.jme3.scene.Mesh;
     37 import com.jme3.scene.VertexBuffer;
     38 import com.jme3.scene.VertexBuffer.Type;
     39 import com.jme3.util.TempVars;
     40 import java.io.IOException;
     41 import java.nio.FloatBuffer;
     42 
     43 /**
     44  * A single track of pose animation associated with a certain mesh.
     45  */
     46 @Deprecated
     47 public final class PoseTrack implements Track {
     48 
     49     private int targetMeshIndex;
     50     private PoseFrame[] frames;
     51     private float[] times;
     52 
     53     public static class PoseFrame implements Savable, Cloneable {
     54 
     55         Pose[] poses;
     56         float[] weights;
     57 
     58         public PoseFrame(Pose[] poses, float[] weights) {
     59             this.poses = poses;
     60             this.weights = weights;
     61         }
     62 
     63         /**
     64          * This method creates a clone of the current object.
     65          * @return a clone of the current object
     66          */
     67         @Override
     68         public PoseFrame clone() {
     69             try {
     70                 PoseFrame result = (PoseFrame) super.clone();
     71                 result.weights = this.weights.clone();
     72                 if (this.poses != null) {
     73                     result.poses = new Pose[this.poses.length];
     74                     for (int i = 0; i < this.poses.length; ++i) {
     75                         result.poses[i] = this.poses[i].clone();
     76                     }
     77                 }
     78                 return result;
     79             } catch (CloneNotSupportedException e) {
     80                 throw new AssertionError();
     81             }
     82         }
     83 
     84         public void write(JmeExporter e) throws IOException {
     85             OutputCapsule out = e.getCapsule(this);
     86             out.write(poses, "poses", null);
     87             out.write(weights, "weights", null);
     88         }
     89 
     90         public void read(JmeImporter i) throws IOException {
     91             InputCapsule in = i.getCapsule(this);
     92             poses = (Pose[]) in.readSavableArray("poses", null);
     93             weights = in.readFloatArray("weights", null);
     94         }
     95     }
     96 
     97     public PoseTrack(int targetMeshIndex, float[] times, PoseFrame[] frames){
     98         this.targetMeshIndex = targetMeshIndex;
     99         this.times = times;
    100         this.frames = frames;
    101     }
    102 
    103     private void applyFrame(Mesh target, int frameIndex, float weight){
    104         PoseFrame frame = frames[frameIndex];
    105         VertexBuffer pb = target.getBuffer(Type.Position);
    106         for (int i = 0; i < frame.poses.length; i++){
    107             Pose pose = frame.poses[i];
    108             float poseWeight = frame.weights[i] * weight;
    109 
    110             pose.apply(poseWeight, (FloatBuffer) pb.getData());
    111         }
    112 
    113         // force to re-upload data to gpu
    114         pb.updateData(pb.getData());
    115     }
    116 
    117     public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
    118         // TODO: When MeshControl is created, it will gather targets
    119         // list automatically which is then retrieved here.
    120 
    121         /*
    122         Mesh target = targets[targetMeshIndex];
    123         if (time < times[0]) {
    124             applyFrame(target, 0, weight);
    125         } else if (time > times[times.length - 1]) {
    126             applyFrame(target, times.length - 1, weight);
    127         } else {
    128             int startFrame = 0;
    129             for (int i = 0; i < times.length; i++) {
    130                 if (times[i] < time) {
    131                     startFrame = i;
    132                 }
    133             }
    134 
    135             int endFrame = startFrame + 1;
    136             float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
    137             applyFrame(target, startFrame, blend * weight);
    138             applyFrame(target, endFrame, (1f - blend) * weight);
    139         }
    140         */
    141     }
    142 
    143     /**
    144      * @return the length of the track
    145      */
    146     public float getLength() {
    147         return times == null ? 0 : times[times.length - 1] - times[0];
    148     }
    149 
    150     /**
    151      * This method creates a clone of the current object.
    152      * @return a clone of the current object
    153      */
    154     @Override
    155     public PoseTrack clone() {
    156         try {
    157             PoseTrack result = (PoseTrack) super.clone();
    158             result.times = this.times.clone();
    159             if (this.frames != null) {
    160                 result.frames = new PoseFrame[this.frames.length];
    161                 for (int i = 0; i < this.frames.length; ++i) {
    162                     result.frames[i] = this.frames[i].clone();
    163                 }
    164             }
    165             return result;
    166         } catch (CloneNotSupportedException e) {
    167             throw new AssertionError();
    168         }
    169     }
    170 
    171     @Override
    172     public void write(JmeExporter e) throws IOException {
    173         OutputCapsule out = e.getCapsule(this);
    174         out.write(targetMeshIndex, "meshIndex", 0);
    175         out.write(frames, "frames", null);
    176         out.write(times, "times", null);
    177     }
    178 
    179     @Override
    180     public void read(JmeImporter i) throws IOException {
    181         InputCapsule in = i.getCapsule(this);
    182         targetMeshIndex = in.readInt("meshIndex", 0);
    183         frames = (PoseFrame[]) in.readSavableArray("frames", null);
    184         times = in.readFloatArray("times", null);
    185     }
    186 }
    187