=== modified file 'VisualizationModule/src/org/gephi/visualization/swing/StandardGraphIO.java' --- VisualizationModule/src/org/gephi/visualization/swing/StandardGraphIO.java 2010-04-29 20:47:13 +0000 +++ VisualizationModule/src/org/gephi/visualization/swing/StandardGraphIO.java 2010-07-13 11:10:27 +0000 @@ -20,11 +20,14 @@ */ package org.gephi.visualization.swing; +import com.sun.opengl.util.BufferUtil; import java.awt.Cursor; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; +import java.nio.DoubleBuffer; +import javax.media.opengl.GLDrawable; import javax.swing.SwingUtilities; import org.gephi.visualization.GraphLimits; import org.gephi.visualization.VizArchitecture; @@ -57,6 +60,10 @@ protected float[] mouseDrag3d = new float[2]; protected float[] mouseDrag = new float[2]; protected float[] startDrag2d = new float[2]; + // Camera location, camera target, and model view matrix at start of drag + protected float[] cameraLocationAtDragStart = new float[3]; + protected float[] cameraTargetAtDragStart = new float[3]; + protected DoubleBuffer modelMatrixAtDragStart; //Flags protected boolean draggingEnable = true; protected boolean dragging = false; @@ -103,6 +110,18 @@ //Save the coordinate of the start rightButtonMoving[0] = x; rightButtonMoving[1] = y; + + // Store camera location, camera target, and model view matrix at beginning of drag + cameraLocationAtDragStart[0] = graphDrawable.cameraLocation[0]; + cameraLocationAtDragStart[1] = graphDrawable.cameraLocation[1]; + cameraLocationAtDragStart[2] = graphDrawable.cameraLocation[2]; + + cameraTargetAtDragStart[0] = graphDrawable.cameraTarget[0]; + cameraTargetAtDragStart[1] = graphDrawable.cameraTarget[1]; + cameraTargetAtDragStart[2] = graphDrawable.cameraTarget[2]; + + modelMatrixAtDragStart = graphDrawable.modelMatrix.duplicate(); + graphDrawable.graphComponent.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); vizEventManager.mouseRightPress(); } else if (vizController.getVizModel().isRotatingEnable() && SwingUtilities.isMiddleMouseButton(e)) { @@ -209,16 +228,81 @@ if (rightButtonMoving[0] != -1) { //The right button is pressed - float proche = graphDrawable.cameraTarget[2] - graphDrawable.cameraLocation[2]; - proche = proche / 300; - - graphDrawable.cameraTarget[0] += (x - rightButtonMoving[0]) * proche; - graphDrawable.cameraTarget[1] += (rightButtonMoving[1] - y) * proche; - graphDrawable.cameraLocation[0] += (x - rightButtonMoving[0]) * proche; - graphDrawable.cameraLocation[1] += (rightButtonMoving[1] - y) * proche; - - rightButtonMoving[0] = x; - rightButtonMoving[1] = y; + + // The following is the original code for draging the canvas + + // float proche = graphDrawable.cameraTarget[2] - graphDrawable.cameraLocation[2]; + // proche = proche / 300; + // proche = -1; + + // graphDrawable.cameraTarget[0] += (x - rightButtonMoving[0]) * proche; + // graphDrawable.cameraTarget[1] += (rightButtonMoving[1] - y) * proche; + // graphDrawable.cameraLocation[0] += (x - rightButtonMoving[0]) * proche; + // graphDrawable.cameraLocation[1] += (rightButtonMoving[1] - y) * proche; + + // rightButtonMoving[0] = x; + // rightButtonMoving[1] = y; + + DoubleBuffer buffer = BufferUtil.newDoubleBuffer(3); + double[] p = new double[3]; + double[] q = new double[3]; + double[] ray = new double[3]; + double t; + + // Construct ray (p --> q) into scene using mouse position at start of drag + // Note: flip y axis + GraphDrawableImpl.glu.gluUnProject(rightButtonMoving[0], graphDrawable.getViewportHeight() - rightButtonMoving[1], 0, modelMatrixAtDragStart, graphDrawable.projMatrix, graphDrawable.viewport, buffer); + buffer.get(p); + buffer.rewind(); + GraphDrawableImpl.glu.gluUnProject(rightButtonMoving[0], graphDrawable.getViewportHeight() - rightButtonMoving[1], 1, modelMatrixAtDragStart, graphDrawable.projMatrix, graphDrawable.viewport, buffer); + buffer.get(q); + buffer.rewind(); + + // Project ray to x-y plane (z = 0) + ray[0] = q[0] - p[0]; + ray[1] = q[1] - p[1]; + ray[2] = q[2] - p[2]; + + t = -p[2] / ray[2]; + ray[0] *= t; + ray[1] *= t; + ray[2] *= t; + + // Mouse position projected to plane in world coordinates (at start of drag) + double[] origin = new double[]{ray[0] + p[0], ray[1] + p[1], 0}; + + // Construct ray (p --> q) into scene using current mouse position + // Note: flip y axis + GraphDrawableImpl.glu.gluUnProject(x, graphDrawable.getViewportHeight() - y, 0, modelMatrixAtDragStart, graphDrawable.projMatrix, graphDrawable.viewport, buffer); + buffer.get(p); + buffer.rewind(); + GraphDrawableImpl.glu.gluUnProject(x, graphDrawable.getViewportHeight() - y, 1, modelMatrixAtDragStart, graphDrawable.projMatrix, graphDrawable.viewport, buffer); + buffer.get(q); + buffer.rewind(); + + // Project ray to x-y plane (z = 0) + ray[0] = q[0] - p[0]; + ray[1] = q[1] - p[1]; + ray[2] = q[2] - p[2]; + + t = -p[2] / ray[2]; + ray[0] *= t; + ray[1] *= t; + ray[2] *= t; + + // Mouse position projected to plane in world coordinates (current mouse position) + double[] destination = new double[]{ray[0] + p[0], ray[1] + p[1], 0}; + + // Determine translation in world coordinates + double dx = origin[0] - destination[0]; + double dy = origin[1] - destination[1]; + + // Translate camera location and camera target accordingly + graphDrawable.cameraLocation[0] = (float) (cameraLocationAtDragStart[0] + dx); + graphDrawable.cameraLocation[1] = (float) (cameraLocationAtDragStart[1] + dy); + graphDrawable.cameraTarget[0] = (float) (cameraTargetAtDragStart[0] + dx); + graphDrawable.cameraTarget[1] = (float) (cameraTargetAtDragStart[1] + dy); + engine.getScheduler().requireUpdateVisible(); }