Author: paperwing
Date: 2011-05-31 14:28:51 -0700 (Tue, 31 May 2011)
New Revision: 25606

Modified:
   csplugins/trunk/toronto/TestA3D/.classpath
   csplugins/trunk/toronto/TestA3D/src/main/java/Base.java
   csplugins/trunk/toronto/TestA3D/src/main/java/OrbitCamControl.java
Log:
orbit cam implemented, now with methods to zoom in/out, and translate the camera

Modified: csplugins/trunk/toronto/TestA3D/.classpath
===================================================================
--- csplugins/trunk/toronto/TestA3D/.classpath  2011-05-31 21:20:37 UTC (rev 
25605)
+++ csplugins/trunk/toronto/TestA3D/.classpath  2011-05-31 21:28:51 UTC (rev 
25606)
@@ -9,7 +9,7 @@
        <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-effects-0.7.jar"/>
        <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-extras-0.7.jar"/>
        <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-jogl-0.7.jar"/>
-       <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-lwjgl-0.7.jar"/>
+       <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-lwjgl-0.7.jar" 
sourcepath="/ardor3d-lwjgl/src"/>
        <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-swt-0.7.jar"/>
        <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-terrain-0.7.jar"/>
        <classpathentry kind="lib" path="/Users/yuedong/Downloads/OpenGL 
graphics libraries/ardor3d-0.7/ardor3d-ui-0.7.jar"/>

Modified: csplugins/trunk/toronto/TestA3D/src/main/java/Base.java
===================================================================
--- csplugins/trunk/toronto/TestA3D/src/main/java/Base.java     2011-05-31 
21:20:37 UTC (rev 25605)
+++ csplugins/trunk/toronto/TestA3D/src/main/java/Base.java     2011-05-31 
21:28:51 UTC (rev 25606)
@@ -4,7 +4,7 @@
 import com.ardor3d.image.util.AWTImageLoader;
 import com.ardor3d.input.*;
 import com.ardor3d.input.control.FirstPersonControl;
-import com.ardor3d.input.control.OrbitCamControl;
+//import com.ardor3d.input.control.OrbitCamControl;
 import com.ardor3d.input.logical.*;
 import com.ardor3d.input.lwjgl.*;
 import com.ardor3d.intersection.PickResults;
@@ -120,6 +120,10 @@
         second.setTranslation(new Vector3(2, 0, -15));
         root.attachChild(second);
         
+        Sphere third = new Sphere("third", 12, 12, 0.3);
+        third.setTranslation(new Vector3(0, -1, -15));
+        root.attachChild(third);
+        
         Quaternion rotation = new Quaternion();
         rotation = rotation.fromAngleNormalAxis(MathUtils.HALF_PI, new 
Vector3(0, 1, 0));
         Cylinder edge = new Cylinder("Cylinder", 8, 8, 0.1, 4);
@@ -140,7 +144,7 @@
  
                logicalLayer.checkTriggers(timer.getTimePerFrame());
 
-               canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 
-15), (new Vector3(1, 0, 0)).normalizeLocal());
+               // canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 
0, -15), (new Vector3(1, 0, 0)).normalizeLocal());
                // orbitCam.update(timer.getTimePerFrame());
                
                // Execute updateQueue item
@@ -176,17 +180,18 @@
        }
  
        protected void registerInputTriggers() {
- 
                //controlHandle = 
                // FirstPersonControl.setupTriggers(logicalLayer, worldUp, 
true);
                
+               orbitCam = new 
OrbitCamControl(canvas.getCanvasRenderer().getCamera(), new Vector3(0, 0, -15), 
worldUp);
+               orbitCam.setupInputTriggers(logicalLayer);
+               
+               // orbitCam.setTarget(new Vector3(0, 0, -10));
                /*
-               orbitCam = new 
OrbitCamControl(canvas.getCanvasRenderer().getCamera(), new Vector3(0, 0, -15));
                orbitCam.setBaseDistance(5);
                orbitCam.setupMouseTriggers(logicalLayer, true);
                orbitCam.setSphereCoords(15, 0, 0);
                */
-               
  
                logicalLayer.registerTrigger(new InputTrigger(new 
MouseButtonClickedCondition(MouseButton.RIGHT), new TriggerAction() {
                        public void perform(final Canvas source, final 
TwoInputStates inputStates, final double tpf) {
@@ -216,21 +221,21 @@
                logicalLayer.registerTrigger(new InputTrigger(new 
MouseButtonPressedCondition(MouseButton.LEFT), new TriggerAction() {
                        public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
                                if (mouseManager.isSetGrabbedSupported()) {
-                                       
mouseManager.setGrabbed(GrabbedState.GRABBED);
+                                       // 
mouseManager.setGrabbed(GrabbedState.GRABBED);
                                }
                        }
                }));
                logicalLayer.registerTrigger(new InputTrigger(new 
MouseButtonReleasedCondition(MouseButton.LEFT), new TriggerAction() {
                        public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
                                if (mouseManager.isSetGrabbedSupported()) {
-                                       
mouseManager.setGrabbed(GrabbedState.NOT_GRABBED);
+                                       // 
mouseManager.setGrabbed(GrabbedState.NOT_GRABBED);
                                }
                        }
                }));
  
                logicalLayer.registerTrigger(new InputTrigger(new 
AnyKeyCondition(), new TriggerAction() {
                        public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
-                               System.out.println("Key character pressed: " + 
inputState.getCurrent().getKeyboardState().getKeyEvent().getKeyChar());
+                               // System.out.println("Key character pressed: " 
+ inputState.getCurrent().getKeyboardState().getKeyEvent().getKeyChar());
                        }
                }));
                

Modified: csplugins/trunk/toronto/TestA3D/src/main/java/OrbitCamControl.java
===================================================================
--- csplugins/trunk/toronto/TestA3D/src/main/java/OrbitCamControl.java  
2011-05-31 21:20:37 UTC (rev 25605)
+++ csplugins/trunk/toronto/TestA3D/src/main/java/OrbitCamControl.java  
2011-05-31 21:28:51 UTC (rev 25606)
@@ -1,33 +1,291 @@
+import java.util.Set;
+
+import com.ardor3d.framework.Canvas;
+import com.ardor3d.input.Key;
+import com.ardor3d.input.KeyboardState;
+import com.ardor3d.input.MouseState;
+import com.ardor3d.input.logical.AnyKeyCondition;
+import com.ardor3d.input.logical.InputTrigger;
+import com.ardor3d.input.logical.KeyHeldCondition;
+import com.ardor3d.input.logical.LogicalLayer;
+import com.ardor3d.input.logical.MouseWheelMovedCondition;
+import com.ardor3d.input.logical.TriggerAction;
+import com.ardor3d.input.logical.TriggerConditions;
+import com.ardor3d.input.logical.TwoInputStates;
+import com.ardor3d.math.FastMath;
 import com.ardor3d.math.Vector3;
+import com.ardor3d.math.type.ReadOnlyVector3;
 import com.ardor3d.renderer.Camera;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 
 public class OrbitCamControl {
-
+       
+       private enum RotateType { HORIZONTAL, VERTICAL }
+       
     private Camera camera;
     
     private Vector3 position = new Vector3();
     private Vector3 target = new Vector3();
     private Vector3 upAxis = new Vector3();
+    private Vector3 leftAxis = new Vector3();
     private Vector3 worldUpAxis = new Vector3();
     
     private double zoomSpeed = 0.01;
     private double horizontalRotateSpeed = 0.01;
     private double verticalRotateSpeed = 0.01;
+    private double rollSpeed = 0.0001;
     
     private double distance = 10;
     private double minDistance = 2;
     private double maxDistance = 25;
     
+    private double xMoveSpeed = 0.01;
+    private double yMoveSpeed = 0.01;
+    private double zMoveSpeed = 0.01;
+    
+    private double translateSpeed = 0.01;
+    
+    private InputTrigger mouseTrigger;
+    
     public OrbitCamControl(Camera camera, Vector3 target, Vector3 worldUpAxis) 
{
-       this.target = target;
+       this.target.set(target);
        this.camera = camera;
-       this.worldUpAxis = worldUpAxis;
+       this.worldUpAxis.set(worldUpAxis);
+       this.position.set(camera.getLocation());
        
-       upAxis.set(camera.getLocation());
+       // Calculate camera distance
+       distance = position.distance(target);
+       
+       upAxis.set(camera.getUp());
+       leftAxis.set(camera.getLeft());
+       
+       System.out.println(position);
     }
     
-    private void rotateHorizontal(double angle) {
-       //camera.
+    public void setTarget(ReadOnlyVector3 target) {
+       // System.out.println("previous camera location: " + 
camera.getLocation());
+       // System.out.println("previous position: " + position);
+       // System.out.println("previous target: " + this.target);
+       
+       // Find translation vector
+       Vector3 offset = target.subtract(this.target, null);
+       
+       camera.setLocation(offset.addLocal(camera.getLocation()));
+       this.target.set(target);
+       position.set(camera.getLocation());
+ 
+       // System.out.println("new camera location: " + camera.getLocation());
+       // System.out.println("new position: " + position);
+       // System.out.println("new target: " + this.target);
     }
     
+    private void translate(ReadOnlyVector3 translation) {
+       setTarget(target.add(translation, null));
+    }
+    
+    private void zoom(double amount) {
+       double newDistance = distance - amount;
+       newDistance = Math.max(minDistance, newDistance);
+       newDistance = Math.min(maxDistance, newDistance);
+       
+       // Offset vector from target to camera
+       Vector3 offset = new Vector3();
+       position.subtract(target, offset);
+       
+       offset.normalizeLocal();
+       offset.multiplyLocal(newDistance);
+       
+       camera.setLocation(target.add(offset, position));
+    }
+    
+    private void roll(double angle) {
+       // Parametric equation for circle in 3D space:
+       // P = R(cos(t)u + sin(t)nxu) + c
+       //
+       // Where:
+       //  -u is a unit vector from the centre of the circle to any point
+       // on the circumference
+       //  -R is the radius
+       //  -n is a unit vector perpendicular to the plane
+       //  -c is the centre of the circle.
+       
+       Vector3 newUp = new Vector3();
+       
+       // Calculate (cos(t)u + sin(t)nxu)
+       newUp.set(camera.getDirection().multiply(-1, null));
+       newUp.crossLocal(camera.getUp());
+       newUp.multiplyLocal(FastMath.sin(angle));
+       
+       newUp.addLocal(camera.getUp().multiply(FastMath.sin(angle), null));
+       newUp.normalizeLocal();
+  
+       // Update the camera
+       camera.setUp(newUp);
+       camera.setLeft(camera.getDirection().cross(newUp, 
null).normalizeLocal().multiply(-1, null));
+  
+       upAxis.set(camera.getUp());
+       leftAxis.set(camera.getLeft());
+       
+       // camera.g
+    }
+    
+    private void orbit(double angle, RotateType type) {
+       // Parametric equation for circle in 3D space:
+       // P = R(cos(t)u + sin(t)nxu) + c
+       //
+       // Where:
+       //  -u is a unit vector from the centre of the circle to any point
+       // on the circumference
+       //  -R is the radius
+       //  -n is a unit vector perpendicular to the plane and c is the centre 
+        //  -c is the centre of the circle.
+       
+       // TODO correct the distance?
+       // TODO check if need to normalize the up vector?
+       
+       Vector3 buffer = new Vector3();
+       Vector3 newPosition = new Vector3();
+       Vector3 unitRelativeToCentre = new Vector3();
+       
+       // Obtain vector u
+       position.subtract(target, buffer);
+       buffer.normalize(unitRelativeToCentre);
+       
+       // Obtain cross product nxu
+       if (type == RotateType.HORIZONTAL) {
+               upAxis.normalize(newPosition);
+       } else if (type == RotateType.VERTICAL) {
+               leftAxis.normalize(newPosition);
+       }
+       newPosition.crossLocal(unitRelativeToCentre);
+       
+       // Obtain sum cos(t)u + sin(t)nxu
+       newPosition.multiplyLocal(FastMath.sin(angle));
+       newPosition.addLocal(unitRelativeToCentre.multiply(FastMath.cos(angle), 
null));
+       
+       // Multiply by R, obtaining R(cos(t)u + sin(t)nxu)
+       newPosition.multiplyLocal(distance);
+       
+       // Add c to result. This results in the new position of the camera
+       newPosition.addLocal(target);
+       
+       // Obtain new unit direction vector from center to camera
+       newPosition.subtract(target, unitRelativeToCentre);
+       unitRelativeToCentre.normalizeLocal();
+       
+       // Obtain projection of previous camera up vector onto the new 
direction vector
+       Vector3 newUpVector = new Vector3(camera.getUp());
+       Vector3 projectionOntoDirection = new Vector3();
+       unitRelativeToCentre.multiply(unitRelativeToCentre.dot(newUpVector), 
projectionOntoDirection);
+       
+       // Obtain new up vector by subtracting this projection from the old one
+       newUpVector.subtractLocal(projectionOntoDirection);
+       newUpVector.normalizeLocal();
+       
+       camera.setLocation(newPosition);
+       // TODO: Check if can just use camera's lookAt method
+       camera.setDirection(target.subtract(newPosition, 
null).normalizeLocal());
+       camera.setUp(newUpVector);
+       
+       // Use (unit direction vector) x (up vector) to give left vector
+       camera.setLeft(unitRelativeToCentre.crossLocal(newUpVector));
+       
+       // Keep track of updated camera data
+       upAxis.set(camera.getUp());
+       leftAxis.set(camera.getLeft());
+       position.set(camera.getLocation());
+    }
+    
+    private void rotate(double horizontal, double vertical) {
+       orbit(-horizontal, RotateType.HORIZONTAL);
+       orbit(-vertical, RotateType.VERTICAL);
+    }
+    
+    private void handleKeyboard(KeyboardState keyBoard) {
+       Set<Key> keysDown = keyBoard.getKeysDown();
+       
+       // System.out.println(keysDown);
+       
+       if (keysDown.contains(Key.LEFT)) {
+               translate(leftAxis.multiply(translateSpeed, null));
+       }
+       
+       if (keysDown.contains(Key.RIGHT)) {
+               translate(leftAxis.multiply(-translateSpeed, null));
+       }
+       
+       if (keysDown.contains(Key.UP)) {
+               translate(upAxis.multiply(translateSpeed, null));
+       }
+       
+       if (keysDown.contains(Key.DOWN)) {
+               translate(upAxis.multiply(-translateSpeed, null));
+       }
+       
+       if (keysDown.contains(Key.SPACE)) {
+               System.out.println("Position: " + position);
+               System.out.println("Target: " + target);
+       }
+       
+       if (keysDown.contains(Key.Q)) {
+               roll(-rollSpeed);
+       }
+       
+       if (keysDown.contains(Key.E)) {
+               roll(rollSpeed);
+       }
+    }
+    
+    public void setupInputTriggers(final LogicalLayer layer) {
+        Predicate<TwoInputStates> mouseDown = 
Predicates.or(TriggerConditions.leftButtonDown(), Predicates
+                .or(TriggerConditions.rightButtonDown(), 
TriggerConditions.middleButtonDown()));
+        
+        Predicate<TwoInputStates> mouseDragged = 
Predicates.and(TriggerConditions.mouseMoved(), mouseDown);
+        Predicate<TwoInputStates> scrollWheelMoved = new 
MouseWheelMovedCondition();
+        
+        TriggerAction mouseAction = new TriggerAction() {
+
+            public void perform(final Canvas source, final TwoInputStates 
inputStates, final double tpf) {
+                final MouseState mouse = 
inputStates.getCurrent().getMouseState();
+                if (mouse.getDx() != 0 || mouse.getDy() != 0) {
+                    rotate(horizontalRotateSpeed * mouse.getDx(), 
verticalRotateSpeed * mouse.getDy());
+                }
+
+                if (mouse.getDwheel() != 0) {
+                    zoom(zoomSpeed * mouse.getDwheel());
+                }
+            }
+        };
+
+        Predicate<TwoInputStates> predicate = Predicates.or(scrollWheelMoved, 
mouseDragged);
+        mouseTrigger = new InputTrigger(predicate, mouseAction);
+        layer.registerTrigger(mouseTrigger);
+        
+        layer.registerTrigger(new InputTrigger(new KeyHeldCondition(Key.LEFT), 
new TriggerAction() {
+                       public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
+                               translate(leftAxis.multiply(translateSpeed, 
null));
+                       }
+               }));
+        
+        layer.registerTrigger(new InputTrigger(new 
KeyHeldCondition(Key.RIGHT), new TriggerAction() {
+                       public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
+                               translate(leftAxis.multiply(-translateSpeed, 
null));
+                       }
+               }));
+        
+        layer.registerTrigger(new InputTrigger(new KeyHeldCondition(Key.UP), 
new TriggerAction() {
+                       public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
+                               translate(upAxis.multiply(translateSpeed, 
null));
+                       }
+               }));
+        
+        layer.registerTrigger(new InputTrigger(new KeyHeldCondition(Key.DOWN), 
new TriggerAction() {
+                       public void perform(final Canvas source, final 
TwoInputStates inputState, final double tpf) {
+                               translate(upAxis.multiply(-translateSpeed, 
null));
+                       }
+               }));
+       
+    }
+    
 }
\ No newline at end of file

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to