• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 jme3test.animation;
33 
34 import com.jme3.animation.AnimControl;
35 import com.jme3.animation.AnimationFactory;
36 import com.jme3.animation.LoopMode;
37 import com.jme3.app.SimpleApplication;
38 import com.jme3.cinematic.Cinematic;
39 import com.jme3.cinematic.MotionPath;
40 import com.jme3.cinematic.PlayState;
41 import com.jme3.cinematic.events.*;
42 import com.jme3.font.BitmapText;
43 import com.jme3.input.ChaseCamera;
44 import com.jme3.input.controls.ActionListener;
45 import com.jme3.input.controls.KeyTrigger;
46 import com.jme3.light.DirectionalLight;
47 import com.jme3.material.Material;
48 import com.jme3.math.ColorRGBA;
49 import com.jme3.math.FastMath;
50 import com.jme3.math.Quaternion;
51 import com.jme3.math.Vector3f;
52 import com.jme3.niftygui.NiftyJmeDisplay;
53 import com.jme3.post.FilterPostProcessor;
54 import com.jme3.post.filters.FadeFilter;
55 import com.jme3.renderer.Caps;
56 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
57 import com.jme3.scene.CameraNode;
58 import com.jme3.scene.Geometry;
59 import com.jme3.scene.Spatial;
60 import com.jme3.scene.shape.Box;
61 import com.jme3.shadow.PssmShadowRenderer;
62 import de.lessvoid.nifty.Nifty;
63 
64 public class TestCinematic extends SimpleApplication {
65 
66     private Spatial model;
67     private Spatial teapot;
68     private MotionPath path;
69     private MotionTrack cameraMotionTrack;
70     private Cinematic cinematic;
71     private ChaseCamera chaseCam;
72     private FilterPostProcessor fpp;
73     private FadeFilter fade;
74     private float time = 0;
75 
main(String[] args)76     public static void main(String[] args) {
77         TestCinematic app = new TestCinematic();
78         app.start();
79 
80 
81 
82     }
83 
84     @Override
simpleInitApp()85     public void simpleInitApp() {
86         //just some text
87         NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(getAssetManager(),
88                 getInputManager(),
89                 getAudioRenderer(),
90                 getGuiViewPort());
91         Nifty nifty;
92         nifty = niftyDisplay.getNifty();
93         nifty.fromXmlWithoutStartScreen("Interface/Nifty/CinematicTest.xml");
94         getGuiViewPort().addProcessor(niftyDisplay);
95         guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
96         final BitmapText text = new BitmapText(guiFont, false);
97         text.setSize(guiFont.getCharSet().getRenderedSize());
98         text.setText("Press enter to play/pause cinematic");
99         text.setLocalTranslation((cam.getWidth() - text.getLineWidth()) / 2, cam.getHeight(), 0);
100         guiNode.attachChild(text);
101 
102 
103         createScene();
104 
105         cinematic = new Cinematic(rootNode, 20);
106         stateManager.attach(cinematic);
107 
108         createCameraMotion();
109 
110         //creating spatial animation for the teapot
111         AnimationFactory factory = new AnimationFactory(20, "teapotAnim");
112         factory.addTimeTranslation(0, new Vector3f(10, 0, 10));
113         factory.addTimeTranslation(20, new Vector3f(10, 0, -10));
114         factory.addTimeScale(10, new Vector3f(4, 4, 4));
115         factory.addTimeScale(20, new Vector3f(1, 1, 1));
116         factory.addTimeRotationAngles(20, 0, 4 * FastMath.TWO_PI, 0);
117         AnimControl control = new AnimControl();
118         control.addAnim(factory.buildAnimation());
119         teapot.addControl(control);
120 
121         //fade in
122         cinematic.addCinematicEvent(0, new FadeEvent(true));
123        // cinematic.activateCamera(0, "aroundCam");
124         cinematic.addCinematicEvent(0, new AnimationTrack(teapot, "teapotAnim", LoopMode.DontLoop));
125         cinematic.addCinematicEvent(0, cameraMotionTrack);
126         cinematic.addCinematicEvent(0, new SoundTrack("Sound/Environment/Nature.ogg", LoopMode.Loop));
127         cinematic.addCinematicEvent(3f, new SoundTrack("Sound/Effects/kick.wav"));
128         cinematic.addCinematicEvent(3, new SubtitleTrack(nifty, "start", 3, "jMonkey engine really kicks A..."));
129         cinematic.addCinematicEvent(5.1f, new SoundTrack("Sound/Effects/Beep.ogg", 1));
130         cinematic.addCinematicEvent(2, new AnimationTrack(model, "Walk", LoopMode.Loop));
131         cinematic.activateCamera(0, "topView");
132       //  cinematic.activateCamera(10, "aroundCam");
133 
134         //fade out
135         cinematic.addCinematicEvent(19, new FadeEvent(false));
136 //        cinematic.addCinematicEvent(19, new AbstractCinematicEvent() {
137 //
138 //            @Override
139 //            public void onPlay() {
140 //                fade.setDuration(1f / cinematic.getSpeed());
141 //                fade.fadeOut();
142 //
143 //            }
144 //
145 //            @Override
146 //            public void onUpdate(float tpf) {
147 //            }
148 //
149 //            @Override
150 //            public void onStop() {
151 //            }
152 //
153 //            @Override
154 //            public void onPause() {
155 //            }
156 //        });
157 
158         cinematic.addListener(new CinematicEventListener() {
159 
160             public void onPlay(CinematicEvent cinematic) {
161                 chaseCam.setEnabled(false);
162                 System.out.println("play");
163             }
164 
165             public void onPause(CinematicEvent cinematic) {
166                 System.out.println("pause");
167             }
168 
169             public void onStop(CinematicEvent cinematic) {
170                 chaseCam.setEnabled(true);
171                 fade.setValue(1);
172                 System.out.println("stop");
173             }
174         });
175 
176         //cinematic.setSpeed(2);
177         flyCam.setEnabled(false);
178         chaseCam = new ChaseCamera(cam, model, inputManager);
179         initInputs();
180 
181     }
182 
createCameraMotion()183     private void createCameraMotion() {
184 
185         CameraNode camNode = cinematic.bindCamera("topView", cam);
186         camNode.setLocalTranslation(new Vector3f(0, 50, 0));
187         camNode.lookAt(teapot.getLocalTranslation(), Vector3f.UNIT_Y);
188 
189         CameraNode camNode2 = cinematic.bindCamera("aroundCam", cam);
190         path = new MotionPath();
191         path.setCycle(true);
192         path.addWayPoint(new Vector3f(20, 3, 0));
193         path.addWayPoint(new Vector3f(0, 3, 20));
194         path.addWayPoint(new Vector3f(-20, 3, 0));
195         path.addWayPoint(new Vector3f(0, 3, -20));
196         path.setCurveTension(0.83f);
197         cameraMotionTrack = new MotionTrack(camNode2, path);
198         cameraMotionTrack.setLoopMode(LoopMode.Loop);
199         cameraMotionTrack.setLookAt(model.getWorldTranslation(), Vector3f.UNIT_Y);
200         cameraMotionTrack.setDirectionType(MotionTrack.Direction.LookAt);
201 
202     }
203 
createScene()204     private void createScene() {
205 
206         model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
207         model.center();
208         model.setShadowMode(ShadowMode.CastAndReceive);
209         rootNode.attachChild(model);
210 
211         Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
212         mat.setColor("Color", ColorRGBA.Cyan);
213 
214         teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
215         teapot.setLocalTranslation(10, 0, 10);
216         teapot.setMaterial(mat);
217         teapot.setShadowMode(ShadowMode.CastAndReceive);
218         rootNode.attachChild(teapot);
219 
220         Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
221         matSoil.setBoolean("UseMaterialColors", true);
222         matSoil.setColor("Ambient", ColorRGBA.Gray);
223         matSoil.setColor("Diffuse", ColorRGBA.Green);
224         matSoil.setColor("Specular", ColorRGBA.Black);
225 
226         Geometry soil = new Geometry("soil", new Box(new Vector3f(0, -6.0f, 0), 50, 1, 50));
227         soil.setMaterial(matSoil);
228         soil.setShadowMode(ShadowMode.Receive);
229         rootNode.attachChild(soil);
230         DirectionalLight light = new DirectionalLight();
231         light.setDirection(new Vector3f(0, -1, -1).normalizeLocal());
232         light.setColor(ColorRGBA.White.mult(1.5f));
233         rootNode.addLight(light);
234 
235         fpp = new FilterPostProcessor(assetManager);
236         fade = new FadeFilter();
237         fpp.addFilter(fade);
238 
239         if (renderer.getCaps().contains(Caps.GLSL100)) {
240             PssmShadowRenderer pssm = new PssmShadowRenderer(assetManager, 512, 1);
241             pssm.setDirection(new Vector3f(0, -1, -1).normalizeLocal());
242             pssm.setShadowIntensity(0.4f);
243             viewPort.addProcessor(pssm);
244             viewPort.addProcessor(fpp);
245         }
246     }
247 
initInputs()248     private void initInputs() {
249         inputManager.addMapping("togglePause", new KeyTrigger(keyInput.KEY_RETURN));
250         inputManager.addMapping("navFwd", new KeyTrigger(keyInput.KEY_RIGHT));
251         inputManager.addMapping("navBack", new KeyTrigger(keyInput.KEY_LEFT));
252         ActionListener acl = new ActionListener() {
253 
254             public void onAction(String name, boolean keyPressed, float tpf) {
255                 if (name.equals("togglePause") && keyPressed) {
256                     if (cinematic.getPlayState() == PlayState.Playing) {
257                         cinematic.pause();
258                         time = cinematic.getTime();
259                     } else {
260                         cinematic.play();
261                     }
262                 }
263 
264                 if (cinematic.getPlayState() != PlayState.Playing) {
265                     if (name.equals("navFwd") && keyPressed) {
266                         time += 0.25;
267                         FastMath.clamp(time, 0, cinematic.getInitialDuration());
268                         cinematic.setTime(time);
269                     }
270                     if (name.equals("navBack") && keyPressed) {
271                         time -= 0.25;
272                         FastMath.clamp(time, 0, cinematic.getInitialDuration());
273                         cinematic.setTime(time);
274                     }
275 
276                 }
277             }
278         };
279         inputManager.addListener(acl, "togglePause", "navFwd", "navBack");
280     }
281 
282     private class FadeEvent extends AbstractCinematicEvent {
283 
284         boolean in = true;
285         float value = 0;
286 
FadeEvent(boolean in)287         public FadeEvent(boolean in) {
288             super(1);
289             this.in = in;
290             value = in ? 0 : 1;
291         }
292 
293         @Override
onPlay()294         public void onPlay() {
295 
296             fade.setDuration(1f / cinematic.getSpeed());
297             if (in) {
298                 fade.fadeIn();
299             } else {
300                 fade.fadeOut();
301             }
302             fade.setValue(value);
303 
304         }
305 
306         @Override
setTime(float time)307         public void setTime(float time) {
308             super.setTime(time);
309             if (time >= fade.getDuration()) {
310                 value = in ? 1 : 0;
311                 fade.setValue(value);
312             } else {
313                 value = time;
314                 if (in) {
315                     fade.setValue(time / cinematic.getSpeed());
316                 } else {
317                     fade.setValue(1 - time / cinematic.getSpeed());
318                 }
319             }
320         }
321 
322         @Override
onUpdate(float tpf)323         public void onUpdate(float tpf) {
324         }
325 
326         @Override
onStop()327         public void onStop() {
328         }
329 
330         @Override
onPause()331         public void onPause() {
332             value = fade.getValue();
333             fade.pause();
334         }
335     }
336 }
337