2 * Copyright (c) 2003-2009 jMonkeyEngine
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
33 package com.jme.curve;
35 import java.io.IOException;
37 import com.jme.math.Vector3f;
38 import com.jme.scene.Controller;
39 import com.jme.scene.Spatial;
40 import com.jme.util.export.InputCapsule;
41 import com.jme.util.export.JMEExporter;
42 import com.jme.util.export.JMEImporter;
43 import com.jme.util.export.OutputCapsule;
46 * <code>CurveController</code> defines a controller that moves a supplied
47 * <code>Spatial</code> object along a curve. Attributes of the curve are set
48 * such as the up vector (if not set, the spacial object will roll along the
49 * curve), the orientation precision defines how accurate the orientation of the
52 * @version $Id: CurveController.java,v 1.14 2007/02/04 14:37:56 sunsett Exp $
54 public class CurveController extends Controller {
55 private static final long serialVersionUID = 1L;
56 private Spatial mover;
59 private float orientationPrecision = 0.1f;
60 private float currentTime = 0.0f;
61 private float deltaTime = 0.0f;
63 private boolean cycleForward = true;
64 private boolean autoRotation = false;
67 * Constructor instantiates a new <code>CurveController</code> object.
68 * The curve object that the controller operates on and the spatial object
69 * that is moved is specified during construction.
70 * @param curve the curve to operate on.
71 * @param mover the spatial to move.
73 public CurveController(Curve curve, Spatial mover) {
76 setUpVector(new Vector3f(0,1,0));
78 setMaxTime(Float.MAX_VALUE);
79 setRepeatType(Controller.RT_CLAMP);
84 * Constructor instantiates a new <code>CurveController</code> object.
85 * The curve object that the controller operates on and the spatial object
86 * that is moved is specified during construction. The game time to
87 * start and the game time to finish is also supplied.
88 * @param curve the curve to operate on.
89 * @param mover the spatial to move.
90 * @param minTime the time to start the controller.
91 * @param maxTime the time to end the controller.
93 public CurveController(
102 setRepeatType(Controller.RT_CLAMP);
107 * <code>setUpVector</code> sets the locking vector for the spatials up
108 * vector. This prevents rolling along the curve and allows for a better
110 * @param up the vector to lock as the spatials up vector.
112 public void setUpVector(Vector3f up) {
118 * <code>setOrientationPrecision</code> sets a precision value for the
119 * spatials orientation. The smaller the number the higher the precision.
120 * By default 0.1 is used, and typically does not require changing.
121 * @param value the precision value of the spatial's orientation.
123 public void setOrientationPrecision(float value) {
124 orientationPrecision = value;
129 * <code>setAutoRotation</code> determines if the object assigned to
130 * the controller will rotate with the curve or just following the
132 * @param value true if the object is to rotate with the curve, false
135 public void setAutoRotation(boolean value) {
136 autoRotation = value;
141 * <code>isAutoRotating</code> returns true if the object is rotating with
142 * the curve and false if it is not.
143 * @return true if the object is following the curve, false otherwise.
145 public boolean isAutoRotating() {
150 * <code>update</code> moves a spatial along the given curve for along a
152 * @see com.jme.scene.Controller#update(float)
154 public void update(float time) {
155 if(mover == null || curve == null || up == null) {
158 currentTime += time * getSpeed();
160 if (currentTime >= getMinTime() && currentTime <= getMaxTime()) {
162 if (getRepeatType() == RT_CLAMP) {
163 deltaTime = currentTime - getMinTime();
164 mover.setLocalTranslation(curve.getPoint(deltaTime,mover.getLocalTranslation()));
166 mover.setLocalRotation(
167 curve.getOrientation(
169 orientationPrecision,
172 } else if (getRepeatType() == RT_WRAP) {
173 deltaTime = (currentTime - getMinTime()) % 1.0f;
178 mover.setLocalTranslation(curve.getPoint(deltaTime,mover.getLocalTranslation()));
180 mover.setLocalRotation(
181 curve.getOrientation(
183 orientationPrecision,
186 } else if (getRepeatType() == RT_CYCLE) {
187 float prevTime = deltaTime;
188 deltaTime = (currentTime - getMinTime()) % 1.0f;
189 if (prevTime > deltaTime) {
190 cycleForward = !cycleForward;
194 mover.setLocalTranslation(curve.getPoint(deltaTime,mover.getLocalTranslation()));
196 mover.setLocalRotation(
197 curve.getOrientation(
199 orientationPrecision,
203 mover.setLocalTranslation(
204 curve.getPoint(1.0f - deltaTime,mover.getLocalTranslation()));
206 mover.setLocalRotation(
207 curve.getOrientation(
209 orientationPrecision,
219 public void reset() {
220 this.currentTime = 0;
223 public void write(JMEExporter e) throws IOException {
225 OutputCapsule capsule = e.getCapsule(this);
226 capsule.write(mover, "mover", null);
227 capsule.write(curve, "Curve", null);
228 capsule.write(up, "up", null);
229 capsule.write(orientationPrecision, "orientationPrecision", 0.1f);
230 capsule.write(cycleForward, "cycleForward", true);
231 capsule.write(autoRotation, "autoRotation", false);
234 public void read(JMEImporter e) throws IOException {
236 InputCapsule capsule = e.getCapsule(this);
238 mover = (Spatial)capsule.readSavable("mover", null);
239 curve = (Curve)capsule.readSavable("curve", null);
240 up = (Vector3f)capsule.readSavable("up", null);
241 orientationPrecision = capsule.readFloat("orientationPrecision", 0.1f);
242 cycleForward = capsule.readBoolean("cycleForward", true);
243 autoRotation = capsule.readBoolean("autoRotation", false);