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 package com.jme3.cinematic.events;
33 
34 import com.jme3.animation.AnimChannel;
35 import com.jme3.animation.AnimControl;
36 import com.jme3.animation.LoopMode;
37 import com.jme3.app.Application;
38 import com.jme3.cinematic.Cinematic;
39 import com.jme3.cinematic.PlayState;
40 import com.jme3.export.InputCapsule;
41 import com.jme3.export.JmeExporter;
42 import com.jme3.export.JmeImporter;
43 import com.jme3.export.OutputCapsule;
44 import com.jme3.scene.Spatial;
45 import java.io.IOException;
46 import java.util.logging.Level;
47 import java.util.logging.Logger;
48 
49 /**
50  *
51  * @author Nehon
52  */
53 public class AnimationTrack extends AbstractCinematicEvent {
54 
55     private static final Logger log = Logger.getLogger(AnimationTrack.class.getName());
56     protected AnimChannel channel;
57     protected String animationName;
58     protected String modelName;
59 
AnimationTrack()60     public AnimationTrack() {
61     }
62 
AnimationTrack(Spatial model, String animationName)63     public AnimationTrack(Spatial model, String animationName) {
64         modelName = model.getName();
65         this.animationName = animationName;
66         initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
67     }
68 
AnimationTrack(Spatial model, String animationName, float initialDuration)69     public AnimationTrack(Spatial model, String animationName, float initialDuration) {
70         super(initialDuration);
71         modelName = model.getName();
72         this.animationName = animationName;
73     }
74 
AnimationTrack(Spatial model, String animationName, LoopMode loopMode)75     public AnimationTrack(Spatial model, String animationName, LoopMode loopMode) {
76         super(loopMode);
77         initialDuration = model.getControl(AnimControl.class).getAnimationLength(animationName);
78         modelName = model.getName();
79         this.animationName = animationName;
80     }
81 
AnimationTrack(Spatial model, String animationName, float initialDuration, LoopMode loopMode)82     public AnimationTrack(Spatial model, String animationName, float initialDuration, LoopMode loopMode) {
83         super(initialDuration, loopMode);
84         modelName = model.getName();
85         this.animationName = animationName;
86     }
87 
88     @Override
initEvent(Application app, Cinematic cinematic)89     public void initEvent(Application app, Cinematic cinematic) {
90         super.initEvent(app, cinematic);
91         if (channel == null) {
92             Object s = cinematic.getEventData("modelChannels", modelName);
93             if (s != null && s instanceof AnimChannel) {
94                 this.channel = (AnimChannel) s;
95             } else if (s == null) {
96                 Spatial model = cinematic.getScene().getChild(modelName);
97                 if (model != null) {
98                     channel = model.getControl(AnimControl.class).createChannel();
99                     cinematic.putEventData("modelChannels", modelName, channel);
100                 } else {
101                     log.log(Level.WARNING, "spatial {0} not found in the scene, cannot perform animation", modelName);
102                 }
103             }
104 
105         }
106     }
107 
108     @Override
setTime(float time)109     public void setTime(float time) {
110         super.setTime(time);
111         float t = time;
112         if(loopMode == loopMode.Loop){
113             t = t % channel.getAnimMaxTime();
114         }
115         if(loopMode == loopMode.Cycle){
116             float parity = (float)Math.ceil(time / channel.getAnimMaxTime());
117             if(parity >0 && parity%2 ==0){
118                 t = channel.getAnimMaxTime() - t % channel.getAnimMaxTime();
119             }else{
120                 t = t % channel.getAnimMaxTime();
121             }
122 
123         }
124         channel.setTime(t);
125         channel.getControl().update(0);
126     }
127 
128     @Override
onPlay()129     public void onPlay() {
130         channel.getControl().setEnabled(true);
131         if (playState == PlayState.Stopped) {
132             channel.setAnim(animationName);
133             channel.setSpeed(speed);
134             channel.setLoopMode(loopMode);
135             channel.setTime(time);
136         }
137     }
138 
139     @Override
onUpdate(float tpf)140     public void onUpdate(float tpf) {
141     }
142 
143     @Override
onStop()144     public void onStop() {
145         channel.getControl().setEnabled(false);
146         channel.setTime(0);
147     }
148 
149     @Override
onPause()150     public void onPause() {
151         channel.getControl().setEnabled(false);
152     }
153 
154     @Override
setLoopMode(LoopMode loopMode)155     public void setLoopMode(LoopMode loopMode) {
156         super.setLoopMode(loopMode);
157         channel.setLoopMode(loopMode);
158     }
159 
160     @Override
write(JmeExporter ex)161     public void write(JmeExporter ex) throws IOException {
162         super.write(ex);
163         OutputCapsule oc = ex.getCapsule(this);
164         oc.write(modelName, "modelName", "");
165         oc.write(animationName, "animationName", "");
166     }
167 
168     @Override
read(JmeImporter im)169     public void read(JmeImporter im) throws IOException {
170         super.read(im);
171         InputCapsule ic = im.getCapsule(this);
172         modelName = ic.readString("modelName", "");
173         animationName = ic.readString("animationName", "");
174     }
175 }
176