Author: paperwing
Date: 2012-02-29 15:45:01 -0800 (Wed, 29 Feb 2012)
New Revision: 28406

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/data/GraphicsData.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/geometric/ViewingVolume.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodeLabelsProcedure.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodesProcedure.java
   
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/tools/GeometryToolkit.java
Log:
refs #678 Viewing volume culling for node labels and nodes implemented; no 
longer draws labels and nodes outside of the field of view.

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
 2012-02-29 22:45:50 UTC (rev 28405)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/Graphics.java
 2012-02-29 23:45:01 UTC (rev 28406)
@@ -26,6 +26,7 @@
 import org.cytoscape.paperwing.internal.input.KeyboardMonitor;
 import org.cytoscape.paperwing.internal.input.MouseMonitor;
 import org.cytoscape.paperwing.internal.picking.ShapePickingProcessor;
+import org.cytoscape.paperwing.internal.tools.GeometryToolkit;
 import org.cytoscape.paperwing.internal.tools.SimpleCamera;
 import org.cytoscape.view.model.CyNetworkView;
 import org.cytoscape.view.model.VisualLexicon;
@@ -128,6 +129,13 @@
                GL2 gl = drawable.getGL().getGL2();
                graphicsData.setGlContext(gl);
                
+               // Re-calculate the viewing volume
+               SimpleCamera camera = graphicsData.getCamera();
+               
graphicsData.getViewingVolume().calculateViewingVolume(camera.getPosition(), 
camera.getDirection(), camera.getUp(), 
+                               graphicsData.getNearZ(), 
graphicsData.getFarZ(), graphicsData.getVerticalFov(), 
+                               
GeometryToolkit.findHorizontalFieldOfView(graphicsData.getDistanceScale(), 
+                                               graphicsData.getScreenWidth(), 
graphicsData.getScreenHeight()));
+               
                // Perform picking
                shapePickingProcessor.processPicking(mouse, keys, graphicsData);
                

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/data/GraphicsData.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/data/GraphicsData.java
        2012-02-29 22:45:50 UTC (rev 28405)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/data/GraphicsData.java
        2012-02-29 23:45:01 UTC (rev 28406)
@@ -9,6 +9,7 @@
 import org.cytoscape.paperwing.internal.Graphics;
 import org.cytoscape.paperwing.internal.coordinator.ViewingCoordinator;
 import org.cytoscape.paperwing.internal.geometric.Vector3;
+import org.cytoscape.paperwing.internal.geometric.ViewingVolume;
 import org.cytoscape.paperwing.internal.tools.SimpleCamera;
 import org.cytoscape.view.model.CyNetworkView;
 import org.cytoscape.view.model.VisualLexicon;
@@ -37,6 +38,8 @@
 
        private float verticalFov = 45.0f;
        
+       private ViewingVolume viewingVolume;
+       
        /** Distance from eye to the near clipping plane */
        private float nearZ = 0.2f;
        
@@ -97,6 +100,7 @@
                pickingData = new PickingData();
                
                camera = new SimpleCamera();
+               viewingVolume = new ViewingVolume();
        }
        
        public void setNetworkView(CyNetworkView networkView) {
@@ -234,4 +238,12 @@
        public void setPickingData(PickingData pickingData) {
                this.pickingData = pickingData;
        }
+
+       public ViewingVolume getViewingVolume() {
+               return viewingVolume;
+       }
+
+       public void setViewingVolume(ViewingVolume viewingVolume) {
+               this.viewingVolume = viewingVolume;
+       }
 }

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/geometric/ViewingVolume.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/geometric/ViewingVolume.java
  2012-02-29 22:45:50 UTC (rev 28405)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/geometric/ViewingVolume.java
  2012-02-29 23:45:01 UTC (rev 28406)
@@ -29,10 +29,19 @@
        private Plane top, bottom;
        private Plane left, right;
        
+       public ViewingVolume() {
+               near = new Plane();
+               far = new Plane();
+               top = new Plane();
+               bottom = new Plane();
+               left = new Plane();
+               right = new Plane();
+       }
+       
        /**
         * Tests if a given point is inside the viewing volume.
         * 
-        * @param point
+        * @param point The test point
         * @return <code>true</code> if the point is inside the volume, 
<code>false</code> otherwise.
         */
        public boolean inside(Vector3 point) {
@@ -50,6 +59,29 @@
        }
        
        /**
+        * Tests if a given point either inside the viewing volume or has a 
distance to the viewing volume
+        * not exceeding a certain given value.
+        * 
+        * @param point The test point
+        * @param distance The maximum distance between the point and the 
volume volume before the point is 
+        * considered to be outside the viewing volume.
+        * @return <code>true</code> If the point is inside or within a certain 
distance from 
+        */
+       public boolean inside(Vector3 point, double distance) {
+               if (isInsidePlane(point, near, distance) &&
+                               isInsidePlane(point, far, distance) &&
+                               isInsidePlane(point, top, distance) &&
+                               isInsidePlane(point, bottom, distance) &&
+                               isInsidePlane(point, left, distance) &&
+                               isInsidePlane(point, right, distance)) {
+                               
+                               return true;
+                       } else {
+                               return false;
+                       }
+       }
+       
+       /**
         * Checks if a point is inside the given plane, that is, it lies on the 
opposite side of the normal.
         * 
         * @param point The test point
@@ -70,6 +102,26 @@
        }
        
        /**
+        * Checks if a point is inside the given plane. If it is not, this 
method still returns <code>true</code>
+        * as long as the point is within a certain distance from the plane.
+        * 
+        * @param point The test point
+        * @param plane The plane to test against
+        * @param radius The maximum distance the point can be to the plane 
before it is considered to be outside the plane
+        * @return <code>true</code> if the point lies on the opposite side of 
the plane's normal, within the given distance.
+        * Returns <code>false</code> otherwise.
+        */
+       private boolean isInsidePlane(Vector3 point, Plane plane, double 
distance) {
+               double signedDistance = plane.normal.dot(point) + 
plane.parameterD;
+               
+               if (signedDistance > distance) {
+                       return false;
+               } else {
+                       return true;
+               }
+       }
+       
+       /**
         * Calculate the boundaries of the viewing volume given the camera 
orientation, the distance to the near and far clipping planes,
         * and the vertical and horizontal fields of view.
         * 
@@ -100,13 +152,46 @@
                double farParameterD = 
-farNormal.dot(cameraPosition.plus(cameraDirection.multiply(zFar)));
                far.set(farNormal, farParameterD);
                
+               // Find the center point on the near plane for later use
+               Vector3 nearCenterPoint = 
cameraPosition.plus(cameraDirection.multiply(zNear));
+               
                // Calculate left plane
                
                // Rotate 90 degrees past the left plane to obtain the normal
                Vector3 leftNormal = cameraDirection.rotate(cameraUp, 
Math.toRadians(horizontalFieldOfView / 2 + 90));
                
                // Find a point on the plane to find the D parameter
+               Vector3 leftSamplePosition = 
cameraLeft.multiply(Math.tan(Math.toRadians(horizontalFieldOfView) / 2) * 
zNear).plus(nearCenterPoint);
+               double leftParameterD = -leftNormal.dot(leftSamplePosition);
+               left.set(leftNormal, leftParameterD);
                
+               // Calculate right plane
+               
+               // Rotate 90 degrees past the right plane to obtain the normal
+               Vector3 rightNormal = cameraDirection.rotate(cameraUp, 
Math.toRadians(horizontalFieldOfView / 2 + 90));
+               
+               // Find a point on the plane to find the D parameter
+               Vector3 rightSamplePosition = 
cameraLeft.multiply(Math.tan(Math.toRadians(horizontalFieldOfView) / 2) * 
-zNear).plus(nearCenterPoint);
+               double rightParameterD = -rightNormal.dot(rightSamplePosition);
+               right.set(rightNormal, rightParameterD);
+               
+               // Calculate top plane
+               
+               Vector3 topNormal = cameraDirection.rotate(cameraLeft, 
-Math.toRadians(verticalFieldOfView / 2 + 90));
+               
+               // Find a point on the plane
+               Vector3 topSamplePosition = 
cameraUp.multiply(Math.tan(Math.toRadians(verticalFieldOfView) / 2) * 
zNear).plus(nearCenterPoint);
+               double topParameterD = -topNormal.dot(topSamplePosition);
+               top.set(topNormal, topParameterD);
+               
+               // Calculate bottom plane
+               
+               Vector3 bottomNormal = cameraDirection.rotate(cameraLeft, 
Math.toRadians(verticalFieldOfView / 2 + 90));
+               
+               // Find a point on the plane
+               Vector3 bottomSamplePosition = 
cameraUp.multiply(Math.tan(Math.toRadians(verticalFieldOfView) / 2) * 
-zNear).plus(nearCenterPoint);
+               double bottomParameterD = 
-bottomNormal.dot(bottomSamplePosition);
+               bottom.set(bottomNormal, bottomParameterD);
        }
 
 }

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodeLabelsProcedure.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodeLabelsProcedure.java
      2012-02-29 22:45:50 UTC (rev 28405)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodeLabelsProcedure.java
      2012-02-29 23:45:01 UTC (rev 28406)
@@ -71,7 +71,7 @@
                
                String text;
                Color textColor;
-               
+
                gl.glPushMatrix();
                textRenderer.beginRendering(graphicsData.getScreenWidth(), 
graphicsData.getScreenHeight(), true);
                // textRenderer.drawString3D(arg0, arg1, arg2, arg3, arg4, arg5)
@@ -100,7 +100,7 @@
                                        
                                        // Only draw the text if the front side 
of the camera faces it
                                        if (offsetFromCamera.magnitudeSquared() 
> Double.MIN_NORMAL 
-                                                       && 
graphicsData.getCamera().getDirection().angle(offsetFromCamera) <= Math.PI / 2) 
{
+                                                       && 
graphicsData.getViewingVolume().inside(text3dPosition, graphicsData.getNearZ() 
/ 2)) {
                                                
                                                // TODO: Check if there is a 
way around this cast
                                                textColor = (Color) 
nodeView.getVisualProperty(BasicVisualLexicon.NODE_LABEL_COLOR);
@@ -128,7 +128,6 @@
                }
                
                textRenderer.endRendering();
-               
                gl.glPopMatrix();
                
        }

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodesProcedure.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodesProcedure.java
   2012-02-29 22:45:50 UTC (rev 28405)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderNodesProcedure.java
   2012-02-29 23:45:01 UTC (rev 28406)
@@ -14,6 +14,7 @@
 import org.cytoscape.model.CyEdge;
 import org.cytoscape.model.CyNode;
 import org.cytoscape.paperwing.internal.data.GraphicsData;
+import org.cytoscape.paperwing.internal.geometric.Vector3;
 import org.cytoscape.paperwing.internal.rendering.shapes.ScalableShapeDrawer;
 import 
org.cytoscape.paperwing.internal.rendering.shapes.ScalableShapeDrawer.ShapeType;
 import org.cytoscape.paperwing.internal.tools.NetworkToolkit;
@@ -94,7 +95,9 @@
                        // gl.glLoadName(33);
 
                        // Draw it only if the visual property says it is 
visible
-                       if 
(nodeView.getVisualProperty(BasicVisualLexicon.NODE_VISIBLE)) {
+                       if 
(nodeView.getVisualProperty(BasicVisualLexicon.NODE_VISIBLE)
+                                       && 
graphicsData.getViewingVolume().inside(new Vector3(x, y, z), 
graphicsData.getNearZ() / 2)) {
+                               
                                gl.glPushMatrix();
                                gl.glTranslatef(x, y, z);
                                gl.glLoadName(index);

Modified: 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/tools/GeometryToolkit.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/tools/GeometryToolkit.java
    2012-02-29 22:45:50 UTC (rev 28405)
+++ 
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/tools/GeometryToolkit.java
    2012-02-29 23:45:01 UTC (rev 28406)
@@ -195,8 +195,22 @@
                return Math.abs(Math.cos(angle) * hypotenuse);
        }
        
-       /*
-       public static double findHorizontalFieldOfView(double 
verticalFieldOfView, int screenWidth, int screenHeight) { 
+       
+       /**
+        * Given the fixed vertical field of view and screen dimensions, 
calculate the horizontal field of view assuming that 
+        * it varies according to the current aspect ratio. If the screen 
dimensions are equal, the returned horizontal field of view
+        * would be equal to the vertical field of view.
+        * 
+        * @param verticalFieldOfView The vertical field of view, in degrees
+        * @param screenWidth The width of the screen
+        * @param screenHeight The height of the screen
+        * @return The calculated horizontal field of view, in degrees
+        */
+       public static double findHorizontalFieldOfView(double 
verticalFieldOfView, int screenWidth, int screenHeight) {
+               double screenDistance = (screenHeight / 2) / 
Math.tan(verticalFieldOfView / 2 * Math.PI / 180);
+               
+               double horizontalFieldOfView = Math.atan(screenWidth / 2 / 
screenDistance);
+               
+               return (horizontalFieldOfView * 180 / Math.PI);
        }
-       */
 }

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