PageRenderTime 78ms CodeModel.GetById 19ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/org/mt4jx/input/inputProcessors/componentProcessors/Rotate3DProcessor/Rotate3DProcessor.java

http://mt4j.googlecode.com/
Java | 865 lines | 514 code | 156 blank | 195 comment | 53 complexity | e487b1c1a71600bcfa1e64a964804751 MD5 | raw file
  1package org.mt4jx.input.inputProcessors.componentProcessors.Rotate3DProcessor;
  2
  3import java.util.ArrayList;
  4import java.util.Iterator;
  5import java.util.List;
  6
  7import org.mt4j.MTApplication;
  8import org.mt4j.components.MTCanvas;
  9import org.mt4j.components.MTComponent;
 10import org.mt4j.components.PickResult;
 11import org.mt4j.components.PickResult.PickEntry;
 12import org.mt4j.components.interfaces.IMTComponent3D;
 13import org.mt4j.input.inputData.AbstractCursorInputEvt;
 14import org.mt4j.input.inputData.InputCursor;
 15import org.mt4j.input.inputProcessors.IInputProcessor;
 16import org.mt4j.input.inputProcessors.MTGestureEvent;
 17import org.mt4j.input.inputProcessors.componentProcessors.AbstractComponentProcessor;
 18import org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor;
 19import org.mt4j.util.camera.IFrustum;
 20import org.mt4j.util.math.Tools3D;
 21import org.mt4j.util.math.Vector3D;
 22import org.mt4jx.input.inputProcessors.componentProcessors.Group3DProcessorNew.Cluster;
 23import org.mt4jx.util.extension3D.ComponentHelper;
 24
 25import processing.core.PApplet;
 26
 27public class Rotate3DProcessor extends AbstractCursorProcessor {
 28
 29	private PApplet pApplet;
 30	
 31	/** The un used cursors. */
 32	private List<InputCursor> unUsedCursors;
 33	
 34	/** The locked cursors. */
 35	private List<InputCursor> lockedCursors;
 36	
 37	/** The rc. */
 38	private RotationContext rc;
 39	
 40	/** The drag plane normal. */
 41	private Vector3D dragPlaneNormal;
 42	
 43	/** The target Obj */
 44	private MTComponent targetComp;
 45	
 46	/** is rotation paused by collision */
 47	private boolean gesturePaused;
 48	
 49	/** has rotation resumed after pausing from collision*/
 50	private boolean resumed;
 51	
 52	public Rotate3DProcessor(PApplet graphicsContext,MTComponent targetComp){
 53		this.pApplet = graphicsContext;
 54		this.unUsedCursors 	= new ArrayList<InputCursor>();
 55		this.lockedCursors 	= new ArrayList<InputCursor>();
 56		this.dragPlaneNormal = new Vector3D(0,0,1);
 57		this.setLockPriority(3);
 58		this.targetComp = targetComp;
 59	}
 60	
 61	
 62	@Override
 63	public void cursorEnded(InputCursor inputCursor, AbstractCursorInputEvt currentEvent) {
 64		IMTComponent3D comp = currentEvent.getTarget();
 65		logger.debug(this.getName() + " INPUT_ENDED RECIEVED - MOTION: " + inputCursor.getId());
 66		
 67		if (lockedCursors.size() == 3 && lockedCursors.contains(inputCursor)){
 68			//there must be 3 cursors for a 3d rotation
 69			InputCursor firstCursor;
 70			InputCursor secondCursor;
 71			InputCursor thirdCursor;
 72			
 73			//TODO proof if this could be done better
 74			if (lockedCursors.get(0).equals(inputCursor)){
 75				firstCursor = inputCursor;
 76				secondCursor = lockedCursors.get(1);
 77				thirdCursor = lockedCursors.get(2);
 78			}else if(lockedCursors.get(1).equals(inputCursor)){
 79				firstCursor = lockedCursors.get(0);
 80				secondCursor = inputCursor;
 81				thirdCursor = lockedCursors.get(2);
 82			}else
 83			{
 84				firstCursor = lockedCursors.get(0);
 85				secondCursor = lockedCursors.get(1);
 86				thirdCursor = inputCursor;
 87			}
 88			
 89			lockedCursors.remove(inputCursor);
 90			ArrayList<InputCursor> leftOverCursors = new ArrayList<InputCursor>();
 91			leftOverCursors.add(lockedCursors.get(0));
 92			leftOverCursors.add(lockedCursors.get(1));
 93			
 94			if (unUsedCursors.size() > 0){ //Check if there are other cursors we could use for scaling if one was removed
 95				InputCursor futureCursor = unUsedCursors.get(0);
 96				if (this.canLock(futureCursor)){ //check if we have priority to claim another cursor and use it
 97					rc = new RotationContext(futureCursor, leftOverCursors.get(0),leftOverCursors.get(1), comp);
 98					if (!rc.isGestureAborted()){
 99						this.getLock(futureCursor);
100						unUsedCursors.remove(futureCursor);
101						lockedCursors.add(futureCursor);
102						logger.debug(this.getName() + " continue with different cursors (ID: " + futureCursor.getId() + ")" + " " + "(ID: " + leftOverCursors.get(0).getId() + ")");
103						//TODO fire start evt?
104					}else{ //couldnt start gesture - cursor's not on component 
105						this.endGesture(leftOverCursors, comp, firstCursor, secondCursor,thirdCursor);
106					}
107				}else{ //we dont have permission to use other cursor  - End gesture
108					this.endGesture(leftOverCursors, comp, firstCursor, secondCursor,thirdCursor);
109				}
110			}else{ //no more unused cursors on comp - End gesture
111				this.endGesture(leftOverCursors, comp, firstCursor, secondCursor,thirdCursor);
112			}
113			this.unLock(inputCursor); //FIXME TEST
114		}else{ //cursor was not a scaling involved cursor
115			if (unUsedCursors.contains(inputCursor)){
116				unUsedCursors.remove(inputCursor);
117			}
118			if(lockedCursors.contains(inputCursor))
119			{
120				lockedCursors.remove(inputCursor);
121			}
122		}
123		
124	}
125	
126	private void endGesture(ArrayList<InputCursor> leftOverCursors, IMTComponent3D component, InputCursor firstCursor, InputCursor secondCursor,InputCursor thirdCursor){
127		lockedCursors.clear();
128		unUsedCursors.addAll(leftOverCursors);
129		Iterator<InputCursor> iter = leftOverCursors.iterator();
130		while(iter.hasNext())
131		{
132			InputCursor iCursor = iter.next();
133			this.unLock(iCursor);
134		}
135		
136		this.fireGestureEvent(new Rotate3DEvent(this, MTGestureEvent.GESTURE_ENDED, component, firstCursor, secondCursor,thirdCursor, Vector3D.ZERO_VECTOR, rc.getRotationPoint(), rc.getRotationDirection(),0,0,0,rc.getRotationAxis()));
137	}
138
139	@Override
140	public void cursorLocked(InputCursor cursor,
141			IInputProcessor lockingprocessor) {
142		if (lockingprocessor instanceof AbstractComponentProcessor){
143			logger.debug(this.getName() + " Recieved MOTION LOCKED by (" + ((AbstractComponentProcessor)lockingprocessor).getName()  + ") - cursor ID: " + cursor.getId());			
144		}else{
145			logger.debug(this.getName() + " Recieved MOTION LOCKED by higher priority signal - cursor ID: " + cursor.getId());
146		}
147		
148		if (lockedCursors.contains(cursor)){ 
149			//cursors was used here! -> we have to stop the gesture
150			//put all used cursors in the unused cursor list and clear the usedcursorlist
151			unUsedCursors.addAll(lockedCursors); 
152			lockedCursors.clear();
153			//TODO fire ended evt?
154			logger.debug(this.getName() + " cursor:" + cursor.getId() + " MOTION LOCKED. Was an active cursor in this gesture!");
155		}
156		
157	}
158
159	@Override
160	public void cursorStarted(InputCursor inputCursor,
161			AbstractCursorInputEvt currentEvent) {
162		IMTComponent3D comp = currentEvent.getTarget();
163		if (lockedCursors.size() >= 3){ //gesture with 3 fingers already in progress
164			unUsedCursors.add(inputCursor);
165			logger.debug(this.getName() + " has already enough cursors for this gesture - adding to unused ID:" + inputCursor.getId());
166		}else{ //no gesture in progress yet
167			
168			//save current selected Object inside of Cluster for correct rotation
169			if(currentEvent.getTarget() instanceof Cluster)
170			{
171				Cluster cluster = (Cluster)currentEvent.getTarget();
172				MTComponent sourceComponent = (MTComponent) currentEvent.getTarget();
173				Vector3D currentPos = new Vector3D(currentEvent.getPosX(),currentEvent.getPosY(),0.0f);				
174				MTCanvas parentCanvas = this.getParentCanvas(sourceComponent);
175				cluster.setComposite(false);
176                PickResult prCanvas = parentCanvas.pick(currentPos.getX(), currentPos.getY(), true);
177                cluster.setComposite(true);
178                List<PickEntry> plCanvas = prCanvas.getPickList();
179                //get the most top element in the picklist
180                if(plCanvas.size()>0)
181                {
182                	PickEntry currentPickEntry = plCanvas.get(plCanvas.size()-1);
183                	
184                	MTComponent currentComponent = currentPickEntry.hitObj;                	
185                	cluster.setCurrentlySelectedChildren(currentComponent);
186                }
187                
188			}
189			
190			if (unUsedCursors.size() == 2){//in this case a new rotation3d can be started
191				logger.debug(this.getName() + " has already has 2 unused cursor - we can try start gesture! used with ID:" + unUsedCursors.get(0).getId() + " and new cursor ID:" + inputCursor.getId());
192				InputCursor otherCursor = unUsedCursors.get(0);//use the both unused Cursors for the rotation axis
193				InputCursor secondCursor = unUsedCursors.get(1);
194				
195				if (this.canLock(otherCursor,secondCursor,inputCursor)){
196					rc = new RotationContext(otherCursor, secondCursor,inputCursor,comp);//create new RotationContext
197					if (!rc.isGestureAborted()){
198						this.getLock(otherCursor, inputCursor,secondCursor);
199						unUsedCursors.remove(otherCursor);//remove the cursors from unUsedCursors
200						unUsedCursors.remove(secondCursor);
201						lockedCursors.add(otherCursor);//put all cursors in lockedCursors
202						lockedCursors.add(inputCursor);
203						lockedCursors.add(secondCursor);
204						logger.debug(this.getName() + " we could lock both cursors!");
205						//this.fireGestureEvent(new Rotate3DEvent(this, MTGestureEvent.GESTURE_DETECTED, comp, otherCursor, secondCursor,inputCursor, Vector3D.ZERO_VECTOR, rc.getRotationPoint(),rc.getRotationDirection(),rc.getRotationDegreesX(),rc.getRotationDegreesY(),rc.getRotationDegreesZ(),rc.getRotationAxis()));
206					}else{
207						rc = null;
208						unUsedCursors.add(inputCursor);	
209					}
210				}else{
211					logger.debug(this.getName() + " we could NOT lock both cursors!");
212					unUsedCursors.add(inputCursor);	
213				}
214			}else if(lockedCursors.size()==2&&inputCursor==rc.getRotateFingerCursor())
215			{
216				InputCursor otherCursor = lockedCursors.get(0);
217				InputCursor secondCursor = lockedCursors.get(1);
218				
219				if (this.canLock(inputCursor)){
220					rc = new RotationContext(otherCursor, secondCursor,inputCursor,comp);
221					if (!rc.isGestureAborted()){
222						this.getLock(inputCursor);
223						lockedCursors.add(inputCursor);						
224						logger.debug(this.getName() + " we could lock both cursors!");
225						this.fireGestureEvent(new Rotate3DEvent(this, MTGestureEvent.GESTURE_STARTED, comp, otherCursor, secondCursor,inputCursor, Vector3D.ZERO_VECTOR, rc.getRotationPoint(),rc.getRotationDirection(), rc.getRotationDegreesX(),rc.getRotationDegreesY(),rc.getRotationDegreesZ(),rc.getRotationAxis()));
226					}else{
227						rc = null;
228						unUsedCursors.add(inputCursor);	
229					}
230				}
231			}
232			else{
233				logger.debug(this.getName() + " we didnt have a unused cursor previously to start gesture now");
234				unUsedCursors.add(inputCursor);
235			}
236			
237		}
238		
239	}
240	
241	public void cursorUnlocked(InputCursor cursor) {
242		logger.debug(this.getName() + " Recieved UNLOCKED signal for cursor ID: " + cursor.getId());
243		
244		if (lockedCursors.size() >= 3){ //we dont need the unlocked cursor, gesture still in progress
245			return;
246		}
247		
248		if (unUsedCursors.contains(cursor)){ //should always be true here!?
249			if (unUsedCursors.size() >= 3){ //we can try to resume the gesture
250				InputCursor firstCursor = unUsedCursors.get(0);
251				InputCursor secondCursor = unUsedCursors.get(1);
252				InputCursor thirdCursor = unUsedCursors.get(2);
253				//See if we can obtain a lock on both cursors
254				if (this.canLock(firstCursor, secondCursor,thirdCursor)){
255					IMTComponent3D comp = firstCursor.getFirstEvent().getTarget();
256					rc = new RotationContext(firstCursor, secondCursor,thirdCursor, comp);
257					if (!rc.isGestureAborted()){ //Check if we could start gesture (ie. if fingers on component)
258						this.getLock(firstCursor, secondCursor,thirdCursor);
259						lockedCursors.add(firstCursor);
260						lockedCursors.add(secondCursor);
261						lockedCursors.add(thirdCursor);
262						logger.debug(this.getName() + " we could lock cursors: " + firstCursor.getId() +", " + secondCursor.getId() + ", " + thirdCursor.getId());
263						unUsedCursors.remove(firstCursor);
264						unUsedCursors.remove(secondCursor);
265						unUsedCursors.remove(thirdCursor);
266					}else{
267						rc = null;
268						logger.debug(this.getName() + " we could NOT resume gesture - cursors not on component: " + firstCursor.getId() +", " + secondCursor.getId());
269					}
270					//TODO fire started evt?
271				}else{
272					logger.debug(this.getName() + " we could NOT lock cursors: " + firstCursor.getId() +", " + secondCursor.getId() + ", " + thirdCursor.getId());
273				}
274			}
275		}else{
276			logger.error(this.getName() + "hmmm - investigate why is cursor not in unusedList?");
277		}
278		
279	}
280	
281	public void cursorUpdated(InputCursor inputCursor,
282			AbstractCursorInputEvt currentEvent) {
283		IMTComponent3D comp = currentEvent.getTarget();
284		if (lockedCursors.size() == 3 && lockedCursors.contains(inputCursor)){
285			rc.updateAndGetRotationAngle(inputCursor);
286			this.fireGestureEvent(new Rotate3DEvent(this, MTGestureEvent.GESTURE_UPDATED, comp, rc.getPinFingerCursor(), rc.getPinFingerSecondCursor(),rc.getRotateFingerCursor(), Vector3D.ZERO_VECTOR, rc.getRotationPoint(),rc.getRotationDirection(),rc.getRotationDegreesX(),rc.getRotationDegreesY(),rc.getRotationDegreesZ(),rc.getRotationAxis() ));			
287		}
288		
289	}
290
291	 private MTCanvas getParentCanvas(MTComponent as) {
292	         MTComponent tmp = as.getRoot();
293	         if(tmp instanceof MTCanvas){
294	                 return (MTCanvas)tmp;
295	         }else{
296	                 MTComponent mtc = as;
297	                 while ((!(mtc == null)) && (!((mtc = mtc.getParent()) instanceof MTCanvas))) {
298	                 }
299	                 return (MTCanvas) mtc;
300	         }
301	 }
302
303	/**
304	 * The Class RotationContext.
305	 */
306	public class RotationContext {
307
308		/** The pin finger start. */
309		private Vector3D pinFingerStart;
310
311		/** The pin finger last. */
312		private Vector3D pinFingerLast;
313
314		/** The pin finger new. */
315		private Vector3D pinFingerNew;
316		
317		/** The second pin finger start. */
318		private Vector3D pinFingerSecondStart;
319		
320		private Vector3D pinFingerSecondLast;
321		
322		private Vector3D pinFingerSecondNew;
323
324		/** The rotate finger start. */
325		private Vector3D rotateFingerStart;
326
327		/** The rotate finger last. */
328		private Vector3D rotateFingerLast;
329
330		/** The rotate finger new. */
331		private Vector3D rotateFingerNew;
332
333		/** The last rotation vect. */
334		private Vector3D lastRotationVect;
335
336		/** The object. */
337		private IMTComponent3D object;
338
339		/** The rotation point. */
340		private Vector3D rotationPoint;
341		
342		private Vector3D rotationAxis;
343
344		/** The pin finger cursor. */
345		private InputCursor pinFingerCursor; 
346		
347		/** The second pin finger cursor. */
348		private InputCursor pinFingerSecondCursor; 
349
350		/** The rotate finger cursor. */
351		private InputCursor rotateFingerCursor;
352		
353		private Vector3D rotateCursorVectorLast;
354
355		/** The new finger middle pos. */
356		private Vector3D newFingerMiddlePos;
357
358		/** The old finger middle pos. */
359		private Vector3D oldFingerMiddlePos;
360
361		/** The pin finger translation vect. */
362		private Vector3D pinFingerTranslationVect;
363
364		private boolean gestureAborted;
365
366		private float percentageX=0.0f,percentageY=0.0f,percentageZ=0.0f;
367		
368		private float rotateLineLength = 0.0f;
369		
370		private float degreesPerLengthUnit = 0.01f;
371		
372		private short rotationDirection = 1;
373		
374		private Vector3D directionFinderLeft;
375		
376		private Vector3D directionFinderRight;
377		/**
378		 * Instantiates a new rotation context.
379		 * 
380		 * @param pinFingerCursor the pin finger cursor
381		 * @param rotateFingerCursor the rotate finger cursor
382		 * @param object the object
383		 */
384		public RotationContext(InputCursor pinFingerCursor, InputCursor pinFingerCursor2, InputCursor rotateFingerCursor, IMTComponent3D object){
385			this.pinFingerCursor = pinFingerCursor;
386			this.pinFingerSecondCursor = pinFingerCursor2;
387			this.rotateFingerCursor = rotateFingerCursor;
388			
389			//check if first two fingers hit an object
390			Vector3D interPoint = getIntersection(pApplet, object, pinFingerCursor);
391  			Vector3D interPoint2 = getIntersection(pApplet, object, pinFingerSecondCursor);
392			
393			this.object = object;
394			
395			//if they hit take their x,y values and make an axis parallel 			
396			if (interPoint !=null&& interPoint2 != null){	
397				interPoint = projectPointToNearPlane(interPoint);
398				interPoint2 = projectPointToNearPlane(interPoint2);
399				pinFingerNew = interPoint;
400				pinFingerSecondNew = interPoint2;
401				setRotationAxis(getRotationAxis(interPoint,interPoint2));
402			 	//rotationAxis = interPoint.getSubtracted(interPoint2);
403			 	//z value of no interest
404			 	//rotationAxis.z = 0.0f;			 				 	
405			}else{
406				logger.error(getName() + " Pinfinger NEW = NULL");
407				pinFingerNew = new Vector3D();
408				pinFingerSecondNew = new Vector3D();
409				setRotationAxis(new Vector3D());
410				//TODO ABORT THE Rotation HERE!
411				gestureAborted = true;
412			}
413					
414			//reset all fingers
415			this.pinFingerStart = pinFingerNew.getCopy(); 
416			this.pinFingerSecondStart = pinFingerSecondNew.getCopy();
417			this.pinFingerLast	= pinFingerStart.getCopy(); 
418			this.pinFingerSecondLast = pinFingerSecondStart.getCopy();
419				
420			this.rotateCursorVectorLast = new Vector3D(rotateFingerCursor.getCurrentEvtPosX(),rotateFingerCursor.getCurrentEvtPosY(),0.0f);
421			
422			updateCalculations();
423		}
424		
425		private void updateCalculations()
426		{
427			float rotationAxisLength = getRotationAxis().length();
428			
429			MTComponent comp = (MTComponent)object;
430			
431			//get center point 			
432			if(!(comp instanceof Cluster))
433			{
434				rotationPoint = ComponentHelper.getCenterPointGlobal(comp);
435				
436			}else
437			{
438				Cluster cl = (Cluster)comp;				
439				rotationPoint = ComponentHelper.getCenterPointGlobal(cl.getCurrentlySelectedChildren());
440			}
441			
442			
443			Vector3D vec = rotationPoint.getCopy();
444			vec.z = vec.z - 1.0f;
445			
446			//get direction in which the rotation should be
447			directionFinderRight = vec.getSubtracted(rotationPoint);//rotationPoint.getSubtracted(vec);
448			
449			directionFinderRight = rotationAxis.getCross(directionFinderRight);
450			
451			directionFinderLeft = directionFinderRight.getInverted();
452			//comp.translate(rotationPoint);
453			
454			//direction Finding
455						
456			//Vector3D com = object.getCenterOfMass();
457			//rotationAxis.z = com.z;
458			
459			Vector3D rotationPartX = new Vector3D(getRotationAxis().x,0.0f,0.0f);
460			Vector3D rotationPartY = new Vector3D(0.0f,getRotationAxis().y,0.0f);
461			Vector3D rotationPartZ = new Vector3D(0.0f,0.0f,getRotationAxis().z);
462							
463//			Tools3D.endGL(pApplet);
464			
465			float dotX = rotationPartX.dot(getRotationAxis());
466			float dotY = rotationPartY.dot(getRotationAxis());
467			float dotZ = rotationPartZ.dot(getRotationAxis());
468			
469			//System.out.println("dotX " + dotX);
470			//System.out.println("dotY " + dotY);
471			//System.out.println("dot Z " + dotZ);
472			
473			//System.out.println("rotationAxis length" + getRotationAxis().length());
474			//System.out.println();
475			float degreesX = (float)Math.toDegrees(Math.acos(dotX/(rotationPartX.length()*getRotationAxis().length())));
476			float degreesY = (float)Math.toDegrees(Math.acos(dotY/(rotationPartY.length()*getRotationAxis().length())));
477			//float degreesZ = (float)Math.toDegrees(Math.acos(dotZ/(rotationPartZ.length()*rotationAxis.length())));
478			
479			if (Float.isNaN(degreesY)){
480				degreesY = 0.0f;
481			}
482			if (Float.isNaN(degreesX)){
483				degreesX = 0.0f;
484			}
485			
486			percentageX = (degreesY/90.0f)*100.0f;
487			percentageY = (degreesX/90.0f)*100.0f;
488			
489			if(getRotationAxis().x<0.0f)
490			{
491				percentageY = -percentageY;
492			}
493			
494			//System.out.println("percentageX " + percentageX);
495			//System.out.println("percentageY " + percentageY);
496			percentageZ = 0.0f;
497		}
498
499		//get the rotation axis which looks always from the less y too the more y value
500		private Vector3D getRotationAxis(Vector3D pointOne,Vector3D pointTwo)
501		{
502			Vector3D rotationAxis = pointOne.getSubtracted(pointTwo);
503			Vector3D rotationAxis2 = pointTwo.getSubtracted(pointOne); 
504			
505			if(rotationAxis.y>=rotationAxis2.y)
506			{
507				return rotationAxis;
508			}else
509			{
510				return rotationAxis2;
511			}
512		}
513		
514		private Vector3D projectPointToNearPlane(Vector3D point)
515		{
516			IFrustum frustum = object.getViewingCamera().getFrustum();
517			//projiziere Punkt auf die Near Plane
518			point = Tools3D.projectPointToPlaneInPerspectiveMode(point, frustum, frustum.getZValueOfNearPlane(),(MTApplication)object.getRenderer());
519			return point;
520		}
521		
522		/**
523		 * Update and get rotation angle.
524		 * 
525		 * @param moveCursor the move cursor
526		 * 
527		 * @return the float
528		 */
529		public void updateAndGetRotationAngle(InputCursor moveCursor) {
530//			/*
531			float newAngleRad;
532			float newAngleDegrees;
533
534			//save the current pinfinger location as the old one
535			if(!resumed)
536			{
537				this.pinFingerLast = this.pinFingerNew;
538	
539				//save the current pinfingertwo location as the old one
540				this.pinFingerSecondLast = this.pinFingerSecondNew;
541				
542				//save the current pinfinger location as the old one
543				this.rotateFingerLast = this.rotateFingerNew;
544	
545				//Check which finger moved and has to be updated
546				if (moveCursor.equals(pinFingerCursor)){
547					updatePinFinger();
548					updateCalculations();
549				}
550				else if(moveCursor.equals(pinFingerSecondCursor))
551				{
552					updatePinFingerSecond();
553					updateCalculations();
554				}
555				else if (moveCursor.equals(rotateFingerCursor)){
556					
557					updateRotateFinger(moveCursor);		
558					//updateCalculations();
559				}
560				
561			}else
562			{				
563				this.pinFingerNew = this.pinFingerLast;
564				//save the current pinfingertwo location as the old one
565				this.pinFingerSecondNew = this.pinFingerSecondLast; 
566				
567				//save the current pinfinger location as the old one
568				this.rotateFingerNew = this.rotateFingerLast; 
569				resumed = false;
570			}
571			////			*/
572		}
573
574
575		/**
576		 * Update rotate finger.
577		 */
578		public void updateRotateFinger(InputCursor rotateCursor){
579			//TODO save last position and use that one if new one is null.. everywhere!
580			/*Vector3D newRotateFingerPos = ToolsIntersection.getRayPlaneIntersection(
581					Tools3D.getCameraPickRay(pApplet, object,rotateFingerCursor.getCurrentEvent().getPosX(), rotateFingerCursor.getCurrentEvent().getPosY()), 
582					dragPlaneNormal, 
583					rotateFingerStart.getCopy());*/
584			//Update the field
585			//if (newRotateFingerPos != null){
586			
587			    float x = rotateCursorVectorLast.x - rotateCursor.getCurrentEvtPosX();
588			    float y = rotateCursorVectorLast.y - rotateCursor.getCurrentEvtPosY();
589			
590			    rotateCursorVectorLast.x = rotateCursor.getCurrentEvtPosX();
591				rotateCursorVectorLast.y = rotateCursor.getCurrentEvtPosY();
592		    
593				Vector3D rotateLengthVec = new Vector3D(x,y,0.0f);
594				
595				this.rotateLineLength = rotateLengthVec.length(); 
596							
597			    Vector3D rotateVector = new Vector3D(rotateCursor.getCurrentEvtPosX(),rotateCursor.getCurrentEvtPosY(),0.0f);
598							    
599				//System.out.println("rotate " + directionFinder.dot(rotateLengthVec));
600						
601				Vector3D finder = this.getRotationAxis().getAdded(rotateVector);
602				
603				float dotRight = directionFinderRight.dot(rotateLengthVec);
604				
605				float deg = this.getRotationAxis().dot(finder)/(finder.length()*this.getRotationAxis().length());
606				
607				/*if(this.getRotationAxis().normalizeLocal().x>rotateVector.normalizeLocal().x)
608				{
609					dotRight = -dot;
610				}*/
611				
612				if(this.getRotationAxis().x>0.0f)
613				{
614					dotRight = -dotRight;
615				}
616				   /*if(directionFinder.dot(rotateLengthVec)>0.0f&&rotateLengthVec.x>yAxis.x)
617					{
618						setRotationDirection((short)-1);
619					}else if(directionFinder.dot(rotateLengthVec)>0.0f&&rotateLengthVec.x<yAxis.x)
620					{
621						setRotationDirection((short)1);
622					}else if(directionFinder.dot(rotateLengthVec)<0.0f&&rotateLengthVec.x>yAxis.x)
623					{
624						setRotationDirection((short)1);
625					}else if(directionFinder.dot(rotateLengthVec)<0.0f&&rotateLengthVec.x<yAxis.x)
626					{
627						setRotationDirection((short)-1);
628					}*/
629				   
630				 /*  if(directionFinder.dot(rotateLengthVec)>0.0f)
631					{
632						setRotationDirection((short)-1);
633					}else 
634					{
635						setRotationDirection((short)1);
636					}*/
637				
638					/*if(Math.toDegrees(deg)>0.0d)
639					{
640						setRotationDirection((short)-1);
641					}else
642					{
643						setRotationDirection((short)1);
644					}*/
645				
646					if(dotRight>0.0d)
647					{
648						setRotationDirection((short)-1);						
649					}else
650					{
651						setRotationDirection((short)1);
652					}
653				//System.out.println("Rotate legnth" + rotateLineLength + " dir "  + rotationDirection);
654			/*}else{
655				logger.error(getName() + " new newRotateFinger Pos = null at update");
656			}*/
657		}
658
659
660		/**
661		 * Update pin finger.
662		 */
663		private void updatePinFinger(){  
664			Vector3D newPinFingerPos = getPlaneIntersection(pApplet, dragPlaneNormal, pinFingerStart.getCopy(), pinFingerCursor);
665			if (newPinFingerPos != null){
666				newPinFingerPos = projectPointToNearPlane(newPinFingerPos);
667				this.pinFingerNew = newPinFingerPos;				
668				this.setRotationAxis(this.getRotationAxis(newPinFingerPos, this.pinFingerSecondNew));
669				//Vector3D middlePoint = getMiddlePointBetweenPinFingers();
670				//this.rotationPoint = targetComp.getCenterPointGlobal();
671			}else{
672				// do nothing
673			}
674		}
675		
676		private void updatePinFingerSecond() 
677		{
678			Vector3D newPinFingerPos = getPlaneIntersection(pApplet, dragPlaneNormal, pinFingerSecondStart.getCopy(), pinFingerSecondCursor);
679			if(newPinFingerPos != null)
680			{
681				newPinFingerPos = projectPointToNearPlane(newPinFingerPos);
682				this.pinFingerSecondNew = newPinFingerPos;
683				this.setRotationAxis(this.getRotationAxis(newPinFingerPos, this.pinFingerNew));
684				//Vector3D middlePoint = getMiddlePointBetweenPinFingers();
685				//this.rotationPoint =  targetComp.getCenterPointGlobal();
686			}else{
687				// do nothing
688			}
689		}
690
691		//if obj is drag enabled, und not scalable! send middlepoint delta f???r translate, 
692		/**
693		 * Gets the updated middle finger pos delta.
694		 * 
695		 * @return the updated middle finger pos delta
696		 */
697		public Vector3D getUpdatedMiddleFingerPosDelta(){
698			newFingerMiddlePos = getMiddlePointBetweenFingers();
699			Vector3D returnVect = newFingerMiddlePos.getSubtracted(oldFingerMiddlePos);
700
701			this.oldFingerMiddlePos = newFingerMiddlePos;
702			return returnVect;
703		}
704
705		/**
706		 * Gets the middle point between fingers.
707		 * 
708		 * @return the middle point between fingers
709		 */
710		public Vector3D getMiddlePointBetweenFingers(){
711			Vector3D bla = rotateFingerNew.getSubtracted(pinFingerNew); //= Richtungsvektor vom 1. zum 2. finger
712			bla.scaleLocal(0.5f); //take the half
713			return (new Vector3D(pinFingerNew.getX() + bla.getX(), pinFingerNew.getY() + bla.getY(), pinFingerNew.getZ() + bla.getZ()));
714		}
715		
716		/**
717		 * Gets the middle point between the two pin fingers()
718		 * 
719		 * @return the middle point between both
720		 */
721		public Vector3D getMiddlePointBetweenPinFingers()
722		{
723			Vector3D midPoint = pinFingerNew.getSubtracted(pinFingerSecondNew);
724			midPoint.scaleLocal(0.5f);
725			
726			return (new Vector3D(pinFingerSecondNew.getX() + midPoint.getX(), pinFingerSecondNew.getY() + midPoint.getY(), pinFingerSecondNew.getZ() + midPoint.getZ()));
727			
728		}
729
730
731		/**
732		 * Gets the pin finger translation vect.
733		 * 
734		 * @return the pin finger translation vect
735		 */
736		public Vector3D getPinFingerTranslationVect() {
737			return pinFingerTranslationVect;
738		}
739
740		/**
741		 * Gets the pin finger start.
742		 * 
743		 * @return the pin finger start
744		 */
745		public Vector3D getPinFingerStart() {
746			return pinFingerStart;
747		}
748		
749		/**
750		 * Gets the pin finger start.
751		 * 
752		 * @return the pin finger start
753		 */
754		public Vector3D getPinFingerSecondStart() {
755			return pinFingerSecondStart;
756		}
757
758		/**
759		 * Gets the rotate finger start.
760		 * 
761		 * @return the rotate finger start
762		 */
763		public Vector3D getRotateFingerStart() {
764			return rotateFingerStart;
765		}
766
767		/**
768		 * Gets the rotation point.
769		 * 
770		 * @return the rotation point
771		 */
772		public Vector3D getRotationPoint() {
773			return rotationPoint;
774		}
775
776		/**
777		 * Gets the pin finger cursor.
778		 * 
779		 * @return the pin finger cursor
780		 */
781		public InputCursor getPinFingerCursor() {
782			return pinFingerCursor;
783		}
784		
785		/**
786		 * Gets the pin finger cursor.
787		 * 
788		 * @return the pin finger cursor
789		 */
790		public InputCursor getPinFingerSecondCursor() {
791			return pinFingerSecondCursor;
792		}
793
794		/**
795		 * Gets the rotate finger cursor.
796		 * 
797		 * @return the rotate finger cursor
798		 */
799		public InputCursor getRotateFingerCursor() {
800			return rotateFingerCursor;
801		}
802
803		public boolean isGestureAborted() {
804			return gestureAborted;
805		}
806		
807		public float percentageX()
808		{
809			return this.percentageX;
810		}
811		
812		public float percentageY()
813		{
814			return this.percentageY;
815		}
816		
817		public float percentageZ()
818		{
819			return this.percentageZ;
820		}
821		
822		public float getRotateLineLength()
823		{
824			return this.rotateLineLength;
825		}
826		
827		public float getRotationDegreesX()
828		{
829			return this.degreesPerLengthUnit*percentageX*rotateLineLength;
830		}
831		
832		public float getRotationDegreesY()
833		{
834			return this.degreesPerLengthUnit*percentageY*rotateLineLength;
835		}
836		
837		public float getRotationDegreesZ()
838		{
839			return this.degreesPerLengthUnit*percentageZ*rotateLineLength;
840		}
841
842		public void setRotationDirection(short rotationDirection) {
843			this.rotationDirection = rotationDirection;
844		}
845
846		public short getRotationDirection() {
847			return rotationDirection;
848		}
849
850		public void setRotationAxis(Vector3D rotationAxis) {
851			this.rotationAxis = rotationAxis;
852		}
853
854		public Vector3D getRotationAxis() {
855			return rotationAxis;
856		}
857
858	}
859
860	public String getName() {
861		return "Rotate3DProcessor";
862	}
863
864}
865