PageRenderTime 86ms CodeModel.GetById 56ms app.highlight 24ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/mt4j/input/inputProcessors/componentProcessors/arcballProcessor/ArcballProcessor.java

http://mt4j.googlecode.com/
Java | 663 lines | 271 code | 130 blank | 262 comment | 39 complexity | f9d0b7b00afafc472a24de0cfeee6030 MD5 | raw file
  1/***********************************************************************
  2 * mt4j Copyright (c) 2008 - 2009 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3 *  
  4 *   This program is free software: you can redistribute it and/or modify
  5 *   it under the terms of the GNU General Public License as published by
  6 *   the Free Software Foundation, either version 3 of the License, or
  7 *   (at your option) any later version.
  8 *
  9 *   This program is distributed in the hope that it will be useful,
 10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 *   GNU General Public License for more details.
 13 *
 14 *   You should have received a copy of the GNU General Public License
 15 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 16 *
 17 ***********************************************************************/
 18package org.mt4j.input.inputProcessors.componentProcessors.arcballProcessor;
 19
 20import java.util.List;
 21
 22import javax.media.opengl.GL;
 23
 24import org.mt4j.components.MTComponent;
 25import org.mt4j.components.bounds.BoundingSphere;
 26import org.mt4j.components.visibleComponents.shapes.AbstractShape;
 27import org.mt4j.input.inputData.AbstractCursorInputEvt;
 28import org.mt4j.input.inputData.InputCursor;
 29import org.mt4j.input.inputProcessors.IInputProcessor;
 30import org.mt4j.input.inputProcessors.componentProcessors.AbstractComponentProcessor;
 31import org.mt4j.input.inputProcessors.componentProcessors.AbstractCursorProcessor;
 32import org.mt4j.util.math.Matrix;
 33import org.mt4j.util.math.Quaternion;
 34import org.mt4j.util.math.Ray;
 35import org.mt4j.util.math.Tools3D;
 36import org.mt4j.util.math.ToolsMath;
 37import org.mt4j.util.math.Vector3D;
 38
 39import processing.core.PApplet;
 40import processing.opengl.PGraphicsOpenGL;
 41
 42/**
 43 * The Class ArcballProcessor. Fires ArcBallGestureEvent events.
 44 * 
 45 * @author Christopher Ruff
 46 */
 47public class ArcballProcessor extends AbstractCursorProcessor {
 48	private PApplet applet;
 49	private Matrix identityDummy;
 50	private BoundingSphere bSphere;
 51	
 52	private MTComponent shape;
 53	
 54	private float sizeScaled = 1;
 55	
 56	private IArcball ac;
 57	
 58	/**
 59	 * Instantiates a new arcball processor.
 60	 * 
 61	 * @param applet the applet
 62	 * @param shape the shape
 63	 */
 64	public ArcballProcessor(PApplet applet, AbstractShape shape){
 65		this(applet, shape, new BoundingSphere(shape));
 66	}
 67	
 68	
 69	public ArcballProcessor(PApplet applet, MTComponent component, BoundingSphere bSphere){
 70		this.applet = applet;
 71		
 72		if (identityDummy == null)
 73			identityDummy = new Matrix();
 74		
 75		this.bSphere = bSphere;
 76		this.bSphere.setRadius(bSphere.getRadius() * sizeScaled);
 77		this.shape = component;
 78//		((BoundingSphere)shape.getBoundingShape()).setRadius(((BoundingSphere)shape.getBoundingShape()).getRadius()*2);
 79		
 80		this.ac = null;
 81		
 82		this.setLockPriority(1);
 83		
 84		logger.debug("Bounding sphere center: " + bSphere.getCenter() + " Radius: " + bSphere.getRadius());
 85	}
 86
 87	
 88	
 89	@Override
 90	public void cursorStarted(InputCursor m, AbstractCursorInputEvt positionEvent) {
 91		InputCursor[] theLockedCursors = getLockedCursorsArray();
 92		//if gesture isnt started and no other cursor on comp is locked by higher priority gesture -> start gesture
 93		if (theLockedCursors.length == 0 && this.canLock(getCurrentComponentCursorsArray())){ 
 94			if (this.canLock(m)){//See if we can obtain a lock on this cursor (depends on the priority)
 95				this.getLock(m);
 96				ac = new MyArcBall(m);
 97				logger.debug(this.getName() + " successfully locked cursor (id:" + m.getId() + ")");
 98				this.fireGestureEvent(new ArcBallGestureEvent(this, ArcBallGestureEvent.GESTURE_STARTED, positionEvent.getCurrentTarget(), identityDummy));
 99			}
100		}
101	}
102
103
104	@Override
105	public void cursorUpdated(InputCursor m, AbstractCursorInputEvt positionEvent) {
106		if (getLockedCursors().contains(m)){
107			Matrix mat = ac.getNewRotation(m);
108			this.fireGestureEvent(new ArcBallGestureEvent(this, ArcBallGestureEvent.GESTURE_UPDATED, positionEvent.getCurrentTarget(), mat));
109		}
110	}
111	
112	
113	@Override
114	public void cursorEnded(InputCursor c, AbstractCursorInputEvt positionEvent) {
115		logger.debug(this.getName() + " INPUT_ENDED RECIEVED - cursor: " + c.getId());
116		if (getLockedCursors().contains(c)){ //cursors was a actual gesture cursors
117			//Check if we can resume the gesture with another cursor
118			InputCursor[] availableCursors = getFreeComponentCursorsArray();
119			if (availableCursors.length > 0 && this.canLock(getCurrentComponentCursorsArray())){ 
120				InputCursor otherCursor = availableCursors[0]; 
121				ac = new MyArcBall(otherCursor);
122				this.getLock(otherCursor);
123			}else{
124				this.fireGestureEvent(new ArcBallGestureEvent(this, ArcBallGestureEvent.GESTURE_ENDED, positionEvent.getCurrentTarget(), identityDummy));
125			}
126		}
127	}
128	
129	
130	
131
132	@Override
133	public void cursorLocked(InputCursor c, IInputProcessor lockingAnalyzer) {
134		if (lockingAnalyzer instanceof AbstractComponentProcessor){
135			logger.debug(this.getName() + " Recieved cursor LOCKED by (" + ((AbstractComponentProcessor)lockingAnalyzer).getName()  + ") - cursor ID: " + c.getId());
136		}else{
137			logger.debug(this.getName() + " Recieved cursor LOCKED by higher priority signal - cursor ID: " + c.getId());
138		}
139
140		this.fireGestureEvent(new ArcBallGestureEvent(this, ArcBallGestureEvent.GESTURE_CANCELED, c.getCurrentTarget(), identityDummy));
141		logger.debug(this.getName() + " cursor:" + c.getId() + " cursor LOCKED. Was an active cursor in this gesture!");
142	}
143
144
145
146	@Override
147	public void cursorUnlocked(InputCursor c) {
148		logger.debug(this.getName() + " Recieved UNLOCKED signal for cursor ID: " + c.getId());
149
150		List<InputCursor> locked = getLockedCursors();
151		if (locked.size() >= 1)
152			return;
153		
154		if (getFreeComponentCursors().size() > 0 && this.canLock(getCurrentComponentCursorsArray())){ 
155			ac = new MyArcBall(c);
156			this.getLock(c);
157			this.fireGestureEvent(new ArcBallGestureEvent(this, ArcBallGestureEvent.GESTURE_RESUMED, c.getCurrentTarget(), identityDummy));
158		}
159	}
160
161	
162	/**
163	 * 
164	 * @author Chris
165	 *
166	 */
167	public interface IArcball{
168		public Matrix getNewRotation(InputCursor m);
169	}
170	
171	
172	/**
173	 * 
174	 * @author Chris
175	 *
176	 */
177	private class MyArcBall implements IArcball{
178		private Vector3D lastPoint;
179		
180		private Quaternion q;
181		private Matrix returnMatrix;
182		private InputCursor m;
183		
184		private boolean doInWorldCoords = true;
185		
186		private boolean camInSphere = false;
187
188		private float camDistToInterSection;
189		
190		public MyArcBall(InputCursor m){
191			this.m = m;
192			
193			lastPoint = getSphereIntersectionObjSpace();
194			
195			if (lastPoint == null){
196				lastPoint = new Vector3D(); //TODO hack: we should abort the gesture 
197			}
198			
199			// TEST
200			if (doInWorldCoords) 
201				lastPoint.transform(shape.getGlobalMatrix());
202			
203			q = new Quaternion();
204			returnMatrix = new Matrix();
205			
206			camDistToInterSection = 1;
207		}
208		
209		
210		public Matrix getNewRotation(InputCursor m){
211			returnMatrix.loadIdentity();
212			
213			Vector3D newInterSection = getSphereIntersectionObjSpace();
214	    	
215	    	if (newInterSection != null){
216	    		if (doInWorldCoords)
217	    		newInterSection.transform(shape.getGlobalMatrix());
218	    		
219	    		logger.debug("Sphere hit, hitpoint: " + newInterSection);
220	    		
221	    		Vector3D center = bSphere.getCenterPointLocal();
222	    		
223	    		if (doInWorldCoords) //TODO center world cachen?
224	    		center.transform(shape.getGlobalMatrix());
225		    	
226		    	Vector3D a = lastPoint.getSubtracted(center);
227		    	Vector3D b = newInterSection.getSubtracted(center);
228		    	
229		    	//float dot = a.dot(b);
230//		    	float angle = Vector3D.angleBetween(a, b);
231		    	float angle = (float)myAngleBetween(a, b);
232//		    	angle *= sizeScaled * 1.5f;
233		    	
234		    	Vector3D rotationAxis = a.crossLocal(b);
235		    	
236		    	//Inverse the angle if we are inside the boundingsphere and 
237		    	//hit the inner side
238		    	if (camInSphere){ //we hit the backside of the boundingsphere, have to invert direction
239//		    		angle *= -1;
240//		    		rotationAxis.rotateZ(PApplet.radians(180)); //better than angle*-1
241		    		rotationAxis.rotateZ(ToolsMath.PI); //better than angle*-1
242//		    		rotationAxis.rotateX(PApplet.radians(180)); //better than angle*-1
243//		    		rotationAxis.scaleLocal(-1); //like angle*-1
244//		    		rotationAxis.rotateAroundAxisLocal(rotationAxis, PApplet.radians(90));
245		    	}
246		    	rotationAxis.normalizeLocal(); 
247		    	
248		    	//TODO map points that didnt intersect to sphere 
249		    	
250		    	//TODO measure distance from cam to sphere intersection point and multiply angle
251		    	//so that if distance big -> less angle, if distance small -> more angle
252//		    	System.out.println("Distance Camera to Sphere Intersection: " + camDistToInterSection);
253//		    	angle *= 1+ 1/camDistToInterSection;
254		    	float dist = Vector3D.distance(shape.getViewingCamera().getPosition() , newInterSection); 
255//		    	System.out.println("Dist: " + dist + " Angle: " + angle);
256		    	//Hack to make rotation faster if near sphere
257		    	float angleScaleFactor = 500f / dist;
258		    	if (angleScaleFactor < 1.5f)
259		    		angleScaleFactor = 1.5f;
260		    	if (angleScaleFactor > 80f)
261		    		angleScaleFactor = 80f;
262//		    	System.out.println("Angle Scale factor: " + angleScaleFactor);
263		    	angle *= angleScaleFactor;
264//		    	System.out.println();
265		    	
266		    	
267//		    	logger.debug("New hitpoint" + NewPt);
268//		    	logger.debug("Axis: " + cross);
269//		    	logger.debug("Angle: " +angle + " \n");
270		    	
271//		    	q.fromAngleNormalAxis(angle, cross);
272//		    	q.toRotationMatrix(returnMatrix);
273		    	
274		    	returnMatrix.fromAngleNormalAxis(angle, rotationAxis);
275		    	//logger.debug(returnMatrix);
276		    	
277		    	this.lastPoint.setValues(newInterSection);
278		    	
279		    	//TODO why often invalid matrix? because we didnt norm the sphere to -1..1?
280		    	if (!returnMatrix.isValid()) {
281//		    		logger.debug("NaN");
282		    		returnMatrix.loadIdentity();
283		    		return returnMatrix;
284		    	}
285		    	
286//		    	returnMatrix = Matrix.getZRotationMatrix(new Vector3D(), 1);
287//		    	Matrix.toRotationAboutPointMatrixAndInverse(returnMatrix, null, new Vector3D());
288		    	
289		    	//to rotate relative to world transform rotation point
290		    	if (doInWorldCoords)
291		    	center = MTComponent.getGlobalVecToParentRelativeSpace(shape, center); 
292		    	
293		    	//To rotate about the center of the object
294		    	Matrix.toRotationAboutPoint(returnMatrix, center);
295	    	}else{
296	    		logger.debug("Sphere wasnt hit!");
297	    	}
298	    	return returnMatrix;
299	    }
300		
301		
302		private double myAngleBetween(Vector3D a, Vector3D b) {
303			float dot = a.dot(b);
304	        double theta = Math.acos(dot / (length(a) * (length(b)) ));
305	        return theta;
306		}
307
308		/**
309	     * Calculate the magnitude (length) of the vector.
310	     * 
311	     * @return      the magnitude of the vector
312	     */
313	    public double length(Vector3D v) {
314	        return  Math.sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
315	    }
316	    
317		private Vector3D getSphereIntersectionObjSpace(){
318//			Icamera cam = shape.getAncestor().getGlobalCam();
319//			
320//	    	Vector3D rayStartPoint = cam.getPosition();
321//	    	Vector3D pointInRayDir = Tools3D.unprojectScreenCoords(applet, m.getLastEvent().getPositionX(), m.getLastEvent().getPositionY());
322//	    	
323//	    	Ray orgRay = new Ray(rayStartPoint, pointInRayDir);
324	    	
325	    	Ray realRayForThisObj = Tools3D.getCameraPickRay(applet, shape, m.getCurrentEvent().getX(), m.getCurrentEvent().getY());
326	    		
327//	    	Ray realRayForThisObj = Tools3D.toComponentCameraPickRay(applet, shape, orgRay);
328			
329			//TRIAL
330			Ray invertedRay = Ray.getTransformedRay(realRayForThisObj, shape.getGlobalInverseMatrix());
331	    	
332			Vector3D is = bSphere.getIntersectionLocal(invertedRay); 
333			
334			//Test to detect whether were inside the sphere
335//			Vector3D camPos = cam.getPosition();
336			Vector3D camPos = shape.getViewingCamera().getPosition();
337			camPos.transform(shape.getGlobalInverseMatrix());
338			
339			if (is != null){
340				camDistToInterSection = Vector3D.distance(camPos, is); 
341				//bSphere.distanceToEdge(camPos);
342			}
343
344            camInSphere = bSphere.containsPointLocal(camPos);
345			return is;
346		}
347		
348	}
349	
350
351	
352	
353	
354	
355	
356	
357	private class ArcBallContext  implements IArcball{
358		 private static final float Epsilon = 1.0e-5f;
359
360		 Quaternion q;
361		 Vector3D StVec;          //Saved click vector
362		    Vector3D EnVec;          //Saved drag vector
363		    float adjustWidth;       //Mouse bounds width
364		    float adjustHeight;      //Mouse bounds height
365
366		    public ArcBallContext(float NewWidth, float NewHeight) {
367		        StVec = new Vector3D();
368		        EnVec = new Vector3D();
369		        setBounds(NewWidth, NewHeight);
370		        q = new Quaternion();
371		    }
372
373		    public void mapToSphere(Vector3D point, Vector3D outVector) {
374		        //Copy paramter into temp point
375		        Vector3D tempPoint = new Vector3D(point.x, point.y, point.z);
376
377		        //Adjust point coords and scale down to range of [-1 ... 1]
378		        tempPoint.x = (tempPoint.x * this.adjustWidth) - 1.0f;
379		        tempPoint.y = 1.0f - (tempPoint.y * this.adjustHeight);
380
381		        //Compute the square of the length of the vector to the point from the center
382		        float length = (tempPoint.x * tempPoint.x) + (tempPoint.y * tempPoint.y);
383
384		        //If the point is mapped outside of the sphere... (length > radius squared)
385		        if (length > 1.0f) {
386		            //Compute a normalizing factor (radius / sqrt(length))
387		            float norm = (float) (1.0 / Math.sqrt(length));
388
389		            //Return the "normalized" vector, a point on the sphere
390		            outVector.x = tempPoint.x * norm;
391		            outVector.y = tempPoint.y * norm;
392		            outVector.z = 0.0f;
393		        } else  {   //Else it's on the inside
394		            //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)
395		            outVector.x = tempPoint.x;
396		            outVector.y = tempPoint.y;
397		            outVector.z = (float) Math.sqrt(1.0f - length);
398		        }
399		    }
400
401		    
402		    public void setBounds(float NewWidth, float NewHeight) {
403		        assert((NewWidth > 1.0f) && (NewHeight > 1.0f));//TODO REMOVE
404
405		        //Set adjustment factor for width/height
406		        adjustWidth = 1.0f / ((NewWidth - 1.0f) * 0.5f);
407		        adjustHeight = 1.0f / ((NewHeight - 1.0f) * 0.5f);
408		    }
409
410		    //Mouse down
411		    public void click(Vector3D NewPt) {
412		        mapToSphere(NewPt, this.StVec);
413		    }
414		    
415		  //Mouse down
416		    public void click(InputCursor m){
417//		    	Icamera cam = shape.getAncestor().getGlobalCam();
418//		    	Vector3D rayStartPoint = cam.getPosition();
419//		    	Vector3D pointInRayDir = Tools3D.unprojectScreenCoords(applet, m.getLastEvent().getPositionX(), m.getLastEvent().getPositionY());
420//		    	Ray orgRay = new Ray(rayStartPoint, pointInRayDir);
421//		    	Ray realRayForThisObj = Tools3D.toComponentCameraPickRay(applet, shape, orgRay);
422				
423		    	Ray realRayForThisObj = Tools3D.getCameraPickRay(applet, shape, m.getCurrentEvent().getX(), m.getCurrentEvent().getY());
424		    	
425				//TRIAL
426				Ray invertedRay = Ray.getTransformedRay(realRayForThisObj, shape.getGlobalInverseMatrix());
427		    	
428		    	Vector3D NewPt = bSphere.getIntersectionLocal(invertedRay);
429		    	
430		    	
431		    	if (NewPt != null){
432		    		PGraphicsOpenGL pgl = ((PGraphicsOpenGL)applet.g); 
433					GL gl 	= pgl.beginGL();  
434						gl.glPushMatrix();
435							gl.glMultMatrixf(shape.getGlobalMatrix().toFloatBuffer());
436							NewPt = Tools3D.projectGL(gl, pgl.glu, NewPt, NewPt);
437						gl.glPopMatrix();
438			    	pgl.endGL();
439			    	
440		    		this.mapToSphere(NewPt, this.StVec);
441		    	}else{
442		    		logger.error(getName() + " Didnt hit sphere!");
443		    	}
444		    }
445		    
446		    public Matrix getNewRotation(InputCursor m){
447//		    	Icamera cam = shape.getAncestor().getGlobalCam();
448//		    	Vector3D rayStartPoint = cam.getPosition();
449//		    	Vector3D pointInRayDir = Tools3D.unprojectScreenCoords(applet, m.getLastEvent().getPositionX(), m.getLastEvent().getPositionY());
450//		    	Ray orgRay = new Ray(rayStartPoint, pointInRayDir);
451//		    	Ray realRayForThisObj = Tools3D.toComponentCameraPickRay(applet, shape, orgRay);
452				
453		    	Ray realRayForThisObj = Tools3D.getCameraPickRay(applet, shape, m.getCurrentEvent().getX(), m.getCurrentEvent().getY());
454		    	
455				//TRIAL
456				Ray invertedRay = Ray.getTransformedRay(realRayForThisObj, shape.getGlobalInverseMatrix());
457		    	
458		    	Vector3D NewPt = bSphere.getIntersectionLocal(invertedRay);
459		    	
460		    	if (NewPt != null){
461		    		PGraphicsOpenGL pgl = ((PGraphicsOpenGL)applet.g); 
462					GL gl 	= pgl.beginGL();  
463						gl.glPushMatrix();
464							gl.glMultMatrixf(shape.getGlobalMatrix().toFloatBuffer());
465							NewPt = Tools3D.projectGL(gl, pgl.glu, NewPt, NewPt);
466						gl.glPopMatrix();
467			    	pgl.endGL();
468			    	
469		    		logger.debug(NewPt);
470		    		this.drag(NewPt, q);
471		    	}else{
472		    		return Matrix.get4x4Identity();
473		    	}
474		    	
475		    	return q.toRotationMatrix();
476		    }
477
478		    //Mouse drag, calculate rotation
479		    public void drag(Vector3D NewPt, Quaternion NewRot) {
480//		    	this.EnVec.setValues(NewPt);
481		    	
482		        //Map the point to the sphere
483		        this.mapToSphere(NewPt, EnVec);
484
485		        //Return the quaternion equivalent to the ration
486		        if (NewRot != null) {
487//		            Vector3D Perp = new Vector3D();
488
489		            //Compute the vector perpendicular to the begin and end vectors
490//		            Vector3D.cross(Perp, StVec, EnVec);
491		            Vector3D Perp = StVec.getCross(EnVec);
492
493		            //Compute the length of the perpendicular vector
494		            if (Perp.length() > Epsilon){    //if its non-zero
495		                //We're ok, so return the perpendicular vector as the transform after all
496		                NewRot.x = Perp.x;
497		                NewRot.y = Perp.y;
498		                NewRot.z = Perp.z;
499		                //In the quaternion values, w is cosine (theta / 2), where theta is rotation angle
500//		                NewRot.w = Vector3D.dot(StVec, EnVec);
501		                NewRot.w = StVec.dot(EnVec);
502		            } else  {                                  //if its zero
503		                //The begin and end vectors coincide, so return an identity transform
504		                NewRot.x = NewRot.y = NewRot.z = NewRot.w = 0.0f;
505		            }
506		        }
507		    }
508
509
510		
511		
512	}
513	
514	
515	
516	
517//	private class ArcBall {
518//
519//		  PApplet parent;
520//		  
521//		  float center_x, center_y, center_z, radius;
522//		  Vector3D v_down, v_drag;
523//		  Quaternion q_now, q_down, q_drag;
524//		  Vector3D[] axisSet;
525//		  int axis;
526//
527//		  /** defaults to radius of min(width/2,height/2) and center_z of -radius */
528//		  public ArcBall(PApplet parent) {
529//		    this(parent.g.width/2.0f,parent.g.height/2.0f,-PApplet.min(parent.g.width/2.0f,parent.g.height/2.0f),PApplet.min(parent.g.width/2.0f,parent.g.height/2.0f), parent);
530//		  }
531//
532//		  public ArcBall(float center_x, float center_y, float center_z, float radius, PApplet parent) {
533//
534//		    this.parent = parent;
535//
536//		    parent.registerMouseEvent(this);
537//		    parent.registerPre(this);
538//
539//		    this.center_x = center_x;
540//		    this.center_y = center_y;
541//		    this.center_z = center_z;
542//		    this.radius = radius;
543//
544//		    v_down = new Vector3D();
545//		    v_drag = new Vector3D();
546//
547//		    q_now = new Quaternion();
548//		    q_down = new Quaternion();
549//		    q_drag = new Quaternion();
550//
551//		    axisSet = new Vector3D[] { 
552//		      new Vector3D(1.0f, 0.0f, 0.0f), new Vector3D(0.0f, 1.0f, 0.0f), new Vector3D(0.0f, 0.0f, 1.0f) };
553//		    axis = -1;  // no constraints...
554//		  }
555//
556//		  public void mouseEvent(MouseEvent event) {
557//		    int id = event.getID();
558//		    if (id == MouseEvent.MOUSE_DRAGGED) {
559//		      mouseDragged();
560//		    } 
561//		    else if (id == MouseEvent.MOUSE_PRESSED) {
562//		      mousePressed();
563//		    }
564//		  }
565//		  
566//		  public Matrix drag(InputCursor m){
567//		   //TODO
568//			  Icamera cam = shape.getAncestor().getGlobalCam();
569//		    	
570//		    	Vector3D rayStartPoint = cam.getPosition();
571//		    	Vector3D pointInRayDir = Tools3D.unprojectScreenCoords(applet, m.getLastEvent().getPositionX(), m.getLastEvent().getPositionY());
572//		    	
573//		    	Ray orgRay = new Ray(rayStartPoint, pointInRayDir);
574//		    		
575//		    	Ray realRayForThisObj = Tools3D.getRealPickRay(shape, orgRay);
576//				
577//				//TRIAL
578//				Ray invertedRay = Ray.getTransformedRay(realRayForThisObj, shape.getAbsoluteWorldToLocalMatrix());
579//		    	
580//		    	Vector3D NewPt = bSphere.getIntersectionPoint(invertedRay);
581//		    	
582//		    	if (NewPt != null){
583//		    		logger.debug(NewPt);
584//		    		this.mouseDragged();
585//		    		
586////		    		this.drag(NewPt, q);
587//		    	}else{
588//		    		return Matrix.get4x4Identity();
589//		    	}
590//		  }
591//
592//		  public void mousePressed() {
593//		    v_down = mouse_to_sphere(parent.mouseX, parent.mouseY);
594//		    q_down.set(q_now);
595////		    q_drag.reset();
596//		    q_drag.loadIdentity();
597//		  }
598//
599//		  
600//		  public void mouseDragged(float x, float y) {
601//			    v_drag = mouse_to_sphere(y, y);
602////			    q_drag.set(Vector3D.dot(v_down, v_drag), Vector3D.cross(v_down, v_drag));
603//			    q_drag.set(v_down.dot(v_drag), v_down.getCross(v_drag));
604//			  }
605//		  
606////		  public void mouseDragged() {
607////		    v_drag = mouse_to_sphere(parent.mouseX, parent.mouseY);
608//////		    q_drag.set(Vector3D.dot(v_down, v_drag), Vector3D.cross(v_down, v_drag));
609////		    q_drag.set(v_down.dot(v_drag), v_down.getCross(v_drag));
610////		  }
611//
612//		  public void pre() {
613//		    parent.translate(center_x, center_y, center_z);
614////		    q_now = Quaternion.mul(q_drag, q_down);
615//		    q_now = q_drag.mult(q_down);
616//		    	
617//		    applyQuaternion2Matrix(q_now);
618//		    parent.translate(-center_x, -center_y, -center_z);
619//		  }
620//
621//		  Vector3D mouse_to_sphere(float x, float y) {
622//		    Vector3D v = new Vector3D();
623//		    v.x = (x - center_x) / radius;
624//		    v.y = (y - center_y) / radius;
625//
626//		    float mag = v.x * v.x + v.y * v.y;
627//		    if (mag > 1.0f) {
628////		      v.normalize();
629//		    	v.normalizeLocal();
630//		    }
631//		    else {
632//		      v.z = PApplet.sqrt(1.0f - mag);
633//		    }
634//
635//		    return (axis == -1) ? v : constrain_vector(v, axisSet[axis]);
636//		  }
637//
638//		  Vector3D constrain_vector(Vector3D vector, Vector3D axis) {
639//		    Vector3D res = new Vector3D();
640////		    res.sub(vector, Vector3D.mul(axis, Vector3D.dot(axis, vector)));
641//		    res.subtractLocal(axis.getScaled(axis.dot(vector)));
642//		    
643////		    res.normalize();
644//		    res.normalizeLocal();
645//		    return res;
646//		  }
647//
648//		  void applyQuaternion2Matrix(Quaternion q) {
649//		    // instead of transforming q into a matrix and applying it...
650//
651//		    float[] aa = q.getValue();
652//		    parent.rotate(aa[0], aa[1], aa[2], aa[3]);
653//		  }
654//
655//	}
656	
657	@Override
658	public String getName() {
659		return "Arcball Processor";
660	}
661
662
663}