/******************************************************************************* * Copyright (c) 2007- VTT Technical Research Centre of Finland. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.proconf.g3d.common; import javax.vecmath.AxisAngle4d; import javax.vecmath.Matrix3d; import javax.vecmath.Vector3d; import org.simantics.proconf.g3d.base.VecmathJmeTools; import com.jme.renderer.Camera; /** * Orbital camera *

* Modified version of fi.vtt.proconf.webmon.graphics3d.utils.OrbitalCamera
* Using floats instead of double
*

* * * @author Marko Luukkainen * */ public class OrbitalCamera { private Vector3d up = new Vector3d(0.0,1.0,0.0); private static Vector3d up2 = new Vector3d(0.0,0.0,-1.0); private static double minDistance = 0.5; private Vector3d target = new Vector3d(); private Vector3d cameraPos = new Vector3d(10.0,0.0,0.0); public void translate(Vector3d v) { target.add(v); cameraPos.add(v); } public void rotateAroundTarget(Vector3d axis, double angle) { Vector3d temp = new Vector3d(cameraPos); temp.sub(target); Matrix3d rotation = new Matrix3d(); rotation.set(new AxisAngle4d(axis,angle)); rotation.transform(temp); temp.add(target); cameraPos.set(temp); } public Vector3d getUnNormalizedHeading() { Vector3d heading = new Vector3d(target); heading.sub(cameraPos); return heading; } public Vector3d getUnNormalizedRight() { Vector3d heading = getUnNormalizedHeading(); Vector3d right = new Vector3d(); right.cross(heading,up); if (right.lengthSquared() < 0.01) right.cross(heading,up2); return right; } public double getDistanceToTarget() { Vector3d t = new Vector3d(target); t.sub(cameraPos); return t.length(); } public void moveToTarget(double distance) { Vector3d heading = getUnNormalizedHeading(); double length = heading.length(); if (length + distance < minDistance) { // cannot move closer return; } heading.scale(distance / length); //normalizing and scaling by distance cameraPos.add(heading); } public void moveScaledToTarget(double s) { Vector3d heading = getUnNormalizedHeading(); double currentLength = heading.length(); double length = currentLength * (1.0 - s);// heading.length(); if (length < minDistance) { s = -minDistance / currentLength + 1.0; } heading.scale(s); //normalizing and scaling by distance cameraPos.add(heading); } public void rotateUp(double angle) { Vector3d right = getUnNormalizedRight(); double length = right.length(); // TODO : better handling of singular cases if (length > 0.01) right.scale(1.0/length); else right.set(-1.0,0.0,0.0); rotateAroundTarget(right,angle); } public void rotateRight(double angle) { rotateAroundTarget(up,angle); } public void moveRight(double length) { Vector3d right = getUnNormalizedRight(); right.normalize(); right.scale(length); translate(right); } public void moveUp(double length) { Vector3d u = new Vector3d(up); u.scale(length); translate(u); } public void moveFront(double length) { Vector3d right = getUnNormalizedRight(); Vector3d front = new Vector3d(); front.cross(up,right); front.normalize(); front.scale(length); translate(front); } public void updateCamera() { Vector3d t = new Vector3d(cameraPos); t.sub(target); t.normalize(); cam.setLocation(VecmathJmeTools.get(cameraPos)); if (Math.abs(t.dot(up)) > 0.99) { cam.lookAt(VecmathJmeTools.get(target), VecmathJmeTools.get(up2)); } else { cam.lookAt(VecmathJmeTools.get(target), VecmathJmeTools.get(up)); } cam.update(); cam.apply(); } /** * @return Returns the cameraPos. */ public Vector3d getCameraPos() { return cameraPos; } /** * @param cameraPos The cameraPos to set. */ public void setCameraPos(Vector3d cameraPos) { this.cameraPos = cameraPos; } /** * @return Returns the target. */ public Vector3d getTarget() { return target; } /** * @param target The target to set. */ public void setTarget(Vector3d target) { this.target = target; } public void setCameraPosRelativeToTarget(Vector3d targetToCam) { targetToCam.add(target); setCameraPos(targetToCam); } public void setUp(Vector3d v) { up.set(v); } public Vector3d getUp() { return up; } public void setDefaultUp() { up.set(0.0,1.0,0.0); } private Camera cam; public void setCamera(Camera cam) { this.cam = cam; } }