public class KeyFrameInterpolator extends Object implements Copyable
A KeyFrameInterpolator holds keyFrames (that define a path) and, optionally, a
reference to a Frame of your application (which will be interpolated). In this case,
when the user startInterpolation()
, the KeyFrameInterpolator regularly updates
the frame()
position, orientation and magnitude along the path.
Here is a typical utilization example (see also ProScene's FrameInterpolation and CameraInterpolation examples):
//init() should look like:
// The KeyFrameInterpolator kfi is given the Frame that it will drive over time.
myFrame = new Frame());
kfi = new KeyFrameInterpolator( myScene, myFrame );
// With an anonymous frame would look like this: kfi = new KeyFrameInterpolator( myScene );
kfi.addKeyFrame( new Frame( new Vec(1,0,0), new Quat() ) );
kfi.addKeyFrame( new Frame( new Vec(2,1,0), new Quat() ) );
// ...and so on for all the keyFrames.
kfi.startInterpolation();
//mainDrawingLoop() should look like:
scene.pushModelView();
kfi.frame().applyTransformation(this);
// Draw your object here. Its position, orientation and magnitude are interpolated.
scene.popModelView();
The keyFrames are defined by a Frame and a time, expressed in seconds. The time has to
be monotonously increasing over keyFrames. When interpolationSpeed()
equals
1.0 (default value), these times correspond to actual user's seconds during
interpolation (provided that your main loop is fast enough). The interpolation is then
real-time: the keyFrames will be reached at their keyFrameTime(int)
.
When the user startInterpolation()
, a timer is started which will update the
frame()
's position, orientation and magnitude every
interpolationPeriod()
milliseconds. This update increases the
interpolationTime()
by interpolationPeriod()
*
interpolationSpeed()
milliseconds.
Note that this mechanism ensures that the number of interpolation steps is constant and
equal to the total path duration()
divided by the
interpolationPeriod()
* interpolationSpeed()
. This is especially
useful for benchmarking or movie creation (constant number of snapshots).
The interpolation is stopped when interpolationTime()
is greater than the
lastTime()
(unless loopInterpolation() is true
).
Note that an Eye has Eye.keyFrameInterpolator(int)
,
that can be used to drive the Eye along a path.
Attention: If a Constraint is attached to the frame()
(see
Frame.constraint()
), it should be deactivated before
interpolationStarted()
, otherwise the interpolated motion (computed as if
there was no constraint) will probably be erroneous.
Constructor and Description |
---|
KeyFrameInterpolator(AbstractScene scn)
Convenience constructor that simply calls
this(scn, new Frame()) . |
KeyFrameInterpolator(AbstractScene scn,
Frame frame)
Creates a KeyFrameInterpolator, with
frame as associated frame() . |
Modifier and Type | Method and Description |
---|---|
void |
addKeyFrame(GenericFrame frame)
Appends a new keyFrame to the path.
|
void |
addKeyFrame(GenericFrame frame,
float time)
Appends a new keyFrame to the path, with its associated
time (in seconds). |
void |
deletePath()
Removes all keyFrames from the path.
|
float |
duration()
Returns the duration of the KeyFrameInterpolator path, expressed in seconds.
|
boolean |
equals(Object obj) |
float |
firstTime()
Returns the time corresponding to the first keyFrame, expressed in seconds.
|
Frame |
frame()
Returns the associated Frame that is interpolated by the KeyFrameInterpolator.
|
KeyFrameInterpolator |
get()
Returns a deep copy of the object.
|
int |
hashCode() |
void |
interpolateAtTime(float time)
Interpolate
frame() at time time (expressed in seconds). |
int |
interpolationPeriod()
Returns the current interpolation period, expressed in milliseconds.
|
float |
interpolationSpeed()
Returns the current interpolation speed.
|
boolean |
interpolationStarted()
Returns
true when the interpolation is being performed. |
float |
interpolationTime()
Returns the current interpolation time (in seconds) along the KeyFrameInterpolator
path.
|
GenericFrame |
keyFrame(int index)
Returns the Frame associated with the keyFrame at index
index . |
float |
keyFrameTime(int index)
Returns the time corresponding to the
index keyFrame. |
float |
lastTime()
Returns the time corresponding to the last keyFrame, expressed in seconds.
|
boolean |
loopInterpolation()
Returns
true when the interpolation is played in an infinite loop. |
int |
numberOfKeyFrames()
Returns the number of keyFrames used by the interpolation.
|
List<Frame> |
path()
Calls
updatePath() and then returns a list of Frames defining the
KeyFrameInterpolator path. |
void |
removeKeyFrame(int index)
|
void |
resetInterpolation()
Stops the interpolation and resets
interpolationTime() to the
firstTime() . |
AbstractScene |
scene()
Returns the scene this object belongs to
|
void |
setFrame(Frame f)
Sets the
frame() associated to the KeyFrameInterpolator. |
void |
setInterpolationPeriod(int myPeriod)
Sets the
interpolationPeriod() . |
void |
setInterpolationSpeed(float speed)
Sets the
interpolationSpeed() . |
void |
setInterpolationTime(float time)
Sets the
interpolationTime() . |
void |
setLoopInterpolation()
Convenience function that simply calls
setLoopInterpolation(true) . |
void |
setLoopInterpolation(boolean loop)
Sets the
loopInterpolation() value. |
void |
startInterpolation()
Convenience function that simply calls
startInterpolation(-1) . |
void |
startInterpolation(int myPeriod)
Starts the interpolation process.
|
void |
stopInterpolation()
Stops an interpolation started with
startInterpolation() . |
void |
toggleInterpolation()
|
public KeyFrameInterpolator(AbstractScene scn)
this(scn, new Frame())
.
Creates an anonymous frame()
to be interpolated by this
KeyFrameInterpolator.
public KeyFrameInterpolator(AbstractScene scn, Frame frame)
frame
as associated frame()
.
The frame()
can be set or changed using setFrame(Frame)
.
interpolationTime()
, interpolationSpeed()
and
interpolationPeriod()
are set to their default values.
public KeyFrameInterpolator get()
Copyable
Typical implementation should simple look like: return new Object(this)
.
public AbstractScene scene()
public Frame frame()
When interpolationStarted()
, this Frame's position, orientation and
magnitude will regularly be updated by a timer, so that they follow the
KeyFrameInterpolator path.
Set using setFrame(Frame)
or with the KeyFrameInterpolator constructor.
public int numberOfKeyFrames()
addKeyFrame(GenericFrame)
to add new keyFrames.public float interpolationTime()
This time is regularly updated when interpolationStarted()
. Can be set
directly with setInterpolationTime(float)
or
interpolateAtTime(float)
.
public float interpolationSpeed()
Default value is 1.0f, which means keyFrameTime(int)
will be matched during
the interpolation (provided that your main loop is fast enough).
A negative value will result in a reverse interpolation of the keyFrames.
interpolationPeriod()
public int interpolationPeriod()
frame()
state will be done by a timer at this period when
interpolationStarted()
.
This period (multiplied by interpolationSpeed()
) is added to the
interpolationTime()
at each update, and the frame()
state is
modified accordingly (see interpolateAtTime(float)
). Default value is 40
milliseconds.
setInterpolationPeriod(int)
public boolean loopInterpolation()
true
when the interpolation is played in an infinite loop.
When false
(default), the interpolation stops when
interpolationTime()
reaches firstTime()
(with negative
interpolationSpeed()
) or lastTime()
.
interpolationTime()
is otherwise reset to firstTime()
(+
interpolationTime()
- lastTime()
) (and inversely for negative
interpolationSpeed()
) and interpolation continues.
public void setInterpolationTime(float time)
interpolationTime()
.
Attention: The frame()
state is not affected by this method. Use this
function to define the starting time of a future interpolation (see
startInterpolation()
). Use interpolateAtTime(float)
to actually
interpolate at a given time.
public void setInterpolationSpeed(float speed)
interpolationSpeed()
. Negative or null values are allowed.public void setInterpolationPeriod(int myPeriod)
interpolationPeriod()
. Should positive.public void setLoopInterpolation()
setLoopInterpolation(true)
.public void setLoopInterpolation(boolean loop)
loopInterpolation()
value.public boolean interpolationStarted()
true
when the interpolation is being performed. Use
startInterpolation()
, stopInterpolation()
or
toggleInterpolation()
to modify this state.public void toggleInterpolation()
public void startInterpolation()
startInterpolation(-1)
.startInterpolation(int)
public void startInterpolation(int myPeriod)
A timer is started with an interpolationPeriod()
period that updates the
frame()
's position, orientation and magnitude.
interpolationStarted()
will return true
until
stopInterpolation()
or toggleInterpolation()
is called.
If period
is positive, it is set as the new interpolationPeriod()
.
The previous interpolationPeriod()
is used otherwise (default).
If interpolationTime()
is larger than lastTime()
,
interpolationTime()
is reset to firstTime()
before interpolation
starts (and inversely for negative interpolationSpeed()
.
Use setInterpolationTime(float)
before calling this method to change the
starting interpolationTime()
.
Attention: The keyFrames must be defined (see
addKeyFrame(GenericFrame, float)
) before you startInterpolation(), or else
the interpolation will naturally immediately stop.
public void stopInterpolation()
startInterpolation()
. See
interpolationStarted()
and toggleInterpolation()
.public void resetInterpolation()
interpolationTime()
to the
firstTime()
.
If desired, call interpolateAtTime(float)
after this method to actually move
the frame()
to firstTime()
.
public void addKeyFrame(GenericFrame frame)
Same as addKeyFrame(GenericFrame, float)
, except that the
keyFrameTime(int)
is set to the previous keyFrameTime(int)
plus one
second (or 0.0 if there is no previous keyFrame).
public void addKeyFrame(GenericFrame frame, float time)
time
(in seconds).
When setRef
is false
the keyFrame is added by value, meaning that the
path will use the current frame
state.
When setRef
is true
the keyFrame is given as a reference to a Frame,
which will be connected to the KeyFrameInterpolator: when frame
is modified,
the KeyFrameInterpolator path is updated accordingly. This allows for dynamic paths,
where keyFrame can be edited, even during the interpolation. null
frame
references are silently ignored. The keyFrameTime(int)
has to be
monotonously increasing over keyFrames.
public void removeKeyFrame(int index)
index
in the list and
stopInterpolation()
if interpolationStarted()
. If
index < 0 || index >= keyFr.size()
the call is silently ignored.public void deletePath()
numberOfKeyFrames()
is set to 0.public List<Frame> path()
updatePath()
and then returns a list of Frames defining the
KeyFrameInterpolator path.
Use it in your KeyFrameInterpolator path drawing routine.
public GenericFrame keyFrame(int index)
index
.
See also keyFrameTime(int)
. index
has to be in the range 0..
numberOfKeyFrames()
-1.
Note: If this keyFrame was defined using a reference to a Frame (see
addKeyFrame(GenericFrame, float)
the current referenced Frame state is
returned.
public float keyFrameTime(int index)
index
keyFrame. index has to be in the
range 0.. numberOfKeyFrames()
-1.keyFrame(int)
public float duration()
Simply corresponds to lastTime()
- firstTime()
. Returns 0.0 if the
path has less than 2 keyFrames.
keyFrameTime(int)
public float firstTime()
Returns 0.0 if the path is empty.
lastTime()
,
duration()
,
keyFrameTime(int)
public float lastTime()
firstTime()
,
duration()
,
keyFrameTime(int)
public void interpolateAtTime(float time)
frame()
at time time
(expressed in seconds).
interpolationTime()
is set to time
and frame()
is set
accordingly.
If you simply want to change interpolationTime()
but not the
frame()
state, use setInterpolationTime(float)
instead.
Processing Library proscene by Jean Pierre Charalambos. (c) 2014-2017 National University of Colombia