1/* 2 * Copyright (c) 2009-2011 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 */ 32package com.jme3.animation; 33 34import com.jme3.export.*; 35import com.jme3.util.TempVars; 36import java.io.IOException; 37 38/** 39 * The animation class updates the animation target with the tracks of a given type. 40 * 41 * @author Kirill Vainer, Marcin Roguski (Kaelthas) 42 */ 43public class Animation implements Savable, Cloneable { 44 45 /** 46 * The name of the animation. 47 */ 48 private String name; 49 50 /** 51 * The length of the animation. 52 */ 53 private float length; 54 55 /** 56 * The tracks of the animation. 57 */ 58 private Track[] tracks; 59 60 /** 61 * Serialization-only. Do not use. 62 */ 63 public Animation() {} 64 65 /** 66 * Creates a new <code>Animation</code> with the given name and length. 67 * 68 * @param name The name of the animation. 69 * @param length Length in seconds of the animation. 70 */ 71 public Animation(String name, float length) { 72 this.name = name; 73 this.length = length; 74 } 75 76 /** 77 * The name of the bone animation 78 * @return name of the bone animation 79 */ 80 public String getName() { 81 return name; 82 } 83 84 /** 85 * Returns the length in seconds of this animation 86 * 87 * @return the length in seconds of this animation 88 */ 89 public float getLength() { 90 return length; 91 } 92 93 /** 94 * This method sets the current time of the animation. 95 * This method behaves differently for every known track type. 96 * Override this method if you have your own type of track. 97 * 98 * @param time the time of the animation 99 * @param blendAmount the blend amount factor 100 * @param control the animation control 101 * @param channel the animation channel 102 */ 103 void setTime(float time, float blendAmount, AnimControl control, AnimChannel channel, TempVars vars) { 104 if (tracks == null) 105 return; 106 107 for (int i = 0; i < tracks.length; i++){ 108 tracks[i].setTime(time, blendAmount, control, channel, vars); 109 } 110 111 /* 112 if (tracks != null && tracks.length > 0) { 113 Track<?> trackInstance = tracks[0]; 114 115 if (trackInstance instanceof SpatialTrack) { 116 Spatial spatial = control.getSpatial(); 117 if (spatial != null) { 118 ((SpatialTrack) tracks[0]).setTime(time, spatial, blendAmount); 119 } 120 } else if (trackInstance instanceof BoneTrack) { 121 BitSet affectedBones = channel.getAffectedBones(); 122 Skeleton skeleton = control.getSkeleton(); 123 for (int i = 0; i < tracks.length; ++i) { 124 if (affectedBones == null || affectedBones.get(((BoneTrack) tracks[i]).getTargetIndex())) { 125 ((BoneTrack) tracks[i]).setTime(time, skeleton, blendAmount); 126 } 127 } 128 } else if (trackInstance instanceof PoseTrack) { 129 Spatial spatial = control.getSpatial(); 130 List<Mesh> meshes = new ArrayList<Mesh>(); 131 this.getMeshes(spatial, meshes); 132 if (meshes.size() > 0) { 133 Mesh[] targets = meshes.toArray(new Mesh[meshes.size()]); 134 for (int i = 0; i < tracks.length; ++i) { 135 ((PoseTrack) tracks[i]).setTime(time, targets, blendAmount); 136 } 137 } 138 } 139 } 140 */ 141 } 142 143 /** 144 * Set the {@link Track}s to be used by this animation. 145 * <p> 146 * The array should be organized so that the appropriate Track can 147 * be retrieved based on a bone index. 148 * 149 * @param tracks The tracks to set. 150 */ 151 public void setTracks(Track[] tracks){ 152 this.tracks = tracks; 153 } 154 155 /** 156 * Returns the tracks set in {@link #setTracks(com.jme3.animation.Track[]) }. 157 * 158 * @return the tracks set previously 159 */ 160 public Track[] getTracks() { 161 return tracks; 162 } 163 164 /** 165 * This method creates a clone of the current object. 166 * @return a clone of the current object 167 */ 168 @Override 169 public Animation clone() { 170 try { 171 Animation result = (Animation) super.clone(); 172 result.tracks = tracks.clone(); 173 for (int i = 0; i < tracks.length; ++i) { 174 result.tracks[i] = this.tracks[i].clone(); 175 } 176 return result; 177 } catch (CloneNotSupportedException e) { 178 throw new AssertionError(); 179 } 180 } 181 182 @Override 183 public String toString() { 184 return getClass().getSimpleName() + "[name=" + name + ", length=" + length + ']'; 185 } 186 187 @Override 188 public void write(JmeExporter ex) throws IOException { 189 OutputCapsule out = ex.getCapsule(this); 190 out.write(name, "name", null); 191 out.write(length, "length", 0f); 192 out.write(tracks, "tracks", null); 193 } 194 195 @Override 196 public void read(JmeImporter im) throws IOException { 197 InputCapsule in = im.getCapsule(this); 198 name = in.readString("name", null); 199 length = in.readFloat("length", 0f); 200 201 Savable[] arr = in.readSavableArray("tracks", null); 202 tracks = new Track[arr.length]; 203 System.arraycopy(arr, 0, tracks, 0, arr.length); 204 } 205} 206