Okay,
@pspeed I came up with new design in 2nd iteration , I am taking similar approach to the SpatialTweens you made.
For example AudioTween:
Initial implementation of AudioTweens :
public class AudioTweens {
public static Tween play(AudioNode audioNode, boolean instanced, double length) {
return new PlayAudio(audioNode, instanced, length);
}
public static Tween syncSpeed(AudioNode audioNode, PositionAdapter pa, double baseSpeed, double length) {
return new SyncSpeed(audioNode, pa, baseSpeed, length);
}
public static Tween syncVolume(AudioNode audioNode, PositionAdapter pa, double baseSpeed, double length) {
return new SyncVolume(audioNode, pa, baseSpeed, length);
}
private static class PlayAudio extends AbstractTween {
private final AudioNode audioNode;
private final boolean instanced;
public PlayAudio(AudioNode audioNode, boolean instanced, double length) {
super(length);
this.audioNode = audioNode;
this.instanced = instanced;
}
@Override
protected void doInterpolate(double t) {
if (audioNode.getStatus() != AudioSource.Status.Playing) {
if (instanced) {
audioNode.playInstance();
} else {
audioNode.play();
}
}
if (t == 1) {
// Done
audioNode.pause();
}
}
}
private static class SyncSpeed extends AbstractTween {
private final AudioNode audioNode;
private final PositionAdapter pa;
private final double baseSpeed;
private final Filterd lowPass = new SimpleMovingMean(10); // 1/6th second of data
public SyncSpeed(AudioNode audioNode, PositionAdapter pa, double baseSpeed, double length) {
super(length);
this.audioNode = audioNode;
this.pa = pa;
this.baseSpeed = baseSpeed;
}
@Override
protected void doInterpolate(double t) {
float forward = pa.getOrientation().mult(Vector3f.UNIT_Z).dot(pa.getVelocity());
double pitch = forward / baseSpeed;
// Pass the pitch through a low-pass filter using
// a moving average
lowPass.addValue(pitch);
pitch = lowPass.getFilteredValue();
pitch = Math.round(pitch * 10) / 10.0;
pitch = FastMath.clamp((float) pitch, 0.5f, 2.0f);
if (pitch != audioNode.getPitch()) {
audioNode.setPitch((float) pitch);
}
}
}
private static class SyncVolume extends AbstractTween {
private final AudioNode audioNode;
private final PositionAdapter pa;
private final double baseSpeed;
public SyncVolume(AudioNode audioNode, PositionAdapter pa, double baseSpeed, double length) {
super(length);
this.audioNode = audioNode;
this.pa = pa;
this.baseSpeed = baseSpeed;
}
@Override
protected void doInterpolate(double t) {
//TODO: implement when needed!
}
}
}
I will add similar one for AnimTweens.
public class AnimTweens {
public static Action action(AnimComposer ac, String name) {
return ac.action(name);
}
public static BaseAction actionSequence(AnimComposer ac, String name, Tween... tweens) {
return ac.actionSequence(name, tweens);
}
public static BlendAction actionBlended(AnimComposer ac, String name, BlendSpace blendSpace, String... clips) {
return ac.actionBlended(name, blendSpace, clips);
}
public static Tween blendAnim(PositionAdapter pa, BlendSpace blendSpace, double baseSpeed, double length) {
return new BlendAnim(pa, blendSpace, baseSpeed, length);
}
public static Tween syncSpeed(PositionAdapter pa, Action action, double baseSpeed, double length) {
return new SyncSpeed(pa, action, baseSpeed, length);
}
private static class BlendAnim extends AbstractTween {
private final PositionAdapter pa;
private final BlendSpace blendSpace;
private final double baseSpeed;
public BlendAnim(PositionAdapter pa, BlendSpace blendSpace, double baseSpeed, double length) {
super(length);
this.pa = pa;
this.blendSpace = blendSpace;
this.baseSpeed = baseSpeed;
}
@Override
protected void doInterpolate(double t) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
private static class SyncSpeed extends AbstractTween {
private final PositionAdapter pa;
private final Action action;
private final double baseSpeed;
public SyncSpeed(PositionAdapter pa, Action action, double baseSpeed, double length) {
super(length);
this.pa = pa;
this.action = action;
this.baseSpeed = baseSpeed;
}
@Override
protected void doInterpolate(double t) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
}
Then next step would be to hook them to my TweenEditor.
Looking forward to hear your idea about new approach.