/*********************************************************************** * mt4j Copyright (c) 2008 - 2009 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * ***********************************************************************/ package org.mt4j.input.inputProcessors.componentProcessors.dragProcessor; import java.util.HashMap; import org.mt4j.components.interfaces.IMTComponent3D; import org.mt4j.input.inputData.InputCursor; import org.mt4j.input.inputData.MTFingerInputEvt; import org.mt4j.input.inputProcessors.IInputProcessor; import org.mt4j.input.inputProcessors.MTGestureEvent; import org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor; import org.mt4j.util.math.Tools3D; import org.mt4j.util.math.ToolsGeometry; import org.mt4j.util.math.Vector3D; import processing.core.PApplet; /** * The Class MultipleDragProcessor. Fires drag events for every cursor on the component instead * of only one cursor, like the DragProcessor. * Fires DragEvent gesture events. * @author Christopher Ruff */ public class MultipleDragProcessor extends AbstractCursorProcessor { /** The app. */ private PApplet app; /** The motion to drag context. */ private HashMap<InputCursor, DragContext> motionToDragContext; /** * Instantiates a new multiple drag processor. * * @param app the app */ public MultipleDragProcessor(PApplet app) { super(); this.app = app; motionToDragContext = new HashMap<InputCursor, DragContext>(); this.setLockPriority(1); } /* (non-Javadoc) * @see org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor#cursorStarted(org.mt4j.input.inputData.InputCursor, org.mt4j.input.inputData.MTFingerInputEvt) */ @Override public void cursorStarted(InputCursor inputCursor, MTFingerInputEvt positionEvent) { DragContext dc = new DragContext(inputCursor); IMTComponent3D comp = positionEvent.getTargetComponent(); if (!dc.gestureAborted){ motionToDragContext.put(inputCursor, dc); this.fireGestureEvent(new DragEvent(this, DragEvent.GESTURE_DETECTED, comp, inputCursor, dc.lastPosition, dc.newPosition)); } } /* (non-Javadoc) * @see org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor#cursorUpdated(org.mt4j.input.inputData.InputCursor, org.mt4j.input.inputData.MTFingerInputEvt) */ @Override public void cursorUpdated(InputCursor inputCursor, MTFingerInputEvt positionEvent) { IMTComponent3D comp = positionEvent.getTargetComponent(); DragContext dc = motionToDragContext.get(inputCursor); if (dc != null && dc.dragObject.getViewingCamera() != null){ dc.updateDragPosition(); this.fireGestureEvent(new DragEvent(this, MTGestureEvent.GESTURE_UPDATED, comp, inputCursor, dc.lastPosition, dc.newPosition)); } } /* (non-Javadoc) * @see org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor#cursorEnded(org.mt4j.input.inputData.InputCursor, org.mt4j.input.inputData.MTFingerInputEvt) */ @Override public void cursorEnded(InputCursor inputCursor, MTFingerInputEvt positionEvent) { IMTComponent3D comp = positionEvent.getTargetComponent(); DragContext dc = motionToDragContext.get(inputCursor); if (dc != null){ this.fireGestureEvent(new DragEvent(this, MTGestureEvent.GESTURE_ENDED, comp, inputCursor, dc.lastPosition, dc.newPosition)); motionToDragContext.remove(inputCursor); } } /* (non-Javadoc) * @see org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor#cursorLocked(org.mt4j.input.inputData.InputCursor, org.mt4j.input.inputProcessors.IInputProcessor) */ @Override public void cursorLocked(InputCursor cursor, IInputProcessor lockingprocessor) { } /* (non-Javadoc) * @see org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor#cursorUnlocked(org.mt4j.input.inputData.InputCursor) */ @Override public void cursorUnlocked(InputCursor cursor) { } /** * The Class DragContext. */ private class DragContext { /** The start position. */ protected Vector3D startPosition; /** The last position. */ protected Vector3D lastPosition; /** The new position. */ protected Vector3D newPosition; /** The drag object. */ private IMTComponent3D dragObject; /** The m. */ private InputCursor m; /** The gesture aborted. */ protected boolean gestureAborted; /** The drag plane normal. */ private Vector3D dragPlaneNormal; /** * Instantiates a new drag context. * * @param m the m */ public DragContext(InputCursor m){ this.dragObject = m.getCurrentEvent().getTargetComponent(); this.m = m; gestureAborted = false; //Calculate the normal of the plane we will be dragging at (useful if camera isnt default) this.dragPlaneNormal = dragObject.getViewingCamera().getPosition().getSubtracted(dragObject.getViewingCamera().getViewCenterPos()).normalizeLocal(); //Set the Drag Startposition Vector3D interSectP = dragObject.getIntersectionGlobal( Tools3D.getCameraPickRay(app, dragObject, m.getCurrentEvent().getPosX(), m.getCurrentEvent().getPosY())); if (interSectP != null) this.startPosition = interSectP; else{ gestureAborted = true; this.startPosition = new Vector3D(0,0,0); //TODO ABORT GESTURE! } this.newPosition = startPosition.getCopy(); this.updateDragPosition(); //Set the Drags lastPostition (the last one before the new one) this.lastPosition = startPosition.getCopy(); } /** * Update drag position. */ public void updateDragPosition(){ Vector3D newPos = ToolsGeometry.getRayPlaneIntersection( Tools3D.getCameraPickRay(app, dragObject, m.getCurrentEvent().getPosX(), m.getCurrentEvent().getPosY()), dragPlaneNormal, startPosition); if (newPos != null){ lastPosition = newPosition; newPosition = newPos; } } } /* (non-Javadoc) * @see org.mt4j.input.inputProcessors.componentProcessors.AbstractComponentProcessor#getName() */ @Override public String getName() { return "Multiple Drag Processor"; } }