Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
package com.marginallyclever.makelangelo.preview;
import com.marginallyclever.util.PreferencesHelper;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point2d;
/**
* All information about the position and zoom level of the virtual eye looking through the PreviewPanel at the robot/art
* @author Dan Royer
*
*/
public class Camera {
public static final float CAMERA_ZOOM_MAX = 1000.0f;
public static final float CAMERA_ZOOM_MIN = 0.25f;
public static final double ZOOM_STEP_SIZE = 0.15;
// scale + position
private double offsetX = 0.0;
private double offsetY = 0.0;
private double zoom = 1.0;
// window size (for aspect ratio?)
private double width, height;
private double fovY = 60;
private double nearZ = 1;
private double farZ = 1000;
public Camera() {}
/**
* Reposition the camera
* @param dx change horizontally
* @param dy change vertically
*/
public void moveRelative(double dx, double dy) {
double scale = PreferencesHelper.getPreferenceNode(PreferencesHelper.MakelangeloPreferenceKey.GRAPHICS).getInt("dragSpeed", 1);
offsetX += dx * scale / zoom;
offsetY += dy * scale / zoom;
}
private void limitCameraZoom() {
if(zoom< CAMERA_ZOOM_MIN) zoom= CAMERA_ZOOM_MIN;
if(zoom> CAMERA_ZOOM_MAX) zoom= CAMERA_ZOOM_MAX;
}
// scale the picture of the robot to fake a zoom.
public void zoom(int amount) {
zoom(amount, new Point2d());
}
/**
* Returns the input converted to world-space coordinates.
* @param input a point relative to the center of the camera view.
* @return the input converted to world-space coordinates.
*/
public Point2d screenToWorldSpace(Point2d input) {
Point2d output = new Point2d();
output.x = input.x/zoom + offsetX;
output.y = input.y/zoom + offsetY;
return output;
}
/**
* Scale the picture of the robot at the indicated point
* @param amount amount to zoom
* @param cursor center of zoom, relative to camera.
*/
public void zoom(int amount, Point2d cursor) {
Point2d before = screenToWorldSpace(cursor);
zoom -= (double)amount * ZOOM_STEP_SIZE;
limitCameraZoom();
Point2d after = screenToWorldSpace(cursor);
offsetX -= after.x - before.x;
offsetY -= after.y - before.y;
}
// scale the picture of the robot to fake a zoom.
public void zoomToFit(double w,double h) {
offsetX = 0;
offsetY = 0;
zoom = Math.max(w/h, h/w);
limitCameraZoom();
}
public double getX() {
return offsetX;
}
public double getY() {
return offsetY;
}
public double getZoom() {
return zoom;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
/**
* return the finite perspective matrix for the camera.
* @param width width of the viewport
* @param height height of the viewport
* @return the perspective projection matrix
*/
public Matrix4d getProjectionMatrix(int width,int height) {
double aspect = (double)width / (double)height;
var far = getFarZ();
var near = getNearZ();
var m = new Matrix4d();
double f = 1.0 / Math.tan(Math.toRadians(fovY) / 2.0);
m.m00 = f / aspect;
m.m11 = f;
m.m22 = -(far + near) / (far - near);
m.m32 = -1.0;
m.m23 = -(2.0 * far * near) / (far - near);
m.m33 = 0.0;
return m;
}
public Matrix4d getOrthographicMatrix(int width, int height) {
Matrix4d matrix = new Matrix4d();
double h = height / 2.0;
double w = width / 2.0;
double left = -w;
double right = w;
double bottom = -h;
double top = h;
double near = nearZ; // Near plane
double far = farZ; // Far plane
matrix.m00 = 2.0 / (right - left);
matrix.m11 = 2.0 / (top - bottom);
matrix.m22 = -2.0 / (far - near);
matrix.m33 = 1.0;
matrix.m30 = -(right + left) / (right - left);
matrix.m31 = -(top + bottom) / (top - bottom);
matrix.m32 = -(far + near) / (far - near);
return matrix;
}
public Matrix4d getViewMatrix() {
Matrix4d matrix = new Matrix4d();
matrix.setIdentity();
matrix.m00 = zoom;
matrix.m11 = zoom;
matrix.m03 = -offsetX * zoom;
matrix.m13 = offsetY * zoom;
matrix.m23 = -1;
return matrix;
}
public double getFovY() {
return fovY;
}
public void setFovY(double fovY) {
this.fovY = fovY;
}
public double getNearZ() {
return nearZ;
}
public void setNearZ(double nearZ) {
this.nearZ = nearZ;
}
public double getFarZ() {
return farZ;
}
public void setFarZ(double farZ) {
this.farZ = farZ;
}
}
f1d2d2224This file is pinned to the selected release. Download the original to open it in your design tool.