## c't-Projekte - Mailinglisten

[Voriger (Datum)] [Nächster (Datum)] [Voriger (Thread)] [Nächster (Thread)]
[Nach Datum][Nach Thread]

### [ct-bot] Patch: komfortable Kamerasteuerung

Absender: Michael Prähofer
Datum: Do, 03.08.2006 10:37:47

    Hallo,
    die unintuitive Maussteuerung des Kamerastandpunktes hat mich schon lange gestoert.
    Viele Gruesse,

    Michael

    Patch: komfortable Kamerasteuerung
    Datum: 	 03.08.2006
    Autor:	Michael Praehofer
    Beschreibung: Es wird die Klasse FocussingObserverBehavior definiert, die dafuer sorgt,
       dass die Kamera immer auf einen Referenzpunkt im Universum, den Fokus, gerichtet ist.
       Um den Fokus  kann vertikal und horizontal rotiert werden, aber seitliches Neigen (rolling)
       ist nicht moeglich. Der Abstand vom Fokus kann veraendert werden (zoom).  Schliesslich
       kann die Position des Fokusses sowohl in der horizontalen (rechte Maustaste), als auch in
       der vertikalen (Mausrad) veraendert werden. Ein Objekt dieser Klasse wird in
       WorldView.java dem ViewingPoint als Behavior hinzugefuegt. Die bisherigen MousBehaviors
       sind entfernt worden
    gegen Version: 	Stand im CVS vom 03.08.2006, Wettbewerbsversion
    Sonstige Voraussetzungen:	keine
    Patchfile: 	orbitPatch.txt

    Motivation:
    Die Steuerung der Kameraposition war bisher ziemlich unpraktisch.

    Ziel:
    Eine komfortablere Steuerung der Kameraposition mit der Maus

    Eine Wechselwirkung mit weiteren Beobachtern des gleichen Universums (im Code vorgesehen)
    wurde nicht getestet, da ich deren Funktionsweise nicht verstanden habe.
    _____________________________________________________________________
    Der WEB.DE SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
    http://smartsurfer.web.de/?mc=100071&distributionid=000000000071

    ### Eclipse Workspace Patch 1.0
    #P ct-Sim
    Index: Changelog.txt
    ===================================================================
    RCS file: /ctbot/ct-Sim/Changelog.txt,v
    retrieving revision 1.24.2.4
    diff -u -r1.24.2.4 Changelog.txt
    --- Changelog.txt	24 Jul 2006 10:38:45 -0000	1.24.2.4
    +++ Changelog.txt	3 Aug 2006 10:04:05 -0000
    @@ -1,5 +1,6 @@
     Changelog fuer c't-Sim
     ======================
    +2006-08-02 Michael Praehofer [mpraehofer@xxxxxx]: Klasse OrbitPlaneBehavior hinzugefuegt, mit der eine intuitive Maussteuerung des Betrachtungspunktes ermoeglicht wird

     2006-07-24 Peter Koenig [pek@xxxxxxxx]: Text der GPL eingefuegt

    Index: ctSim/view/WorldView.java
    ===================================================================
    RCS file: /ctbot/ct-Sim/ctSim/view/WorldView.java,v
    retrieving revision 1.3.2.1
    diff -u -r1.3.2.1 WorldView.java
    --- ctSim/view/WorldView.java	15 Jul 2006 00:00:59 -0000	1.3.2.1
    +++ ctSim/view/WorldView.java	3 Aug 2006 10:04:05 -0000
    @@ -35,19 +35,11 @@
     import javax.media.j3d.BranchGroup;
     import javax.media.j3d.Canvas3D;
     import javax.media.j3d.GraphicsConfigTemplate3D;
    -import javax.media.j3d.Transform3D;
    -import javax.media.j3d.TransformGroup;
     import javax.swing.Box;
     import javax.swing.BoxLayout;
     import javax.swing.JComponent;
     import javax.swing.SwingUtilities;
     import javax.vecmath.Point3d;
    -import javax.vecmath.Vector3d;
    -
    -import com.sun.j3d.utils.behaviors.mouse.MouseBehavior;
    -import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
    -import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
    -import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
     import com.sun.j3d.utils.universe.SimpleUniverse;

     import ctSim.ErrorHandler;
    @@ -71,7 +63,7 @@
     	private Canvas3D worldCanvas;

     	/** Die TransformGroup fuer den Blickpunkt in die 3D-Welt */
    -	private TransformGroup tgViewPlatform;
    +//	private TransformGroup tgViewPlatform;

     //	 Zur Benutzung des org.j3d.ui.navigation-Paketes die Kommentarzeichen entfernen
     //	/** Navigations Objekt */
    @@ -121,38 +113,6 @@
     	 * Erzeugt die GUI
     	 */
     	public void initGUI() {
    -		/* Hole die TransformGroup aus dem SimpleUniverse heraus */
    -		this.tgViewPlatform = this.universe.getViewingPlatform().getViewPlatformTransform() ;
    -
    -		// Zur Benutzung des org.j3d.ui.navigation Paketes den folgenden Block auskommentieren
    -		// Start Block
    -		// Create the root of the branch graph
    -		BranchGroup objRoot = new BranchGroup();
    -        BoundingSphere mouseBounds = null;
    -
    -		mouseBounds = new BoundingSphere(new Point3d(), 1000.0);
    -
    -		MouseRotate myMouseRotate = new MouseRotate(MouseBehavior.INVERT_INPUT);
    -        myMouseRotate.setTransformGroup(this.tgViewPlatform);
    -        myMouseRotate.setSchedulingBounds(mouseBounds);
    -        myMouseRotate.setFactor(0.001d);
    -        objRoot.addChild(myMouseRotate);
    -
    -        MouseTranslate myMouseTranslate = new MouseTranslate(MouseBehavior.INVERT_INPUT);
    -        myMouseTranslate.setTransformGroup(this.tgViewPlatform);
    -        myMouseTranslate.setSchedulingBounds(mouseBounds);
    -        myMouseTranslate.setFactor(0.01d);
    -        objRoot.addChild(myMouseTranslate);
    -
    -        MouseZoom myMouseZoom = new MouseZoom(MouseBehavior.INVERT_INPUT);
    -        myMouseZoom.setTransformGroup(this.tgViewPlatform);
    -        myMouseZoom.setSchedulingBounds(mouseBounds);
    -        myMouseZoom.setFactor(0.05d);
    -        objRoot.addChild(myMouseZoom);
    -
    -        this.universe.addBranchGraph(objRoot);
    -        // End Block
    -
     		try {
     			this.worldCanvas.setVisible(true);
     			this.setVisible(true);
    @@ -190,17 +150,27 @@
     	public void setUniverse(SimpleUniverse uni, float dimX, float dimY) {
     		this.universe = uni;
     		// Blickpunkt so weit zuruecksetzen, dass alles zu sehen ist.
    -
    +		double aspectRatio=1.5; // geschaetzt. Ich weiss nicht wie abfragen.
    +								 // this.universe.getCanvas().getSize() gibt (0,0) zurueck
     		double biggerOne;
    -		if (dimX > dimY)
    +		if (dimX*aspectRatio > dimY) {
     			biggerOne = dimX;
    -		else
    -			biggerOne = dimY;
    -
    -		Transform3D translate = new Transform3D();
    -		this.universe.getViewingPlatform().getViewPlatformTransform().getTransform(translate);
    -		translate.setTranslation(new Vector3d(dimX/2,dimY/2,(biggerOne/2)/Math.tan(this.universe.getViewer().getView().getFieldOfView()/2)));
    -		this.universe.getViewingPlatform().getViewPlatformTransform().setTransform(translate);
    +		} else {
    +			biggerOne = dimY/aspectRatio;
    +		}
    +		this.universe.getViewer().getView().setFrontClipDistance(.01);
    +//		 add orbit behavior to the ViewingPlatform
    +	    // and translate
    +	    FocussingObserverBehavior orbit = new FocussingObserverBehavior(this.universe.getCanvas());
    +	    orbit.setFocusPosition(new Point3d(dimX/2,dimY/2,-2));
    +	    orbit.stopZoom=true;
    +	    orbit.setProportionalZoom(true);
    +	    orbit.setDistancefromFocus(4
    +	    	+(biggerOne/2)/Math.tan(this.universe.getViewer().getView().getFieldOfView()/2));
    +	    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
    +	        1000.0);
    +	    orbit.setSchedulingBounds(bounds);
    +	    this.universe.getViewingPlatform().setViewPlatformBehavior(orbit);
     	}

    Index: ctSim/view/FocussingObserverBehavior.java
    ===================================================================
    RCS file: ctSim/view/FocussingObserverBehavior.java
    diff -N ctSim/view/FocussingObserverBehavior.java
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ ctSim/view/FocussingObserverBehavior.java	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,819 @@
    +/*
    + * (2006-08-02) Adapted by phophermi (mpraehofer@xxxxxx) from
    + * $RCSfile: OrbitBehavior.java,v $
    + *
    + * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * - Redistribution of source code must retain the above copyright
    + *   notice, this list of conditions and the following disclaimer.
    + *
    + * - Redistribution in binary form must reproduce the above copyright
    + *   notice, this list of conditions and the following disclaimer in
    + *   the documentation and/or other materials provided with the
    + *   distribution.
    + *
    + * Neither the name of Sun Microsystems, Inc. or the names of
    + * contributors may be used to endorse or promote products derived
    + * from this software without specific prior written permission.
    + *
    + * This software is provided "AS IS," without a warranty of any
    + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
    + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
    + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
    + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
    + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
    + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
    + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
    + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
    + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
    + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
    + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
    + * POSSIBILITY OF SUCH DAMAGES.
    + *
    + * You acknowledge that this software is not designed, licensed or
    + * intended for use in the design, construction, operation or
    + * maintenance of any nuclear facility.
    + *
    + * $Revision: 1.4 $
    + * $Date: 2006/01/05 04:10:48 $
    + * $State: Exp $
    + */
    +
    +package ctSim.view;
    +
    +import java.awt.event.MouseEvent;
    +import java.awt.AWTEvent;
    +import javax.media.j3d.Transform3D;
    +import javax.media.j3d.Canvas3D;
    +
    +import javax.vecmath.Vector3d;
    +import javax.vecmath.Point3d;
    +import com.sun.j3d.utils.universe.ViewingPlatform;
    +import com.sun.j3d.utils.behaviors.vp.ViewPlatformAWTBehavior;
    +import com.sun.j3d.internal.J3dUtilsI18N;
    +
    +/**
    + * Ermoeglicht ganz aehnlich wie OrbitBehavior eine intuitive Maussteuerung der
    + * Position und Richtung des Betrachters. Sie ist dazu gedacht das Geschehen,
    + * dass sich in einem horizontalen Bereich, z.B. nahe der x-y-Ebene abspielt,
    + * als externer Beobachter verfolgen zu koennen.
    + *
    + * Die Kamera schaut immer auf den Fokus, ein Punkt im Universum.
    + * 1. Der Abstand vom Fokus, distanceFromFocus, kann durch die Zoom-Funktion bei
    + * gedrueckter mittlerer Maustaste veraendert werden.
    + * 2. Die Position relativ zum Fokus, kann durch Rotation um eine im Fokus
    + * senkrecht (in z-Richtung) aufgestellte Drehachse, und durch Rotation um eine
    + * waagrechte Achse durch den Fokus, die immer senkrecht auf der
    + * Verbindungsgeraden Auge-Fokus steht, mit der linken Maustaste veraendert
    + * werden.
    + * 3. Die x- und y-Koordinaten des Fokusses koennen mit der rechten Maustaste
    + * veraendert werden.
    + * 4. Schliesslich kann, falls vorhanden, mit dem Mausrad die z-Komponente der
    + * Fokus-Position eingestellt werden.
    + *
    + * Dies ist eine abgespeckte Version des OrbitBehaviours. Wird ein zweites
    + * Behavior definiert, kann es zu unvorhersehbarem Verhalten fuehren.
    + * Veraendert wurde im wesentlichen nur integrateTransforms().
    + * Das Behavior speichert seinen internen Zustand in den Variablen
    + * distanceFromFocus, xAngle, zAngle, focus.
    + * Die TransformGroup fuer die Kameraposition wird daraus jedesmal neu errechnet.
    + *
    + * Man koennte es vermutlich leicht dahingehend veraendern, dass der Focus dem
    + * Bot folgt, und die Blickrichtung immer der des Bots entspricht.
    + *
    + * Es folgt der noch zutreffende Kommentar aus OrbitBehavior.
    + *
    + * Moves the View around a point of interest when the mouse is dragged with a
    + * mouse button pressed. Includes rotation, zoom, and translation actions.
    + * <p>
    + * This behavior must be added to the ViewingPlatform using the
    + * <code>ViewingPlatform.setViewPlatformBehavior</code> method.
    + * <p>
    + * The rotate action rotates the ViewPlatform around the point of interest when
    + * the mouse is moved with the main mouse button pressed. The rotation is in the
    + * direction of the mouse movement, with a default rotation of 0.01 radians for
    + * each pixel of mouse movement.
    + * <p>
    + * The zoom action moves the ViewPlatform closer to or further from the point of
    + * interest when the mouse is moved with the middle mouse button pressed (or
    + * Alt-main mouse button on systems without a middle mouse button). The default
    + * zoom action is to translate the ViewPlatform 0.01 units for each pixel of
    + * mouse movement. Moving the mouse up moves the ViewPlatform closer, moving the
    + * mouse down moves the ViewPlatform further away.
    + * <p>
    + * By default, the zoom action allows the ViewPlatform to move through the
    + * center of rotation to orbit at a negative radius. The <code>STOP_ZOOM</code>
    + * constructor flag will stop the ViewPlatform at a minimum radius from the
    + * center. The default minimum radius is 0.0 and can be set using the
    + * <code>setMinRadius</code> method.
    + * <p>
    + * The <code>PROPORTIONAL_ZOOM</code> constructor flag changes the zoom action
    + * to move the ViewPlatform proportional to its distance from the center of
    + * rotation. For this mode, the default action is to move the ViewPlatform by 1%
    + * of its distance from the center of rotation for each pixel of mouse movement.
    + * <p>
    + * The translate action translates the ViewPlatform when the mouse is moved with
    + * the right mouse button pressed (Shift-main mouse button on systems without a
    + * right mouse button). The translation is in the direction of the mouse
    + * movement, with a default translation of 0.01 units for each pixel of mouse
    + * movement.
    + * <p>
    + * The sensitivity of the actions can be scaled using the <code>set</code><i>Action</i><code>Factor()</code>
    + * methods which scale the default movement by the factor. The rotate and
    + * translate actions have separate factors for x and y.
    + * <p>
    + * The actions can be reversed using the <code>REVERSE_</code><i>ACTION</i>
    + * constructor flags. The default action moves the ViewPlatform around the
    + * objects in the scene. The <code>REVERSE_</code><i>ACTION</i> flags can
    + * make the objects in the scene appear to be moving in the direction of the
    + * mouse movement.
    + * <p>
    + * The actions can be disabled by either using the <code>DISABLE_</code><i>ACTION</i>
    + * constructor flags or the <code>set</code><i>Action</i><code>Enable</code>
    + * methods.
    + * <p>
    + *
    + * @since Java 3D 1.2.1
    + */
    +public class FocussingObserverBehavior extends ViewPlatformAWTBehavior {
    +
    +	private Point3d focus = new Point3d(0, 0, 0);
    +
    +	private double zAngle = 0;
    +
    +	private double xAngle = 0;
    +
    +	private Vector3d translate = new Vector3d();
    +
    +	private Transform3D target = new Transform3D();
    +
    +	private Transform3D helper = new Transform3D();
    +
    +	private double longitude = 0.0;
    +
    +	private double latitude = 0.0;
    +
    +	private double rollAngle = 0.0;
    +
    +	private double distanceFromFocus = 20.0;
    +
    +	private int mouseX = 0;
    +
    +	private int mouseY = 0;
    +
    +	private double rotXFactor = 1.0;
    +
    +	private double rotYFactor = 1.0;
    +
    +	private double transXFactor = 1.0;
    +
    +	private double transYFactor = 1.0;
    +
    +	private double zoomFactor = 1.0;
    +
    +	private double verticalLiftFactor = .05;
    +
    +	private double xtrans = 0.0;
    +
    +	private double ytrans = 0.0;
    +
    +	public boolean zoomEnabled = true;
    +
    +	public boolean rotateEnabled = true;
    +
    +	public boolean translateEnabled = true;
    +
    +	public boolean reverseRotate = false;
    +
    +	public boolean reverseTrans = false;
    +
    +	public boolean reverseZoom = false;
    +
    +	public boolean stopZoom = false;
    +
    +	private boolean proportionalZoom = false;
    +
    +	private double minRadius = 0.0;
    +
    +	private int leftButton = ROTATE;
    +
    +	private int rightButton = TRANSLATE;
    +
    +	private int middleButton = ZOOM;
    +
    +	/**
    +	 * Constructor flag to reverse the rotate behavior
    +	 */
    +	public static final int REVERSE_ROTATE = 0x010;
    +
    +	/**
    +	 * Constructor flag to reverse the translate behavior
    +	 */
    +	public static final int REVERSE_TRANSLATE = 0x020;
    +
    +	/**
    +	 * Constructor flag to reverse the zoom behavior
    +	 */
    +	public static final int REVERSE_ZOOM = 0x040;
    +
    +	/**
    +	 * Constructor flag to reverse all the behaviors
    +	 */
    +	public static final int REVERSE_ALL = (REVERSE_ROTATE | REVERSE_TRANSLATE | REVERSE_ZOOM);
    +
    +	/**
    +	 * Constructor flag that indicates zoom should stop when it reaches the
    +	 * minimum orbit radius set by setMinRadius(). The minimus radius default is
    +	 * 0.0.
    +	 */
    +	public static final int STOP_ZOOM = 0x100;
    +
    +	/**
    +	 * Constructor flag to disable rotate
    +	 */
    +	public static final int DISABLE_ROTATE = 0x200;
    +
    +	/**
    +	 * Constructor flag to disable translate
    +	 */
    +	public static final int DISABLE_TRANSLATE = 0x400;
    +
    +	/**
    +	 * Constructor flag to disable zoom
    +	 */
    +	public static final int DISABLE_ZOOM = 0x800;
    +
    +	/**
    +	 * Constructor flag to use proportional zoom, which determines how much you
    +	 * zoom based on view's distance from the center of rotation. The percentage
    +	 * of distance that the viewer zooms is determined by the zoom factor.
    +	 */
    +	public static final int PROPORTIONAL_ZOOM = 0x1000;
    +
    +	/**
    +	 * Used to set the fuction for a mouse button to Rotate
    +	 */
    +	private static final int ROTATE = 0;
    +
    +	/**
    +	 * Used to set the function for a mouse button to Translate
    +	 */
    +	private static final int TRANSLATE = 1;
    +
    +	/**
    +	 * Used to set the function for a mouse button to Zoom
    +	 */
    +	private static final int ZOOM = 2;
    +
    +	private static final double NOMINAL_ZOOM_FACTOR = .01;
    +
    +	private static final double NOMINAL_PZOOM_FACTOR = 1.0;
    +
    +	private static final double NOMINAL_ROT_FACTOR = .01;
    +
    +	private static final double NOMINAL_TRANS_FACTOR = .01;
    +
    +	private double rotXMul = NOMINAL_ROT_FACTOR * rotXFactor;
    +
    +	private double rotYMul = NOMINAL_ROT_FACTOR * rotYFactor;
    +
    +	private double transXMul = NOMINAL_TRANS_FACTOR * transXFactor;
    +
    +	private double transYMul = NOMINAL_TRANS_FACTOR * transYFactor;
    +
    +	private double zoomMul = NOMINAL_ZOOM_FACTOR * zoomFactor;
    +
    +	/**
    +	 * Parameterless constructor for this behavior. This is intended for use by
    +	 * ConfiguredUniverse, which requires such a constructor for configurable
    +	 * behaviors. The Canvas3D used to listen for mouse and mouse motion events
    +	 * is obtained from the superclass setViewingPlatform() method.
    +	 *
    +	 * @since Java 3D 1.3
    +	 */
    +	public FocussingObserverBehavior() {
    +		super(MOUSE_LISTENER | MOUSE_MOTION_LISTENER | MOUSE_WHEEL_LISTENER);
    +	}
    +
    +	/**
    +	 * Creates a new OrbitBehavior
    +	 *
    +	 * @param c
    +	 *            The Canvas3D to add the behavior to
    +	 */
    +	public FocussingObserverBehavior(Canvas3D c) {
    +		this(c, 0);
    +	}
    +
    +	/**
    +	 * Creates a new OrbitBehavior
    +	 *
    +	 * @param c
    +	 *            The Canvas3D to add the behavior to
    +	 * @param flags
    +	 *            The option flags
    +	 */
    +	public FocussingObserverBehavior(Canvas3D c, int flags) {
    +		super(c, MOUSE_LISTENER | MOUSE_MOTION_LISTENER | MOUSE_WHEEL_LISTENER
    +				| flags);
    +
    +		if ((flags & DISABLE_ROTATE) != 0) {
    +			rotateEnabled = false;
    +		}
    +		if ((flags & DISABLE_ZOOM) != 0) {
    +			zoomEnabled = false;
    +		}
    +		if ((flags & DISABLE_TRANSLATE) != 0) {
    +			translateEnabled = false;
    +		}
    +		if ((flags & REVERSE_TRANSLATE) != 0) {
    +			reverseTrans = true;
    +		}
    +		if ((flags & REVERSE_ROTATE) != 0) {
    +			reverseRotate = true;
    +		}
    +		if ((flags & REVERSE_ZOOM) != 0) {
    +			reverseZoom = true;
    +		}
    +		if ((flags & STOP_ZOOM) != 0) {
    +			stopZoom = true;
    +		}
    +		if ((flags & PROPORTIONAL_ZOOM) != 0) {
    +			proportionalZoom = true;
    +			zoomMul = NOMINAL_PZOOM_FACTOR * zoomFactor;
    +		}
    +	}
    +
    +	@Override
    +	protected synchronized void processAWTEvents(final AWTEvent[] events) {
    +		motion = false;
    +		for (int i = 0; i < events.length; i++) {
    +			if (events[i] instanceof MouseEvent) {
    +				processMouseEvent((MouseEvent) events[i]);
    +			}
    +		}
    +	}
    +
    +	protected void processMouseEvent(final MouseEvent evt) {
    +
    +		if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
    +			mouseX = evt.getX();
    +			mouseY = evt.getY();
    +			motion = true;
    +		} else if (evt.getID() == MouseEvent.MOUSE_DRAGGED) {
    +			int xchange = evt.getX() - mouseX;
    +			int ychange = evt.getY() - mouseY;
    +			// rotate
    +			if (rotate(evt)) {
    +				if (reverseRotate) {
    +					longitude -= xchange * rotXMul;
    +					latitude -= ychange * rotYMul;
    +				} else {
    +					longitude += xchange * rotXMul;
    +					latitude += ychange * rotYMul;
    +				}
    +			}
    +			// translate
    +			else if (translate(evt)) {
    +				if (reverseTrans) {
    +					xtrans = -xchange * transXMul;
    +					ytrans = +ychange * transYMul;
    +				} else {
    +					xtrans = +xchange * transXMul;
    +					ytrans = -ychange * transYMul;
    +				}
    +			}
    +			// zoom
    +			else if (zoom(evt)) {
    +				doZoomOperations(ychange);
    +			}
    +			mouseX = evt.getX();
    +			mouseY = evt.getY();
    +			motion = true;
    +		} else if (evt.getID() == MouseEvent.MOUSE_RELEASED) {
    +		} else if (evt.getID() == MouseEvent.MOUSE_WHEEL) {
    +			if (evt instanceof java.awt.event.MouseWheelEvent) {
    +				// I/O differenciation is made between
    +				// java.awt.event.MouseWheelEvent.WHEEL_UNIT_SCROLL or
    +				// java.awt.event.MouseWheelEvent.WHEEL_BLOCK_SCROLL so
    +				// that behavior remains stable and not dependent on OS
    +				// settings.
    +				// If getWheelRotation() was used for calculating the zoom,
    +				// the zooming speed could act differently on different
    +				// platforms,
    +				// if, for example, the user sets his mouse wheel to jump 10
    +				// lines
    +				// or a block.
    +				focus.z += (((java.awt.event.MouseWheelEvent) evt)
    +						.getWheelRotation() * verticalLiftFactor);
    +				motion = true;
    +			}
    +		}
    +	}
    +
    +	/*
    +	 * extraction of the zoom algorithms so that there is no code duplication or
    +	 * source 'uglyfication'.
    +	 */
    +	private void doZoomOperations(int ychange) {
    +		if (proportionalZoom) {
    +			if (reverseZoom) {
    +				if ((distanceFromFocus - (zoomMul * ychange
    +						* distanceFromFocus / 100.0)) > minRadius) {
    +					distanceFromFocus -= (zoomMul * ychange
    +							* distanceFromFocus / 100.0);
    +				} else {
    +					distanceFromFocus = minRadius;
    +				}
    +			} else {
    +				if ((distanceFromFocus + (zoomMul * ychange
    +						* distanceFromFocus / 100.0)) > minRadius) {
    +					distanceFromFocus += (zoomMul * ychange
    +							* distanceFromFocus / 100.0);
    +				} else {
    +					distanceFromFocus = minRadius;
    +				}
    +			}
    +		} else {
    +			if (stopZoom) {
    +				if (reverseZoom) {
    +					if ((distanceFromFocus - ychange * zoomMul) > minRadius) {
    +						distanceFromFocus -= ychange * zoomMul;
    +					} else {
    +						distanceFromFocus = minRadius;
    +					}
    +				} else {
    +					if ((distanceFromFocus + ychange * zoomMul) > minRadius) {
    +						distanceFromFocus += ychange * zoomMul;
    +					} else {
    +						distanceFromFocus = minRadius;
    +					}
    +				}
    +			} else {
    +				if (reverseZoom) {
    +					distanceFromFocus -= ychange * zoomMul;
    +				} else {
    +					distanceFromFocus += ychange * zoomMul;
    +				}
    +			}
    +		}
    +	}
    +
    +	/**
    +	 * Sets the ViewingPlatform for this behavior. This method is called by the
    +	 * ViewingPlatform. If a sub-calls overrides this method, it must call
    +	 * super.setViewingPlatform(vp). NOTE: Applications should <i>not</i> call
    +	 * this method.
    +	 */
    +	@Override
    +	public void setViewingPlatform(ViewingPlatform vp) {
    +		super.setViewingPlatform(vp);
    +		if (vp != null) {
    +			integrateTransforms();
    +		}
    +	}
    +
    +
    +	@Override
    +	protected synchronized void integrateTransforms() {
    +		zAngle -= longitude;
    +		xAngle -= latitude;
    +		focus.x -= Math.cos(zAngle) * xtrans - Math.sin(zAngle) * ytrans;
    +		focus.y -= Math.sin(zAngle) * xtrans + Math.cos(zAngle) * ytrans;
    +		target.setIdentity();
    +
    +		translate.set(focus);
    +		helper.setTranslation(translate);
    +		target.mul(helper);
    +
    +		helper.rotZ(zAngle);
    +		target.mul(helper);
    +
    +		helper.rotX(xAngle);
    +		target.mul(helper);
    +
    +		helper.rotZ(rollAngle);
    +		target.mul(helper);
    +
    +		translate.set(0, 0, distanceFromFocus);
    +		helper.setTranslation(translate);
    +		target.mul(helper);
    +
    +		targetTG.setTransform(target);
    +		longitude = 0;
    +		latitude = 0;
    +		xtrans = 0;
    +		ytrans = 0;
    +	}
    +
    +	/**
    +	 * Sets the center around which the View rotates. The default is (0,0,0).
    +	 *
    +	 * @param center
    +	 *            The Point3d to set the center of rotation to
    +	 */
    +	public synchronized void setFocusPosition(Point3d center) {
    +		focus.set(center);
    +	}
    +	/**
    +	 * Places the value of the center around which the View rotates into the
    +	 * Point3d.
    +	 *
    +	 * @param center
    +	 *            The Point3d
    +	 */
    +	public void getFocusPosition(Point3d center) {
    +		center.set(focus);
    +	}
    +
    +	/**
    +	 * Places the distance from the focus into the aragument?
    +	 * @param r
    +	 */
    +	public void getDistanceFromFocus(double r){
    +		r=distanceFromFocus;
    +	}
    +
    +	/**
    +	 * Sets the distance from the focus. default is 20.
    +	 * @param r
    +	 */
    +	public synchronized void setDistancefromFocus(double r){
    +		if (r<minRadius) {
    +			distanceFromFocus=minRadius;
    +		}
    +		else {
    +			distanceFromFocus=r;
    +		}
    +	}
    +
    +	// TODO
    +	// Need to add key factors for Rotate, Translate and Zoom
    +	// Method calls should just update MAX_KEY_ANGLE, KEY_TRANSLATE and
    +	// KEY_ZOOM
    +	//
    +	// Methods also need to correctly set sign of variables depending on
    +	// the Reverse settings.
    +
    +	/**
    +	 * Sets the rotation x and y factors. The factors are used to determine how
    +	 * many radians to rotate the view for each pixel of mouse movement. The
    +	 * view is rotated factor * 0.01 radians for each pixel of mouse movement.
    +	 * The default factor is 1.0.
    +	 *
    +	 * @param xfactor
    +	 *            The x movement multiplier
    +	 * @param yfactor
    +	 *            The y movement multiplier
    +	 */
    +	public synchronized void setRotFactors(double xfactor, double yfactor) {
    +		rotXFactor = xfactor;
    +		rotYFactor = yfactor;
    +		rotXMul = NOMINAL_ROT_FACTOR * xfactor;
    +		rotYMul = NOMINAL_ROT_FACTOR * yfactor;
    +	}
    +
    +	/**
    +	 * Sets the rotation x factor. The factors are used to determine how many
    +	 * radians to rotate the view for each pixel of mouse movement. The view is
    +	 * rotated factor * 0.01 radians for each pixel of mouse movement. The
    +	 * default factor is 1.0.
    +	 *
    +	 * @param xfactor
    +	 *            The x movement multiplier
    +	 */
    +	public synchronized void setRotXFactor(double xfactor) {
    +		rotXFactor = xfactor;
    +		rotXMul = NOMINAL_ROT_FACTOR * xfactor;
    +	}
    +
    +	/**
    +	 * Sets the rotation y factor. The factors are used to determine how many
    +	 * radians to rotate the view for each pixel of mouse movement. The view is
    +	 * rotated factor * 0.01 radians for each pixel of mouse movement. The
    +	 * default factor is 1.0.
    +	 *
    +	 * @param yfactor
    +	 *            The y movement multiplier
    +	 */
    +	public synchronized void setRotYFactor(double yfactor) {
    +		rotYFactor = yfactor;
    +		rotYMul = NOMINAL_ROT_FACTOR * yfactor;
    +	}
    +
    +	/**
    +	 * Sets the translation x and y factors. The factors are used to determine
    +	 * how many units to translate the view for each pixel of mouse movement.
    +	 * The view is translated factor * 0.01 units for each pixel of mouse
    +	 * movement. The default factor is 1.0.
    +	 *
    +	 * @param xfactor
    +	 *            The x movement multiplier
    +	 * @param yfactor
    +	 *            The y movement multiplier
    +	 */
    +	public synchronized void setTransFactors(double xfactor, double yfactor) {
    +		transXFactor = xfactor;
    +		transYFactor = yfactor;
    +		transXMul = NOMINAL_TRANS_FACTOR * xfactor;
    +		transYMul = NOMINAL_TRANS_FACTOR * yfactor;
    +	}
    +
    +	/**
    +	 * Sets the translation x factor. The factors are used to determine how many
    +	 * units to translate the view for each pixel of mouse movement. The view is
    +	 * translated factor * 0.01 units for each pixel of mouse movement. The
    +	 * default factor is 1.0.
    +	 *
    +	 * @param xfactor
    +	 *            The x movement multiplier
    +	 */
    +	public synchronized void setTransXFactor(double xfactor) {
    +		transXFactor = xfactor;
    +		transXMul = NOMINAL_TRANS_FACTOR * xfactor;
    +	}
    +
    +	/**
    +	 * Sets the translation y factor. The factors are used to determine how many
    +	 * units to translate the view for each pixel of mouse movement. The view is
    +	 * translated factor * 0.01 units for each pixel of mouse movement. The
    +	 * default factor is 1.0.
    +	 *
    +	 * @param yfactor
    +	 *            The y movement multiplier
    +	 */
    +	public synchronized void setTransYFactor(double yfactor) {
    +		transYFactor = yfactor;
    +		transYMul = NOMINAL_TRANS_FACTOR * yfactor;
    +	}
    +
    +	/**
    +	 * Sets the zoom factor. The factor is used to determine how many units to
    +	 * zoom the view for each pixel of mouse movement. The view is zoomed factor *
    +	 * 0.01 units for each pixel of mouse movement. For proportional zoom, the
    +	 * view is zoomed factor * 1% of the distance from the center of rotation
    +	 * for each pixel of mouse movement. The default factor is 1.0.
    +	 *
    +	 * @param zfactor
    +	 *            The movement multiplier
    +	 */
    +	public synchronized void setZoomFactor(double zfactor) {
    +		zoomFactor = zfactor;
    +		if (proportionalZoom) {
    +			zoomMul = NOMINAL_PZOOM_FACTOR * zfactor;
    +		} else {
    +			zoomMul = NOMINAL_ZOOM_FACTOR * zfactor;
    +		}
    +	}
    +
    +	/**
    +	 * Returns the x rotation movement multiplier
    +	 *
    +	 * @return The movement multiplier for x rotation
    +	 */
    +	public double getRotXFactor() {
    +		return rotXFactor;
    +	}
    +
    +	/**
    +	 * Returns the y rotation movement multiplier
    +	 *
    +	 * @return The movement multiplier for y rotation
    +	 */
    +	public double getRotYFactor() {
    +		return rotYFactor;
    +	}
    +
    +	/**
    +	 * Returns the x translation movement multiplier
    +	 *
    +	 * @return The movement multiplier for x translation
    +	 */
    +	public double getTransXFactor() {
    +		return transXFactor;
    +	}
    +
    +	/**
    +	 * Returns the y translation movement multiplier
    +	 *
    +	 * @return The movement multiplier for y translation
    +	 */
    +	public double getTransYFactor() {
    +		return transYFactor;
    +	}
    +
    +	/**
    +	 * Returns the zoom movement multiplier
    +	 *
    +	 * @return The movement multiplier for zoom
    +	 */
    +	public double getZoomFactor() {
    +		return zoomFactor;
    +	}
    +
    +	boolean rotate(MouseEvent evt) {
    +		if (rotateEnabled) {
    +			if ((leftButton == ROTATE)
    +					&& (!evt.isAltDown() && !evt.isMetaDown())) {
    +				return true;
    +			}
    +			if ((middleButton == ROTATE)
    +					&& (evt.isAltDown() && !evt.isMetaDown())) {
    +				return true;
    +			}
    +			if ((rightButton == ROTATE)
    +					&& (!evt.isAltDown() && evt.isMetaDown())) {
    +				return true;
    +			}
    +		}
    +		return false;
    +	}
    +
    +	boolean zoom(MouseEvent evt) {
    +		if (zoomEnabled) {
    +			if (evt instanceof java.awt.event.MouseWheelEvent) {
    +				return true;
    +			}
    +			if ((leftButton == ZOOM) && (!evt.isAltDown() && !evt.isMetaDown())) {
    +				return true;
    +			}
    +			if ((middleButton == ZOOM)
    +					&& (evt.isAltDown() && !evt.isMetaDown())) {
    +				return true;
    +			}
    +			if ((rightButton == ZOOM) && (!evt.isAltDown() && evt.isMetaDown())) {
    +				return true;
    +			}
    +		}
    +		return false;
    +	}
    +
    +	boolean translate(MouseEvent evt) {
    +		if (translateEnabled) {
    +			if ((leftButton == TRANSLATE)
    +					&& (!evt.isAltDown() && !evt.isMetaDown())) {
    +				return true;
    +			}
    +			if ((middleButton == TRANSLATE)
    +					&& (evt.isAltDown() && !evt.isMetaDown())) {
    +				return true;
    +			}
    +			if ((rightButton == TRANSLATE)
    +					&& (!evt.isAltDown() && evt.isMetaDown())) {
    +				return true;
    +			}
    +		}
    +		return false;
    +	}
    +
    +	/**
    +	 * Sets the minimum radius for the OrbitBehavior. The zoom will stop at this
    +	 * distance from the center of rotation. The default is 0.0. The minimum
    +	 * will have no affect if the STOP_ZOOM constructor flag is not set.
    +	 *
    +	 * @param r
    +	 *            the minimum radius
    +	 * @exception IllegalArgumentException
    +	 *                if the radius is less than 0.0
    +	 */
    +	public synchronized void setMinRadius(double r) {
    +		if (r < 0.0) {
    +			throw new IllegalArgumentException(J3dUtilsI18N
    +					.getString("OrbitBehavior1"));
    +		}
    +		minRadius = r;
    +	}
    +
    +
    +	/**
    +	 * Returns the minimum orbit radius. The zoom will stop at this distance
    +	 * from the center of rotation if the STOP_ZOOM constructor flag is set.
    +	 *
    +	 * @return the minimum radius
    +	 */
    +	public double getMinRadius() {
    +		return minRadius;
    +	}
    +
    +
    +	/**
    +	 * Set proportional zoom behavior. The default is false.
    +	 *
    +	 * @param state
    +	 *            if true, use proportional zoom behavior
    +	 * @since Java 3D 1.3
    +	 */
    +	public synchronized void setProportionalZoom(boolean state) {
    +		proportionalZoom = state;
    +
    +		if (state) {
    +			zoomMul = NOMINAL_PZOOM_FACTOR * zoomFactor;
    +		} else {
    +			zoomMul = NOMINAL_ZOOM_FACTOR * zoomFactor;
    +		}
    +	}
    +}

- Voriger (Datum): [ct-bot] Video/Bilder Material, Markus Stöber
- Nächster (Datum): [ct-bot] Maussensor, Daniel Morell
- Voriger (Thread): [ct-bot] Video/Bilder Material, Markus Stöber
- Nächster (Thread): [ct-bot] BUG Nach einem Rennen, Markus Stöber
- Indizes:
  - Datum
  - Thread