/*
* Open Source Physics software is free software as described near the bottom of this code file.
*
* For additional information and documentation on Open Source Physics please see:
* <http://www.opensourcephysics.org/>
*/
package org.opensourcephysics.display3d.core;
import org.opensourcephysics.controls.XMLControl;
/**
* <p>Title: Camera</p>
* <p>Description: This class provides access to the position of the camera,
* its focus point and its distance to the projection screen that are used
* to view the 3D scenes. The camera can also be rotated around the line
* of sight (i.e. the line which conects the camera with the focus point).</p>
* <p>The camera position can be set using either the desired X,Y,Z coordinates
* or spherical coordinates around the focus point. This makes it
* easy to rotate the scene both horizontally and vertically (around the focus).</p>
* <p>Panning can be achieved by moving the focus point to one side.</p>
* <p>Zooming is done increasing (positive zoom) or decreasing the distance
* between the camera and the projection screen.</p>
* <p> The projection screen is always normal to the line of sight and has
* its origin at the intersection of this line with the screen itself.</p>
* <p>The camera provides fives different modes of projecting points in space
* to the screen. Two modes are truly three-dimensional. The other three are
* planar modes.
*
* @author Francisco Esquembre
* @version June 2005
* @see #setProjectionMode(int)
*/
public interface Camera {
static public final int MODE_PLANAR_XY = 0;
static public final int MODE_PLANAR_XZ = 1;
static public final int MODE_PLANAR_YZ = 2;
static public final int MODE_PERSPECTIVE_OFF = 3;
static public final int MODE_PERSPECTIVE_ON = 4;
static public final int MODE_NO_PERSPECTIVE = 10;
static public final int MODE_PERSPECTIVE = 11;
/**
* Sets one of the projecting modes. Possible values are:
* <ul>
* <li>MODE_PERSPECTIVE or MODE_PERSPECTIVE_ON: 3D mode in which objects far away look smaller.</li>
* <li>MODE_NO_PERSPECTIVE or MODE_PERSPECTIVE_OFF: 3D mode in which distance doesn't affect the size
* of the objects</li>
* <li>MODE_PLANAR_XY: 2D mode in which only the X and Y coordinates are displayed.</li>
* <li>MODE_PLANAR_XZ: 2D mode in which only the X and Z coordinates are displayed.</li>
* <li>MODE_PLANAR_YZ: 2D mode in which only the Y and Z coordinates are displayed.</li>
* </ul>
* <p>Changing the mode does not reset the camera.
* @param mode int
*/
public void setProjectionMode(int mode);
/**
* Gets the projecting mode of the camera.
* @return int
* #see #setProjectionMode(int)
*/
public int getProjectionMode();
/**
* Resets the camera to the default.
* The camera is placed along the X direction, at a reasonable distance
* from the center of the panel, which becomes the focus, and is not rotated.
* The screen is also placed at a reasonable distance so that to view the
* whole scene.
*/
public void reset();
/**
* Sets the position of the camera.
* @param x double
* @param y double
* @param z double
*/
public void setXYZ(double x, double y, double z);
/**
* Sets the position of the camera.
* @param point double[]
*/
public void setXYZ(double[] point);
/**
* Returns the camera X coordinate
* @return double the X coordinate of the camera position
*/
public double getX();
/**
* Returns the camera Y coordinate
* @return double the Y coordinate of the camera position
*/
public double getY();
/**
* Returns the camera Z coordinate
* @return double the Z coordinate of the camera position
*/
public double getZ();
/**
* Sets the focus point of the camera. That it, the point in space
* at which the camera is pointing.
* @param x double
* @param y double
* @param z double
*/
public void setFocusXYZ(double x, double y, double z);
/**
* Sets the focus of the camera.
* @param point double[]
*/
public void setFocusXYZ(double[] point);
/**
* Returns the focus X coordinate
* @return double the X coordinate of the focus position
*/
public double getFocusX();
/**
* Returns the focus Y coordinate
* @return double the Y coordinate of the focus position
*/
public double getFocusY();
/**
* Returns the focus Z coordinate
* @return double the Z coordinate of the focus position
*/
public double getFocusZ();
/**
* Sets the angle that the camera is rotated along the line of sight.
* Default is 0.
* @param angle double The angle in radians
*/
public void setRotation(double angle);
/**
* Returns the angle that the camera is rotated along the line of sight.
* @return double
*/
public double getRotation();
/**
* Sets the distance from the camera to the projecting screen.
* @param distance double
*/
public void setDistanceToScreen(double distance);
/**
* Returns the distance from the camera to the projecting screen.
* @return double
*/
public double getDistanceToScreen();
/**
* Set the azimuthal (horizontal) angle of the camera position in spherical
* coordinates with respect to the focus point. A value of 0 places the
* camera in the XZ plane.
* @param angle the desired angle in radians
*/
public void setAzimuth(double angle);
/**
* Get the horizontal angle of the camera position in spherical coordinates
* with respect to the focus point. A value of 0 means the camera is in the
* XZ plane.
* @return double
*/
public double getAzimuth();
/**
* Set the elevation (vertical) angle of the camera position in spherical
* coordinates with respect to the focus point. A value of 0 places the
* camera is in the XY plane.
* @param angle the desired angle in radians in the range [-Math.PI/2,Math.PI/2]
*/
public void setAltitude(double angle);
/**
* Get the elevation (vertical) angle of the camera position in spherical
* coordinates with respect to the focus point. A value of 0 means the
* camera is in the XY plane.
* @return double
*/
public double getAltitude();
/**
* Set the angles of the camera position in spherical coordinates
* with respect to the focus point.
* @param azimuth the desired azimuthal angle in radians
* @param altitude the desired altitude angle in radians in the range [-Math.PI/2,Math.PI/2]
*/
public void setAzimuthAndAltitude(double azimuth, double altitude);
/**
* Returns the transfomation used to project (x,y,z) points in space
* to points of the form (a,b,distance). (a,b) are the coordinates
* of the projected point in the screen coordinate system. distance
* is a measure of how far the point is from the camera. Typically,
* points in the plane parallel to the screen at the focus point
* are at distance=1.
* @return double
*/
public org.opensourcephysics.numerics.Transformation getTransformation();
/**
* Copies its configuration from another camera
* @param camera
*/
public void copyFrom(Camera camera);
// ----------------------------------------------------
// XML loader
// ----------------------------------------------------
abstract static class Loader implements org.opensourcephysics.controls.XML.ObjectLoader {
abstract public Object createObject(XMLControl control);
public void saveObject(XMLControl control, Object obj) {
Camera camera = (Camera) obj;
control.setValue("projection mode", camera.getProjectionMode()); //$NON-NLS-1$
control.setValue("x", camera.getX()); //$NON-NLS-1$
control.setValue("y", camera.getY()); //$NON-NLS-1$
control.setValue("z", camera.getZ()); //$NON-NLS-1$
control.setValue("focus x", camera.getFocusX()); //$NON-NLS-1$
control.setValue("focus y", camera.getFocusY()); //$NON-NLS-1$
control.setValue("focus z", camera.getFocusZ()); //$NON-NLS-1$
control.setValue("rotation", camera.getRotation()); //$NON-NLS-1$
control.setValue("distance to screen", camera.getDistanceToScreen()); //$NON-NLS-1$
}
public Object loadObject(XMLControl control, Object obj) {
Camera camera = (Camera) obj;
camera.setProjectionMode(control.getInt("projection mode")); //$NON-NLS-1$
double x = control.getDouble("x"); //$NON-NLS-1$
double y = control.getDouble("y"); //$NON-NLS-1$
double z = control.getDouble("z"); //$NON-NLS-1$
camera.setXYZ(x, y, z);
x = control.getDouble("focus x"); //$NON-NLS-1$
y = control.getDouble("focus y"); //$NON-NLS-1$
z = control.getDouble("focus z"); //$NON-NLS-1$
camera.setFocusXYZ(x, y, z);
camera.setRotation(control.getDouble("rotation")); //$NON-NLS-1$
camera.setDistanceToScreen(control.getDouble("distance to screen")); //$NON-NLS-1$
return camera;
}
}
}
/*
* Open Source Physics software is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License (GPL) as
* published by the Free Software Foundation; either version 2 of the License,
* or(at your option) any later version.
* Code that uses any portion of the code in the org.opensourcephysics package
* or any subpackage (subdirectory) of this package must must also be be released
* under the GNU GPL license.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
* or view the license online at http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2007 The Open Source Physics project
* http://www.opensourcephysics.org
*/