[Bprocessor-commit] gl/src/net/sourceforge/bprocessor/gl/tool ControlledMoveStrategy.java,NONE,1.1 V
Status: Pre-Alpha
Brought to you by:
henryml
From: Nordholt <nor...@us...> - 2006-03-27 14:39:01
|
Update of /cvsroot/bprocessor/gl/src/net/sourceforge/bprocessor/gl/tool In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16355 Added Files: ControlledMoveStrategy.java VectorMoveStrategy.java Log Message: first versions of the vector and controlled strategies for the movetool --- NEW FILE: VectorMoveStrategy.java --- //--------------------------------------------------------------------------------- // $Id: VectorMoveStrategy.java,v 1.1 2006/03/27 14:38:48 nordholt Exp $ // // Copyright (c) 2005 The BProcessor Team (http://bprocessor.sourceforge.net) // Released under the Lesser GNU Public License v2.1 //--------------------------------------------------------------------------------- package net.sourceforge.bprocessor.gl.tool; import net.sourceforge.bprocessor.gl.GLView; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Vertex; import java.util.HashSet; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.awt.event.MouseEvent; import java.awt.Cursor; import java.awt.event.KeyEvent; import org.apache.log4j.Logger; /** * The vector strategy for the move tool */ public class VectorMoveStrategy extends MoveTool { /** Number of clicks when in 3 click mode */ private int numberOfClicks; /** The Three click constructors edge */ private Edge threeClickConst; /** The aligning edge */ private Edge alignEdge; /** The logger */ private static Logger log = Logger.getLogger(VectorMoveStrategy.class); /** * The Constructor * @param glv The 3D canvas * @param cursor The cursor */ public VectorMoveStrategy(GLView glv, Cursor cursor) { super(glv, cursor); alignEdge = null; numberOfClicks = 1; } /** * Invoked when a mouse button has been pressed on a component. * @param e The MouseEvent object */ protected void pressed(MouseEvent e) { if (numberOfClicks == 1) { super.pressed(e); vertices = new HashSet(); collect(moveEntities, vertices); from = findInitial(target, e); initial = from.copy(); threeClickConst = new Edge(initial, initial); threeClickConst.setConstructor(true); glv.getView().addTempEdge(threeClickConst); numberOfClicks = 2; number = ""; } else if (numberOfClicks == 2) { Vertex movement = findInitial(target, e).minus(initial); move(moveEntities, movement); glv.getView().removeTempEdge(threeClickConst); threeClickConst = null; if (alignEdge != null) { glv.getView().removeTempEdge(alignEdge); alignEdge = null; } update(); numberOfClicks = 1; } } /** * Invoked when the mouse cursor has been moved * @param e The MouseEvent object */ protected void moved(MouseEvent e) { boolean showAlign = false; if (threeClickConst != null) { Set moveConstructors = makeXYZConerConstructors(new Vertex(0, 0, 0)); displayConstructors(moveConstructors); glv.getView().removeTempEdge(threeClickConst); if (alignEdge != null) { glv.getView().addTempEdge(alignEdge); } findTarget(e); glv.getView().makeTarget(target); if (target != null) { Vertex to = findInitial(target, e); if (target instanceof Edge) { Edge targetEdge = (Edge)target; if (!targetEdge.equals(alignEdge)) { Timer alignTimer = new Timer(); TimerTask alignTask = new AlignTask(targetEdge); alignTimer.schedule(alignTask, 300); } if (alignEdge != null) { Vertex alignDir = alignEdge.getDirection(); Vertex targetDir = targetEdge.getDirection(); Vertex dirCross = alignDir.cross(targetDir); showAlign = dirCross.length() < 0.000001; } } if (to != null) { threeClickConst.setTo(to); lastMoveDirection = to.minus(initial).copy(); glv.setLength(lastMoveDirection.length()); //Do we really want this to move also? //Vertex movement = to.minus(from); //move(moveEntities, movement); //from = to; } } else { threeClickConst.setTo(from); } if (threeClickConst != null) { glv.getView().addTempEdge(threeClickConst); } if (!showAlign) { glv.getView().removeTempEdge(alignEdge); } clearConstructors(moveConstructors); } else { findTarget(e); glv.getView().makeTarget(target); } } /** * Class for handeling the task of assigning an alignedge. */ private class AlignTask extends TimerTask { /** The edge candidate to become the alignedge */ private Edge candidateEdge; /** * Constructor * @param candidate the candidate to become alignedge */ public AlignTask(Edge candidate) { super(); candidateEdge = candidate; } /** * checks if the target is still the same edge, * thus making it the alignedge */ public void run() { if (target instanceof Edge) { candidateEdge.equals((Edge)target); Vertex direction = candidateEdge.getDirection(); Vertex alignTo = direction.copy(); Vertex alignFrom = direction.copy(); alignFrom.scale(-1000); alignTo.scale(1000); glv.getView().removeTempEdge(alignEdge); alignEdge = new Edge(alignFrom.add(initial), alignTo.add(initial)); alignEdge.setConstructor(true); glv.getView().addTempEdge(alignEdge); glv.repaint(true); } } } /** * Invoked when a key has been pressed. Lets user control the mode of movement. * After movement in one direction a length can be typed in to adjust the movement * to a specific length. * ESCAPE - cancel movement. * 0-9 - type length in length field. * ENTER - perform move of the specified length. * @param e The KeyEvent */ public void keyPressed(KeyEvent e) { super.keyPressed(e); } } --- NEW FILE: ControlledMoveStrategy.java --- //--------------------------------------------------------------------------------- // $Id: ControlledMoveStrategy.java,v 1.1 2006/03/27 14:38:48 nordholt Exp $ // // Copyright (c) 2005 The BProcessor Team (http://bprocessor.sourceforge.net) // Released under the Lesser GNU Public License v2.1 //--------------------------------------------------------------------------------- package net.sourceforge.bprocessor.gl.tool; import net.sourceforge.bprocessor.gl.GLView; import net.sourceforge.bprocessor.model.Edge; import net.sourceforge.bprocessor.model.Surface; import net.sourceforge.bprocessor.model.Vertex; import net.sourceforge.bprocessor.model.Entity; import net.sourceforge.bprocessor.model.Plane; import net.sourceforge.bprocessor.model.Project; import net.sourceforge.bprocessor.model.Camera; import java.util.HashSet; import java.util.HashMap; import java.util.List; import java.util.Iterator; import java.util.Collection; import java.awt.event.MouseEvent; import java.awt.Cursor; import java.awt.event.KeyEvent; import org.apache.log4j.Logger; /** * The controlled strategy for the move tool */ public class ControlledMoveStrategy extends MoveTool { /** The logger */ private static Logger log = Logger.getLogger(ControlledMoveStrategy.class); /** The slidemap */ private HashMap slideMap; /** The entity to be moved controlled */ private Entity controlled; /** The plane to drag according to */ private Plane dragPlane; /** Vector to restrict movement in one direction */ private Vertex restrictionVector; /** The initial movepoint */ private Vertex initial; /** * The Constructor * @param glv The 3D canvas * @param cursor The cursor */ public ControlledMoveStrategy(GLView glv, Cursor cursor) { super(glv, cursor); slideMap = new HashMap(); restrictionVector = null; } /** * Invoked when a mouse button has been pressed on a component. * @param e The MouseEvent object */ protected void pressed(MouseEvent e) { super.pressed(e); if (target != null) { initial = findInitial(target, e); from = initial.copy(); slideMap = new HashMap(); vertices = new HashSet(); if (!moveEntities.isEmpty()) { Iterator it = moveEntities.iterator(); controlled = (Entity)it.next(); } moveEntities.clear(); moveEntities.add(controlled); number = ""; } collect(moveEntities, vertices); } /** * Invoked when the mouse is held pressed and moved * @param e The MouseEvent object */ protected void dragged(MouseEvent e) { findRestrictions(e); if (dragPlane != null && restrictionVector != null) { int x = e.getX(); int y = e.getY(); Vertex parentPos = glv.getView().toPlaneCoords(new double[] {x, y}, dragPlane); if (parentPos != null) { Vertex delta = parentPos.minus(from); //Restricting movement. Vertex restrictCopy = restrictionVector.copy(); restrictCopy.scale(1 / restrictCopy.length()); restrictCopy.scale(delta.dot(restrictCopy)); delta = restrictCopy; if (log.isDebugEnabled()) { log.debug("from " + from.getX() + ", " + from.getY() + ", " + from.getZ()); log.debug("delta " + delta.getX() + ", " + delta.getY() + ", " + delta.getZ()); } move(vertices, delta); from.move(delta.getX(), delta.getY(), delta.getZ()); glv.setLength(from.minus(initial).length()); lastMoveDirection = delta.copy(); update(); } else { log.warn("could not hit the dragplane"); } } } /** * Set up the restriction to make the movement controlled * @param e a mouse event. */ private void findRestrictions(MouseEvent e) { if (controlled != null) { if (slideMap.isEmpty()) { findTarget(e); if (controlled instanceof Edge) { Edge controlledEdge = (Edge)controlled; if (target instanceof Surface) { Surface targetSurface = (Surface)target; if (controlledEdge.getSurfaces().contains(targetSurface)) { glv.getView().makeTarget(target); dragPlane = targetSurface.plane(); Vertex controlledDir = controlledEdge.getDirection(); Vertex surfaceNormal = targetSurface.normal(); restrictionVector = controlledDir.cross(surfaceNormal); restrictionVector.scale(1 / restrictionVector.length()); List edges = targetSurface.getEdges(); int index = edges.indexOf(controlledEdge); Edge leftEdge; Edge rightEdge; if (index == 0) { leftEdge = (Edge)edges.get(edges.size() - 1); rightEdge = (Edge)edges.get(index + 1); } else if (index == (edges.size() - 1)) { leftEdge = (Edge)edges.get(index - 1); rightEdge = (Edge)edges.get(0); } else { leftEdge = (Edge)edges.get(index - 1); rightEdge = (Edge)edges.get(index + 1); } Edge toSlideEdge = null; Edge fromSlideEdge = null; if (controlledDir.cross(leftEdge.getDirection()).length() > 0.00001 && controlledDir.cross(rightEdge.getDirection()).length() > 0.00001) { Vertex to = controlledEdge.getTo(); Vertex from = controlledEdge.getFrom(); if (to.getEdges().contains(leftEdge) && from.getEdges().contains(rightEdge)) { toSlideEdge = leftEdge; fromSlideEdge = rightEdge; } else if (from.getEdges().contains(leftEdge) && to.getEdges().contains(rightEdge)) { fromSlideEdge = leftEdge; toSlideEdge = rightEdge; } slideMap = new HashMap(); slideMap.put(controlledEdge.getTo(), toSlideEdge.getDirection()); slideMap.put(controlledEdge.getFrom(), fromSlideEdge.getDirection()); } else { dragPlane = null; restrictionVector = null; log.warn("This edge is bound"); } } } } else if (controlled instanceof Vertex) { Vertex controlledVertex = (Vertex)controlled; if (target instanceof Edge && controlledVertex.getEdges().contains((Edge)target)) { Edge targetEdge = (Edge)target; slideMap = new HashMap(); slideMap.put(controlledVertex, targetEdge.getDirection()); restrictionVector = targetEdge.getDirection(); findRestrictionPlane(); } } else if (controlled instanceof Surface) { Surface controlledSurface = (Surface)controlled; restrictionVector = controlledSurface.normal(); findRestrictionPlane(); slideMap = new HashMap(); Collection vertices = controlledSurface.getVertices(); Iterator it = vertices.iterator(); boolean bound = false; while (it.hasNext() && !bound) { Vertex vertex = (Vertex)it.next(); slideMap.put(vertex, restrictionVector); Collection edges = vertex.getEdges(); Iterator edgeIt = edges.iterator(); int otherEdges = 0; while (edgeIt.hasNext() && !bound) { Edge edge = (Edge)edgeIt.next(); if (!controlledSurface.getEdges().contains(edge)) { otherEdges++; slideMap.put(vertex, edge.getDirection()); } bound = otherEdges > 1; } } if (bound) { slideMap = new HashMap(); restrictionVector = null; dragPlane = null; log.warn("this surface is bound!"); } } } } } /** * Sets an appropriate dragPlane that aligned with the * restrictionvector and containing a specified point to * make reasonable movements. */ protected void findRestrictionPlane() { Camera camera = Project.getInstance().getCurrentCamera(); double[] centerPoint = camera.getCenter(); double[] cameraPoint = camera.getCamera(); Vertex eyeVector = new Vertex(cameraPoint[0] - centerPoint[0], cameraPoint[1] - centerPoint[1], cameraPoint[2] - centerPoint[2]); Vertex cross = restrictionVector.cross(eyeVector); Vertex planeNormal; if (cross.isZero()) { double[] rollVector = camera.getRoll(); planeNormal = new Vertex(rollVector[0], rollVector[1], rollVector[2]); } else { planeNormal = (restrictionVector.cross(eyeVector)).cross(restrictionVector); } dragPlane = new Plane(planeNormal.getX(), planeNormal.getY(), planeNormal.getZ(), -planeNormal.dot(initial)); } /** * Moves a set of vertices in a controlled way, so that they slide along * vectors specified in the slideMap. * @param vertices The vertices that should be moved. * @param delta the movement. */ protected void move(Collection vertices, Vertex delta) { Vertex deltaUnit = delta.copy(); deltaUnit.scale(1 / delta.length()); Iterator it = vertices.iterator(); while (it.hasNext()) { Vertex vertex = (Vertex)it.next(); Vertex slideDir = (Vertex)slideMap.get(vertex); double slideScale; if (delta == null) { log.info("delta null"); } if (slideDir == null) { log.info("slideDir null"); } if (deltaUnit == null) { log.info("deltaUnit null"); } if (delta.getX() != 0) { slideScale = delta.getX() / (slideDir.dot(deltaUnit) * deltaUnit.getX()); } else if (delta.getY() != 0) { slideScale = delta.getY() / (slideDir.dot(deltaUnit) * deltaUnit.getY()); } else { slideScale = delta.getZ() / (slideDir.dot(deltaUnit) * deltaUnit.getZ()); } slideDir.scale(slideScale); vertex.move(slideDir.getX(), slideDir.getY(), slideDir.getZ()); } } /** * Invoked when a key has been pressed. Lets user control the mode of movement. * After movement in one direction a length can be typed in to adjust the movement * to a specific length. * ESCAPE - cancel movement. * 0-9 - type length in length field. * ENTER - perform move of the specified length. * @param e The KeyEvent */ public void keyPressed(KeyEvent e) { super.keyPressed(e); } } |