package org.mt4j.input.gestureAction;
import org.mt4j.components.MTComponent;
import org.mt4j.components.interfaces.IMTComponent3D;
import org.mt4j.components.interfaces.IMTController;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent;
import org.mt4j.util.math.Vector3D;
public class InertiaDragAction implements IGestureEventListener {
private float limit;
private float damping;
private int integrationTime;
public InertiaDragAction(){
this(120, 0.85f, 17);
// this(120, 0.85f, 100);
}
public InertiaDragAction(int integrationTime, float damping, float maxVelocityLength){
this.integrationTime = integrationTime;
this.limit = maxVelocityLength;
this.damping = damping;
}
public boolean processGestureEvent(MTGestureEvent ge) {
IMTComponent3D t = ge.getTargetComponent();
if (t instanceof MTComponent) {
MTComponent comp = (MTComponent) t;
DragEvent de = (DragEvent)ge;
IMTController oldController;
switch (de.getId()) {
case DragEvent.GESTURE_DETECTED:
break;
case DragEvent.GESTURE_UPDATED:
break;
case DragEvent.GESTURE_ENDED:
Vector3D vel = de.getDragCursor().getVelocityVector(integrationTime);
vel.scaleLocal(0.9f); //Test - integrate over longer time but scale down velocity vec
vel = vel.getLimited(limit);
oldController = comp.getController();
comp.setController(new InertiaController(comp, vel, oldController));
break;
default:
break;
}
}
return false;
}
private class InertiaController implements IMTController{
private MTComponent target;
private Vector3D startVelocityVec;
// private float dampingValue = 0.90f;
// private float dampingValue = 0.80f;
// private float dampingValue = 0.45f;
private IMTController oldController;
//TODO use animation instead and ease out?
private int animationTime = 1000;
private int currentAnimationTime = 0;
private float movePerMilli;
private Vector3D moveVectNorm;
private Vector3D moveVect;
public InertiaController(MTComponent target, Vector3D startVelocityVec, IMTController oldController) {
super();
this.target = target;
this.startVelocityVec = startVelocityVec;
this.oldController = oldController;
//Animation inertiaAnim = new Animation("Inertia anim for " + target, new MultiPurposeInterpolator(startVelocityVec.length(), 0, 100, 0.0f, 0.5f, 1), target);
/*
currentAnimationTime = 0;
movePerMilli = startVelocityVec.length()/animationTime;
moveVectNorm = startVelocityVec.getNormalized();
moveVect = new Vector3D();
*/
}
//TODO ? inertia animation is frame based, not time - so framerate decides how long it goes..
////@Override
public void update(long timeDelta) {
/*
currentAnimationTime += timeDelta;
if (currentAnimationTime < animationTime){
moveVect.setValues(moveVectNorm);
moveVect.scaleLocal(timeDelta * movePerMilli);
target.translateGlobal(moveVect);
}else{
target.setController(oldController);
return;
}
*/
// /*
if (Math.abs(startVelocityVec.x) < 0.05f && Math.abs(startVelocityVec.y) < 0.05f){
startVelocityVec.setValues(Vector3D.ZERO_VECTOR);
target.setController(oldController);
return;
}
startVelocityVec.scaleLocal(damping);
target.translateGlobal(startVelocityVec);
// */
if (oldController != null){
oldController.update(timeDelta);
}
}
}
}