package org.mt4j.input.gestureAction;
import org.mt4j.components.MTComponent;
import org.mt4j.components.TransformSpace;
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;
/**
* The Class InertiaDragAction.
*/
public class InertiaDragAction implements IGestureEventListener {
/** The limit. */
private float limit;
/** The damping. */
private float damping;
/** The integration time. */
private int integrationTime;
/**
* Instantiates a new inertia drag action.
*/
public InertiaDragAction(){
this(125, 0.85f, 25);
// this(120, 0.85f, 100);
}
/**
* Instantiates a new inertia drag action.
*
* @param integrationTime the integration time
* @param damping the damping
* @param maxVelocityLength the max velocity length
*/
public InertiaDragAction(int integrationTime, float damping, float maxVelocityLength){
this.integrationTime = integrationTime;
this.limit = maxVelocityLength;
this.damping = damping;
}
/* (non-Javadoc)
* @see org.mt4j.input.inputProcessors.IGestureEventListener#processGestureEvent(org.mt4j.input.inputProcessors.MTGestureEvent)
*/
public boolean processGestureEvent(MTGestureEvent ge) {
IMTComponent3D t = ge.getTarget();
if (t instanceof MTComponent) {
MTComponent comp = (MTComponent) t;
DragEvent de = (DragEvent)ge;
IMTController oldController;
switch (de.getId()) {
case DragEvent.GESTURE_STARTED:
break;
case DragEvent.GESTURE_RESUMED:
break;
case DragEvent.GESTURE_UPDATED:
break;
case DragEvent.GESTURE_CANCELED:
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;
}
/**
* The Class InertiaController.
*/
private class InertiaController implements IMTController{
/** The target. */
private MTComponent target;
/** The start velocity vec. */
private Vector3D startVelocityVec;
// private float dampingValue = 0.90f;
// private float dampingValue = 0.80f;
// private float dampingValue = 0.45f;
/** The old controller. */
private IMTController oldController;
//TODO use animation instead and ease out?
/** The animation time. */
private int animationTime = 1000;
/** The current animation time. */
private int currentAnimationTime = 0;
/** The move per milli. */
private float movePerMilli;
/** The move vect norm. */
private Vector3D moveVectNorm;
/** The move vect. */
private Vector3D moveVect;
/**
* Instantiates a new inertia controller.
*
* @param target the target
* @param startVelocityVec the start velocity vec
* @param oldController the old controller
*/
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
/* (non-Javadoc)
* @see org.mt4j.components.interfaces.IMTController#update(long)
*/
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);
Vector3D vec = new Vector3D(startVelocityVec);
vec.transformDirectionVector(target.getGlobalInverseMatrix()); //Transform direction vector into component local coordinates
target.translate(vec,TransformSpace.LOCAL);
// target.translateGlobal(startVelocityVec);
// */
if (oldController != null){
oldController.update(timeDelta);
}
}
}
}