Author: paperwing
Date: 2011-07-21 05:55:43 -0700 (Thu, 21 Jul 2011)
New Revision: 26228

Added:
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngine.java
Modified:
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/Graphics.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/SimpleCamera.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngineFactory.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngine.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngineFactory.java
Log:
updated drag selection box; updated mouse reticle; implementing default layout

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/Graphics.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/Graphics.java
 2011-07-20 23:50:11 UTC (rev 26227)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/Graphics.java
 2011-07-21 12:55:43 UTC (rev 26228)
@@ -1,12 +1,22 @@
 package org.cytoscape.paperwing.internal;
 import java.awt.Component;
+import java.awt.Font;
+import java.awt.Graphics2D;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.Rectangle2D;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
@@ -18,11 +28,14 @@
 import javax.media.opengl.GLProfile;
 import javax.media.opengl.glu.GLU;
 import javax.media.opengl.glu.GLUquadric;
+
+import com.jogamp.opengl.util.awt.TextRenderer;
 import com.jogamp.opengl.util.gl2.GLUT;
 
 import org.cytoscape.session.CyApplicationManager;
 import org.cytoscape.model.CyEdge;
 import org.cytoscape.model.CyEdge.Type;
+import org.cytoscape.model.CyNetwork;
 import org.cytoscape.model.CyNetworkManager;
 import org.cytoscape.model.CyNode;
 import org.cytoscape.view.model.CyNetworkView;
@@ -30,6 +43,7 @@
 import org.cytoscape.view.model.View;
 import org.cytoscape.view.model.VisualLexicon;
 import org.cytoscape.view.presentation.RenderingEngineManager;
+import org.cytoscape.view.presentation.property.MinimalVisualLexicon;
 import org.cytoscape.view.presentation.property.RichVisualLexicon;
 
 public class Graphics implements GLEventListener {
@@ -55,19 +69,20 @@
        private static final int EDGE_SLICES_DETAIL = 4;
        private static final int EDGE_STACKS_DETAIL = 1;
 
-       private static final float SELECT_BORDER_RADIUS = 0.0025f;
-       
+       private static final float SELECT_BORDER_RADIUS = 0.0027f;
        private static final int SELECT_BORDER_SLICES_DETAIL = 7;
        private static final int SELECT_BORDER_STACKS_DETAIL = 1;
        
-       private static final double SELECT_BORDER_DISTANCE = 0.92;
+       private static final double SELECT_BORDER_DISTANCE = 0.91;
        
+       private static final double RETICLE_DISTANCE = 0.06;
+       private static final double RETICLE_RADIUS = 0.012;
+       private static final double RETICLE_LENGTH = 0.03;;
        
-       
        private int nodeListIndex;
        private int edgeListIndex;
        
-       private int pointerListIndex;
+       private int reticleListIndex;
        private int selectBorderListIndex;
        
        private long startTime;
@@ -84,7 +99,13 @@
        
        private TreeSet<Integer> selectedNodeIndices;
        private TreeSet<Integer> selectedEdgeIndices;
+
+       private LinkedHashSet<CyNode> dragHoveredNodes;
+       private LinkedHashSet<CyEdge> dragHoveredEdges;
        
+       private TreeSet<Integer> dragHoveredNodeIndices;
+       private TreeSet<Integer> dragHoveredEdgeIndices;
+       
        private static int NULL_COORDINATE = Integer.MIN_VALUE;
        
        private boolean dragSelectMode;
@@ -103,7 +124,7 @@
        // private LinkedHashSet<CyNode>
        
        private static enum DrawStateModifier {
-           HOVERED, SELECTED, NORMAL, ENLARGED, SELECT_BORDER
+           HOVERED, SELECTED, NORMAL, ENLARGED, SELECT_BORDER, RETICLE
        }
        
         private static final int NO_TYPE = -1;
@@ -122,6 +143,8 @@
        private CyNetworkView networkView;
        private VisualLexicon visualLexicon;
        
+       private TextRenderer textRenderer;
+       
        private boolean latch_1;
        
        private Vector3 currentSelectedProjection;
@@ -169,6 +192,8 @@
                
                selectBottomRightX = NULL_COORDINATE;
                selectBottomRightY = NULL_COORDINATE;
+               
+               textRenderer = new TextRenderer(new Font("SansSerif", 
Font.PLAIN, 36));
        }
        
        public void trackInput(Component component) {
@@ -227,15 +252,46 @@
                // ------------------
                
                if (!dragSelectMode) {
-                       gl.glPushMatrix();
+                       //gl.glPushMatrix();
                        //gl.glTranslated(rightPointer.x(), rightPointer.y(), 
rightPointer.z());
                        
                        Vector3 projection = 
projectMouseCoordinates(camera.getDistance());
                        
-                       gl.glTranslated(projection.x(), projection.y(), 
projection.z());
-                       gl.glColor3f(0.93f, 0.23f, 0.32f);
-                       gl.glCallList(pointerListIndex);
+                       Vector3 leftOffset = 
camera.getLeft().multiply(RETICLE_DISTANCE);
+                       Vector3 upOffset = 
camera.getUp().multiply(RETICLE_DISTANCE);
+                       
+                       Vector3 left = projection.add(leftOffset);
+                       Vector3 right = projection.subtract(leftOffset);
+                       Vector3 top = projection.add(upOffset);
+                       Vector3 bottom = projection.subtract(upOffset);
+                       
+                       gl.glColor3f(0.6f, 0.4f, 0.4f);
+                       
+                       gl.glPushMatrix();
+                       setUpFacingTransformation(gl, left, 
leftOffset.multiply(-1));
+                       gl.glCallList(reticleListIndex);
                        gl.glPopMatrix();
+                       
+                       gl.glPushMatrix();
+                       setUpFacingTransformation(gl, right, leftOffset);
+                       gl.glCallList(reticleListIndex);
+                       gl.glPopMatrix();
+                       
+                       gl.glPushMatrix();
+                       setUpFacingTransformation(gl, top, 
upOffset.multiply(-1));
+                       gl.glCallList(reticleListIndex);
+                       gl.glPopMatrix();
+                       
+                       gl.glPushMatrix();
+                       setUpFacingTransformation(gl, bottom, upOffset);
+                       gl.glCallList(reticleListIndex);
+                       gl.glPopMatrix();
+                       
+                       //gl.glTranslated(projection.x(), projection.y(), 
projection.z());
+                       //gl.glColor3f(0.93f, 0.23f, 0.32f);
+                       
+                       //gl.glCallList(pointerListIndex);
+                       //gl.glPopMatrix();
                }
                
                // Draw selection box
@@ -246,7 +302,7 @@
                
                if (dragSelectMode) {
                        
-                       drawSelectionBox(gl, SELECT_BORDER_DISTANCE);
+                       drawSelectBox(gl, SELECT_BORDER_DISTANCE);
                        
 //                     
 //                     gl.glLineWidth(3.0f);
@@ -279,6 +335,8 @@
                //gl.glColor3f(0.73f, 0.73f, 0.73f);
                drawEdges(gl, DrawStateModifier.NORMAL);
 
+               drawNodeNames(gl);
+               
                framesElapsed++;
        }
        
@@ -314,6 +372,10 @@
                                                new Vector3(0, 1, 0), 0.04, 
0.002, 0.01, 0.01, 0.4);
                        }
                        
+                       if (pressed.contains(KeyEvent.VK_K)) {
+                               generalLayout();
+                       }
+                       
                        // Debug-related boolean
                        if (pressed.contains(KeyEvent.VK_1)) {
                                latch_1 = true;
@@ -521,7 +583,7 @@
                                
                                if (!selectedNodes.isEmpty()) {
                                        // TODO: Check if this is a suitable 
place to put this, as it helps to make node dragging smoother
-                                       selectProjectionDistance = 
findSelectionMidpoint().distance(camera.getPosition());
+                                       selectProjectionDistance = 
findAveragePosition(selectedNodes).distance(camera.getPosition());
                                }
                        }
                        
@@ -596,8 +658,15 @@
                                selectBottomRightY = mouse.y();
                                
                                if (Math.abs(selectTopLeftX - 
selectBottomRightX) >= 1 
-                                               && Math.abs(selectTopLeftY - 
selectBottomRightY) >= 1) {
+                                               && Math.abs(selectTopLeftY - 
selectBottomRightY) >= 1 &&
+                                               selectTopLeftX != 
NULL_COORDINATE && 
+                                               selectTopLeftY != 
NULL_COORDINATE) {
                                        
+//                                     PickResults results = performPick(gl, 
(selectTopLeftX + selectBottomRightX)/2, 
+//                                                     (selectTopLeftY + 
selectBottomRightY)/2, 
+//                                                     Math.abs(selectTopLeftX 
- selectBottomRightX),
+//                                                     Math.abs(selectTopLeftY 
- selectBottomRightY), true);
+                                       
                                        dragSelectMode = true;
                                } else {
                                        dragSelectMode = false;
@@ -605,7 +674,8 @@
                        }
                        
                        // Drag selection; selecting contents of the box
-                       if (mouse.getReleased().contains(MouseEvent.BUTTON1) && 
!keys.getHeld().contains(KeyEvent.VK_CONTROL)) {
+                       if (mouse.getReleased().contains(MouseEvent.BUTTON1) && 
!keys.getHeld().contains(KeyEvent.VK_CONTROL)
+                                       && dragSelectMode) {
                                selectBottomRightX = mouse.x();
                                selectBottomRightY = mouse.y();
                                
@@ -660,7 +730,7 @@
                        
                        if (mouse.getPressed().contains(MouseEvent.BUTTON1) && 
!selectedNodes.isEmpty()) {
                                // Store the result for use for 
mouse-difference related calculations
-                               selectProjectionDistance = 
findSelectionMidpoint().distance(camera.getPosition());
+                               selectProjectionDistance = 
findAveragePosition(selectedNodes).distance(camera.getPosition());
                                
                                previousSelectedProjection = 
projectMouseCoordinates(selectProjectionDistance);
                        // } else if 
(mouse.getHeld().contains(MouseEvent.BUTTON1) && !selectedNodes.isEmpty() && 
previousSelectProjection != null) {
@@ -691,6 +761,9 @@
                                }
                                
                                previousSelectedProjection = 
currentSelectedProjection;
+                               
+                               selectTopLeftX = NULL_COORDINATE;
+                               selectTopLeftY = NULL_COORDINATE;
                        }
                        
                        
@@ -702,6 +775,20 @@
                return projectMouseCoordinates(mouse.x(), mouse.y(), 
planeDistance);
        }
        
+       /**
+        * Converts 2D mouse coordinates to 3D coordinates, where the 
coordinate for the
+        * 3rd dimension is specified by the distance between the camera and 
the plane
+        * which intersects a line passing through the eye and the cursor 
location
+        * 
+        * @param x
+        *                      x window coordinate of the mouse
+        * @param y
+        *                      y window coordinate of the mouse
+        * @param planeDistance
+        *                      the distance between the camera and the 
intersecting plane
+        * @return
+        *                      the 3D position of the mouse
+        */
        private Vector3 projectMouseCoordinates(int x, int y, double 
planeDistance) {
                
                // Project mouse coordinates into 3d space for mouse 
interactions
@@ -751,28 +838,43 @@
                return projection;
        }
        
-       private Vector3 findSelectionMidpoint() {
-               if (selectedNodes.isEmpty()) {
+       
+       /**
+        * Obtain the average position of a set of nodes, where each node has 
the same
+        * weight in the average
+        * 
+        * @param nodes
+        *                              the {@link Collection} of nodes
+        * @return
+        *                              the average position
+        */
+       private Vector3 findAveragePosition(Collection<CyNode> nodes) {
+               if (nodes.isEmpty()) {
                        return null;
                }
                
-               View<CyNode> nodeView;
                double x = 0;
                double y = 0;
                double z = 0;
                
-               for (CyNode node : selectedNodes) {
-                       // TODO: This relies on an efficient traversal of 
selected nodes, as well
+               View<CyNode> nodeView;
+               
+               for (CyNode node : nodes) {
+                       // TODO: This relies on an efficient traversal of 
nodes, as well
                        // as efficient retrieval from the networkView object
                        nodeView = networkView.getNodeView(node);
                        
-                       x += 
nodeView.getVisualProperty(RichVisualLexicon.NODE_X_LOCATION);
-                       y += 
nodeView.getVisualProperty(RichVisualLexicon.NODE_Y_LOCATION);
-                       z += 
nodeView.getVisualProperty(RichVisualLexicon.NODE_Z_LOCATION);
+                       if (nodeView != null) {
+                               x += 
nodeView.getVisualProperty(RichVisualLexicon.NODE_X_LOCATION);
+                               y += 
nodeView.getVisualProperty(RichVisualLexicon.NODE_Y_LOCATION);
+                               z += 
nodeView.getVisualProperty(RichVisualLexicon.NODE_Z_LOCATION);
+                       } else {
+                               System.out.println("Node with no view found: " 
+ node + ", index: " + node.getIndex());
+                       }
                }
                
                Vector3 result = new Vector3(x, y, z);
-               result.divideLocal(DISTANCE_SCALE * selectedNodes.size());
+               result.divideLocal(DISTANCE_SCALE * nodes.size());
                
                return result;
        }
@@ -958,6 +1060,47 @@
                //              EDGE_SLICES_DETAIL, EDGE_STACKS_DETAIL);
                // gl.glTranslatef(-testNode.x, -testNode.y, -testNode.z);
        }
+       
+       private void drawNodeNames(GL2 gl) {
+               float x, y, z;
+               
+               for (View<CyNode> nodeView : networkView.getNodeViews()) {
+                       x = 
nodeView.getVisualProperty(RichVisualLexicon.NODE_X_LOCATION).floatValue() / 
DISTANCE_SCALE;
+                       y = 
nodeView.getVisualProperty(RichVisualLexicon.NODE_Y_LOCATION).floatValue() / 
DISTANCE_SCALE;
+                       z = 
nodeView.getVisualProperty(RichVisualLexicon.NODE_Z_LOCATION).floatValue() / 
DISTANCE_SCALE;
+                       
+                       gl.glLoadName(NO_INDEX);
+                       
+                       float offsetDistance = -0.05f;
+                       x += camera.getDirection().x() * offsetDistance;
+                       y += camera.getDirection().y() * offsetDistance;
+                       z += camera.getDirection().z() * offsetDistance;
+                       
+                       String text = "node: " + 
nodeView.getVisualProperty(MinimalVisualLexicon.NODE_LABEL);
+                       x += camera.getLeft().x() * 
(textRenderer.getBounds(text).getWidth() / 2);
+                       y += camera.getLeft().y() * 
(textRenderer.getBounds(text).getWidth() / 2);
+                       z += camera.getLeft().z() * 
(textRenderer.getBounds(text).getWidth() / 2);
+                       
+                       x -= camera.getUp().x() * 
(textRenderer.getBounds(text).getHeight() / 2);
+                       y -= camera.getUp().y() * 
(textRenderer.getBounds(text).getHeight() / 2);
+                       z -= camera.getUp().z() * 
(textRenderer.getBounds(text).getHeight() / 2);
+                       
+                       gl.glPushMatrix();
+                       
+                       setUpFacingTransformation(gl, new Vector3(x, y, z), 
camera.getDirection().multiply(-1));
+                       
+                       gl.glRotated(camera.getUp().angle(new Vector3(0, 0, 
1)), camera.getDirection().x(), camera.getDirection().y(), 
camera.getDirection().z());
+                       
+                       textRenderer.begin3DRendering();
+                       textRenderer.draw3D(text, 0, 0, 0, 0.002f);
+                       textRenderer.end3DRendering();
+                       
+                       gl.glPopMatrix();
+               }
+               
+               
+               
+       }
 
        // This method will draw all edges
        private void drawEdges(GL2 gl, DrawStateModifier generalModifier) {
@@ -1083,6 +1226,23 @@
                latch_1 = false;
        }
        
+       
+       /**
+        * Draws an edge shaped around a quadratic Bezier curve
+        * 
+        * @param gl
+        *                      {@link GL2} rendering object
+        * @param p0
+        *                      the starting point, p0
+        * @param p1
+        *                      the approach point, p1
+        * @param p2
+        *                      the end point, p2
+        * @param numSegments
+        *                      the number of straight-line segments used to 
approximate the Bezier curve
+        * @param modifier
+        *                      a modifier to change the appearance of the edge 
object
+        */
        private void drawQuadraticEdge(GL2 gl, Vector3 p0, Vector3 p1, Vector3 
p2, int numSegments, DrawStateModifier modifier) {
                // TODO: Allow the minimum distance to be changed
                if (p0.distanceSquared(p2) < 
MINIMUM_EDGE_DRAW_DISTANCE_SQUARED) {
@@ -1210,20 +1370,47 @@
                }
        }
        
-       private void drawSingleEdge(GL2 gl, Vector3 start, Vector3 end, 
DrawStateModifier modifier) {
-               gl.glPushMatrix();
+       /** 
+        * Set up matrix transformations such that the position is equal to the 
location vector 
+        * and the z-axis is in the direction of the given direction
+        * 
+        * @param gl
+        *                      {@link GL2} rendering object
+        * @param location
+        *                      desired position
+        * @param direction
+        *                      desired direction, does not have to be a unit 
vector
+        *                      
+        */
+       private void setUpFacingTransformation(GL2 gl, Vector3 location, 
Vector3 direction) {
+               gl.glTranslated(location.x(), location.y(), location.z());
                
-               // TODO: Consider using a Vector3f object for just floats, to 
use translatef instead of translated
-               gl.glTranslated(start.x(), start.y(), start.z());
-               
                Vector3 current = new Vector3(0, 0, 1);
-               Vector3 direction = end.subtract(start);
+               Vector3 rotateAxis = current.cross(direction);
                
-               Vector3 rotateAxis = current.cross(direction);
-
                gl.glRotated(Math.toDegrees(direction.angle(current)), 
rotateAxis.x(), rotateAxis.y(),
                                rotateAxis.z());
+       }
+       
+       /**
+        * Draws a single edge-like graphics object
+        * 
+        * @param gl
+        *                      {@link GL2} rendering object
+        * @param start
+        *                      start location
+        * @param end
+        *                      end location
+        * @param modifier
+        *                      a modifier to vary the appearance of the output
+        */
+       private void drawSingleEdge(GL2 gl, Vector3 start, Vector3 end, 
DrawStateModifier modifier) {
+               gl.glPushMatrix();
                
+               Vector3 direction = end.subtract(start);
+               
+               setUpFacingTransformation(gl, start, direction);
+               
                gl.glScalef(1.0f, 1.0f, (float) direction.magnitude());
                
                if (modifier == DrawStateModifier.NORMAL) {
@@ -1240,7 +1427,7 @@
                        gl.glColor3f(0.45f, 0.45f, 0.70f);
                        gl.glCallList(edgeListIndex);
                } else if (modifier == DrawStateModifier.SELECT_BORDER) {
-                       gl.glColor3f(0.70f, 0.38f, 0.64f);
+                       gl.glColor3f(0.72f, 0.31f, 0.40f);
                        gl.glCallList(selectBorderListIndex);
                } else {
                        // Invalid modifier found
@@ -1249,7 +1436,15 @@
                gl.glPopMatrix();
        }
 
-       private void drawSelectionBox(GL2 gl, double drawDistance) {
+       /**
+        * Draw the drag selection box
+        * 
+        * @param gl
+        *                      {@link GL2} rendering object
+        * @param drawDistance
+        *                      the distance from the camera to draw the box
+        */
+       private void drawSelectBox(GL2 gl, double drawDistance) {
                Vector3 topLeft = projectMouseCoordinates(selectTopLeftX, 
selectTopLeftY, drawDistance);
                Vector3 bottomLeft = projectMouseCoordinates(selectTopLeftX, 
selectBottomRightY, drawDistance);
                
@@ -1257,15 +1452,26 @@
                Vector3 bottomRight = 
projectMouseCoordinates(selectBottomRightX, selectBottomRightY, drawDistance);
 
                
-               drawSingleSelectionEdge(gl, topLeft, topRight);
-               drawSingleSelectionEdge(gl, topLeft, bottomLeft);
+               drawSingleSelectEdge(gl, topLeft, topRight);
+               drawSingleSelectEdge(gl, topLeft, bottomLeft);
                
-               drawSingleSelectionEdge(gl, topRight, bottomRight);
-               drawSingleSelectionEdge(gl, bottomLeft, bottomRight);
+               drawSingleSelectEdge(gl, topRight, bottomRight);
+               drawSingleSelectEdge(gl, bottomLeft, bottomRight);
                
        }
        
-       private void drawSingleSelectionEdge(GL2 gl, Vector3 originalStart, 
Vector3 originalEnd) {
+       /**
+        * Draws an edge-like object for the border of the selection box; 
calculations are made so that
+        * the corners of the box are sharp
+        * 
+        * @param gl
+        *                      {@link GL2} rendering object
+        * @param originalStart
+        *                      the intended start position for this edge, 
before corrections
+        * @param originalEnd
+        *                      the intended end position for this edge, before 
corrections
+        */
+       private void drawSingleSelectEdge(GL2 gl, Vector3 originalStart, 
Vector3 originalEnd) {
                Vector3 offset = originalEnd.subtract(originalStart);
                offset.normalizeLocal();
                offset.multiplyLocal(SELECT_BORDER_RADIUS/2);
@@ -1316,7 +1522,7 @@
        private void createDisplayLists(GL2 gl) {
                nodeListIndex = gl.glGenLists(1);
                edgeListIndex = gl.glGenLists(1);
-               pointerListIndex = gl.glGenLists(1);
+               reticleListIndex = gl.glGenLists(1);
                
                selectBorderListIndex = gl.glGenLists(1);
                
@@ -1349,39 +1555,23 @@
                                EDGE_SLICES_DETAIL, EDGE_STACKS_DETAIL);
                gl.glEndList();
                
-               // Draw Pointer
-               // ------------
+               // Draw a line for the reticle
+               // -----------------------------
                
-               GLUquadric pointerQuadric = glu.gluNewQuadric();
-               glu.gluQuadricDrawStyle(pointerQuadric, GLU.GLU_LINE);
-               glu.gluQuadricNormals(pointerQuadric, GLU.GLU_NONE);
+               GLUquadric reticleQuadric = glu.gluNewQuadric();
+               glu.gluQuadricDrawStyle(reticleQuadric, GLU.GLU_FILL);
+               glu.gluQuadricNormals(reticleQuadric, GLU.GLU_SMOOTH);
                
                float axisLength = 0.056f;
                float overHang = 0.028f;
                float radius = 0.002f;
                
-               gl.glNewList(pointerListIndex, GL2.GL_COMPILE);
+               gl.glNewList(reticleListIndex, GL2.GL_COMPILE);
                // glu.gluSphere(pointerQuadric, SMALL_SPHERE_RADIUS / 4, 4, 4);
                
-               // Draw X axis
-               gl.glTranslatef(-overHang, 0.0f, 0.0f);
-               gl.glRotatef(90, 0, 1, 0);
-               glu.gluCylinder(pointerQuadric, radius, radius, axisLength, 4, 
1);
-               gl.glRotatef(-90, 0, 1, 0);
-               gl.glTranslatef(overHang, 0.0f, 0.0f);
+               glu.gluCylinder(reticleQuadric, RETICLE_RADIUS, RETICLE_RADIUS, 
RETICLE_LENGTH,
+                               SELECT_BORDER_SLICES_DETAIL, 
SELECT_BORDER_STACKS_DETAIL);
                
-               // Draw Y axis
-               gl.glTranslatef(0.0f, -overHang, 0.0f);
-               gl.glRotatef(-90, 1, 0, 0);
-               glu.gluCylinder(pointerQuadric, radius, radius, axisLength, 4, 
1);
-               gl.glRotatef(90, 1, 0, 0);
-               gl.glTranslatef(0.0f, overHang, 0.0f);
-               
-               // Draw Z axis
-               gl.glTranslatef(0.0f, 0.0f, -overHang);
-               glu.gluCylinder(pointerQuadric, radius, radius, axisLength, 4, 
1);
-               gl.glTranslatef(0.0f, 0.0f, overHang);
-               
                gl.glEndList();
                
                // Draw Selection Box Border
@@ -1454,17 +1644,185 @@
                screenWidth = width;
        }
        
+       public void provideCentralView() {
+               
camera.moveTo(findAveragePosition(networkView.getModel().getNodeList()));
+               camera.moveBackward();
+               camera.zoomOut(50);
+               // camera.
+       }
+       
+       public void generalLayout() {
+               
+               // Find the central node
+               // ---------------------
+               
+               // Approach: Use node with most edges
+               
+               HashSet<CyNode> plantedNodes = new HashSet<CyNode>();
+               
+               CyNetwork network = networkView.getModel();
+               
+               CyNode centerNode = null;
+               int highestNeighborCount = -1;
+               int neighbourCount;
+               
+               for (CyNode node : network.getNodeList()) {
+                       neighbourCount = network.getNeighborList(node, 
Type.ANY).size();
+                       
+                       if (centerNode == null) {
+                               centerNode = node;
+                               highestNeighborCount = neighbourCount;
+                       } else {
+                               if (neighbourCount > highestNeighborCount) {
+                                       centerNode = node;
+                                       highestNeighborCount = neighbourCount;
+                               }
+                       }
+               }
+               
+               // Mark as planted
+               plantedNodes.add(centerNode);
+               
+               // Plant the center node
+               // ---------------------
+               
+               
networkView.getNodeView(centerNode).setVisualProperty(RichVisualLexicon.NODE_X_LOCATION,
 0.0);
+               
networkView.getNodeView(centerNode).setVisualProperty(RichVisualLexicon.NODE_Y_LOCATION,
 0.0);
+               
networkView.getNodeView(centerNode).setVisualProperty(RichVisualLexicon.NODE_Z_LOCATION,
 0.0);
+               
+               // Plant the first neighbors
+               // -------------------------
+               
+               // Idea: 2nd and further neighbors arranged in an x degree cone 
+               // facing outwards from the last edge
+       
+               HashMap<CyNode, Vector3> outwardDirections = new 
HashMap<CyNode, Vector3>();
+               
+               
+               double nodeDistance = 0.6 * DISTANCE_SCALE;
+               
+               LinkedHashSet<CyNode> firstNeighbors = new 
LinkedHashSet<CyNode>();
+               
+               // Removes duplicates as well
+               firstNeighbors.addAll(network.getNeighborList(centerNode, 
Type.ANY));
+               
+               int firstNeighborCount = firstNeighbors.size();
+               
+               double rotation = 0; 
+               
+               if (firstNeighborCount > 0) {
+                       rotation = Math.PI * 2 / firstNeighborCount;
+               }
+               
+               Vector3 current = new Vector3(0, 0, 0);
+               Vector3 offset = new Vector3(0, 1, 0);
+               offset.multiplyLocal(nodeDistance);
+               
+               for (CyNode firstNeighbor : firstNeighbors) {
+                       
networkView.getNodeView(firstNeighbor).setVisualProperty(RichVisualLexicon.NODE_X_LOCATION,
+                                       offset.x() + current.x());
+                       
networkView.getNodeView(firstNeighbor).setVisualProperty(RichVisualLexicon.NODE_Y_LOCATION,
 
+                                       offset.y() + current.y());
+                       
networkView.getNodeView(firstNeighbor).setVisualProperty(RichVisualLexicon.NODE_Z_LOCATION,
 
+                                       offset.z() + current.z());
+                       
+                       outwardDirections.put(firstNeighbor, offset);
+                       
+                       offset = offset.rotate(new Vector3(0, 0, 1), rotation);
+                       
+                       // Mark as planted
+                       plantedNodes.add(firstNeighbor);
+               }
+       
+       
+               // Plant the next neighbors
+               // ------------------------
+               
+               double conicalAngle = 0.51;
+               double outwardProjectionDistance = nodeDistance;
+               
+               LinkedHashSet<CyNode> currentNeighbors = firstNeighbors;
+               LinkedHashSet<CyNode> nextToVisit = new LinkedHashSet<CyNode>();
+               
+               do {
+                       
+                       nodeDistance *= 1.1;
+                       
+                       for (CyNode currentNeighbor : currentNeighbors) {
+                               
+                               LinkedHashSet<CyNode> nextNeighbors = new 
LinkedHashSet<CyNode>();
+                               
+                               // This will also remove redundant nodes from 
the getNeighborList result
+                               
nextNeighbors.addAll(network.getNeighborList(currentNeighbor, Type.ANY));
+                               
+                               Vector3 outwardOffset = 
outwardDirections.get(currentNeighbor);
+                               outwardOffset.normalizeLocal();
+                               
outwardOffset.multiplyLocal(outwardProjectionDistance);
+                               
+                               Vector3 perpendicularOffset = 
outwardOffset.cross(new Vector3(0, 0, 1));
+                               perpendicularOffset.multiplyLocal(nodeDistance 
* Math.tan(conicalAngle));
+                               
+                               double conicalRotation = 0;
+                               
+                               if (nextNeighbors.size() > 0) {
+                                       conicalRotation = 2 * Math.PI / 
nextNeighbors.size();
+                               }
+                               
+                               for (CyNode nextNeighbor : nextNeighbors) {
+                                       
+                                       if 
(!plantedNodes.contains(nextNeighbor)) {
+                                               
networkView.getNodeView(nextNeighbor).setVisualProperty(RichVisualLexicon.NODE_X_LOCATION,
+                                                               
perpendicularOffset.x() + outwardOffset.x() + 
+                                                               
networkView.getNodeView(currentNeighbor).
+                                                               
getVisualProperty(RichVisualLexicon.NODE_X_LOCATION));
+                                               
networkView.getNodeView(nextNeighbor).setVisualProperty(RichVisualLexicon.NODE_Y_LOCATION,
+                                                               
perpendicularOffset.y() + outwardOffset.y() + 
+                                                               
networkView.getNodeView(currentNeighbor).
+                                                               
getVisualProperty(RichVisualLexicon.NODE_Y_LOCATION));
+                                               
networkView.getNodeView(nextNeighbor).setVisualProperty(RichVisualLexicon.NODE_Z_LOCATION,
+                                                               
perpendicularOffset.z() + outwardOffset.z() + 
+                                                               
networkView.getNodeView(currentNeighbor).
+                                                               
getVisualProperty(RichVisualLexicon.NODE_Z_LOCATION));
+                                               
+                                               
outwardDirections.put(nextNeighbor, perpendicularOffset.add(outwardOffset));
+                                               
+                                               perpendicularOffset = 
perpendicularOffset.rotate(outwardOffset, conicalRotation);
+                                               
+                                               // Mark as planted
+                                               plantedNodes.add(nextNeighbor);
+                                               
+                                               nextToVisit.add(nextNeighbor);
+                                       }
+                               }
+                       }
+                       
+                       currentNeighbors.clear();
+                       currentNeighbors.addAll(nextToVisit);
+                       
+                       nextToVisit.clear();
+                       
+               } while (!currentNeighbors.isEmpty());
+               
+       }
+       
        /*
-       // Draw X axis gl.glTranslatef(-overhang, 0.0f, 0.0f);
-       gl.glRotatef(90, 0, 1, 0); gl.glColor3f(1.0f, 0.0f, 0.0f);
-       glut.glutSolidCylinder(0.005f, axisLength, 6, 3); gl.glRotatef(-90, 0, 
1, 0); gl.glTranslatef(overhang, 0.0f, 0.0f);
+       // Draw X axis
+       gl.glTranslatef(-overHang, 0.0f, 0.0f);
+       gl.glRotatef(90, 0, 1, 0);
+       glu.gluCylinder(reticleQuadric, radius, radius, axisLength, 4, 1);
+       gl.glRotatef(-90, 0, 1, 0);
+       gl.glTranslatef(overHang, 0.0f, 0.0f);
        
-       // Draw Y axis gl.glTranslatef(0.0f, -overhang, 0.0f);
-       gl.glRotatef(-90, 1, 0, 0); gl.glColor3f(0.0f, 1.0f, 0.0f);
-       glut.glutSolidCylinder(0.005f, axisLength, 6, 3); gl.glRotatef(90, 1, 
0, 0); gl.glTranslatef(0.0f, overhang, 0.0f);
+       // Draw Y axis
+       gl.glTranslatef(0.0f, -overHang, 0.0f);
+       gl.glRotatef(-90, 1, 0, 0);
+       glu.gluCylinder(reticleQuadric, radius, radius, axisLength, 4, 1);
+       gl.glRotatef(90, 1, 0, 0);
+       gl.glTranslatef(0.0f, overHang, 0.0f);
        
-       // Draw Z axis gl.glTranslatef(0.0f, 0.0f, -overhang);
-       gl.glColor3f(0.0f, 0.0f, 1.0f); glut.glutSolidCylinder(0.005f,
-       axisLength, 6, 3); gl.glTranslatef(0.0f, 0.0f, overhang);
+       // Draw Z axis
+       gl.glTranslatef(0.0f, 0.0f, -overHang);
+       glu.gluCylinder(reticleQuadric, radius, radius, axisLength, 4, 1);
+       gl.glTranslatef(0.0f, 0.0f, overHang);
        */
 }

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/SimpleCamera.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/SimpleCamera.java
     2011-07-20 23:50:11 UTC (rev 26227)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/SimpleCamera.java
     2011-07-21 12:55:43 UTC (rev 26228)
@@ -238,14 +238,81 @@
                newTarget.addLocal(position);
                target.set(newTarget);
                
+               left.set(up.cross(direction));
+               left.normalizeLocal();
+       }
+       
+       private void turnVertical(double angle) {
+               direction = direction.rotate(left, angle);
+               direction.normalizeLocal();
+               
+               Vector3 newTarget = direction.multiply(distance);
+               newTarget.addLocal(position);
+               target.set(newTarget);
+               
+               up.set(direction.cross(left));
+               up.normalizeLocal();
+       }
+       
+       private void turnHorizontal2(double angle) {
+               Vector3 targetOffset = new Vector3();
+               
+               if (distance > 1) {
+                       targetOffset.set(target.subtract(position));
+               } else {
+                       targetOffset.set(direction);
+               }
+               
+               targetOffset = targetOffset.rotate(up, angle);
+               direction.set(targetOffset.normalize());
+               
+               Vector3 newTarget = position.add(targetOffset);
+               target.set(newTarget);
+               
+               left.set(up.cross(direction));
+               left.normalizeLocal();
+       }
+       
+       private void turnVertical2(double angle) {
+               Vector3 targetOffset = new Vector3();
+               
+               if (distance > 1) {
+                       targetOffset.set(target.subtract(position));
+               } else {
+                       targetOffset.set(direction);
+               }
+               
+               targetOffset = targetOffset.rotate(left, angle);
+               direction.set(targetOffset.normalize());
+               
+               Vector3 newTarget = position.add(targetOffset);
+               target.set(newTarget);
+               
+               up.set(direction.cross(left));
+               up.normalizeLocal();
+       }
+       
+       private void turnHorizontalOld(double angle) {
+               direction = direction.rotate(up, angle);
+               direction.normalizeLocal();
+               
+               Vector3 newTarget = direction.multiply(distance);
+               newTarget.addLocal(position);
+               target.set(newTarget);
+               
+               left.set(up.cross(direction));
+               left.normalizeLocal();
+               
+               /*
                left = left.projectNormal(direction);
                left.normalizeLocal();
                
                // TODO: Check if this line is needed to maintain up, 
direction, and left are perpendicular
-               // up.set(direction.cross(left));
+               up.set(direction.cross(left));
+               */
        }
        
-       private void turnVertical(double angle) {
+       private void turnVerticalOld(double angle) {
                direction = direction.rotate(left, angle);
                direction.normalizeLocal();
                
@@ -253,11 +320,16 @@
                newTarget.addLocal(position);
                target.set(newTarget);
                
+               up.set(direction.cross(left));
+               up.normalizeLocal();
+               
+               /*
                up = up.projectNormal(direction);
                up.normalizeLocal();
                
                // TODO: Check if this line is needed to maintain up, 
direction, and left are perpendicular
-               // left.set(up.cross(direction));
+               left.set(up.cross(direction));
+               */
        }
        
        private void orbitHorizontal(double angle) {

Added: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngine.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngine.java
                           (rev 0)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngine.java
   2011-07-21 12:55:43 UTC (rev 26228)
@@ -0,0 +1,17 @@
+package org.cytoscape.paperwing.internal;
+
+import org.cytoscape.model.CyNetwork;
+import org.cytoscape.view.model.View;
+import org.cytoscape.view.model.VisualLexicon;
+
+public class WindMapRenderingEngine extends WindRenderingEngine {
+
+       public WindMapRenderingEngine(Object container, View<CyNetwork> 
viewModel,
+                       VisualLexicon visualLexicon) {
+               
+               super(container, viewModel, visualLexicon);
+               
+               graphics.provideCentralView();
+       }
+
+}


Property changes on: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngine.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngineFactory.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngineFactory.java
    2011-07-20 23:50:11 UTC (rev 26227)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindMapRenderingEngineFactory.java
    2011-07-21 12:55:43 UTC (rev 26228)
@@ -65,11 +65,12 @@
                */
                
                //TODO: NetworkViewManager does not contain all instances of 
CyNetworkView, so wait 
-               WindRenderingEngine engine = new WindRenderingEngine(container, 
viewModel, visualLexicon);
+               WindMapRenderingEngine engine = new 
WindMapRenderingEngine(container, viewModel, visualLexicon);
                System.out.println("map returning engine: " + engine);
                renderingEngineManager.addRenderingEngine(engine);
                
                System.out.println("map engine active?: " + engine.isActive());
+               System.out.println("getRendringEngine result: " + 
renderingEngineManager.getRendringEngine(viewModel));
                
                return engine;
        }

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngine.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngine.java
      2011-07-20 23:50:11 UTC (rev 26227)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngine.java
      2011-07-21 12:55:43 UTC (rev 26228)
@@ -40,6 +40,8 @@
        
        private FPSAnimator animator;
        
+       protected Graphics graphics;
+       
        private boolean active;
        
        public WindRenderingEngine(Object container, View<CyNetwork> viewModel, 
VisualLexicon visualLexicon) {
@@ -84,7 +86,7 @@
                        // TODO: check whether to use GLCanvas or GLJPanel
                        GLJPanel panel = new GLJPanel(capabilities);
                        
-                       Graphics graphics = new Graphics(networkView, 
visualLexicon);
+                       graphics = new Graphics(networkView, visualLexicon);
 
                        panel.addGLEventListener(graphics);
        
@@ -129,7 +131,7 @@
                        active = true;
                }
        }
-       
+
        @Override
        public View<CyNetwork> getViewModel() {
                return viewModel;

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngineFactory.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngineFactory.java
       2011-07-20 23:50:11 UTC (rev 26227)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/WindRenderingEngineFactory.java
       2011-07-21 12:55:43 UTC (rev 26228)
@@ -74,6 +74,7 @@
                renderingEngineManager.addRenderingEngine(engine);
                
                System.out.println("Engine active?: " + engine.isActive());
+               System.out.println("getRendringEngine result: " + 
renderingEngineManager.getRendringEngine(viewModel));
                
                return engine;
        }

-- 
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