Commit 8b2c68c5 authored by Matthias Betz's avatar Matthias Betz
Browse files

add panning with mouse btn 3

parent 7ba987f3
......@@ -19,6 +19,7 @@ import java.nio.FloatBuffer;
import org.joml.Math;
import org.joml.Matrix4f;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryUtil;
......@@ -27,24 +28,21 @@ public class Camera {
private static final float MIN_DISTANCE = 1f;
private static final float PI = (float) Math.PI;
private Matrix4f projMatrix;
Matrix4f projMatrix;
private Matrix4f viewMatrix;
private Matrix4f projViewMatrix;
private float rotateAroundX = 2f;
private float rotateAroundZ = 3f;
private float rotateAroundZ = 0f;
private Vector3f eyeVec = new Vector3f();
private Vector3f center = new Vector3f();
private Vector3f eyePos = new Vector3f();
private Vector3f centerPos = new Vector3f();
private Vector3f up = new Vector3f();
private float distance = 5;
private static final float SCROLL_PERCENTAGE = 0.1f;
private UniformLocation uniformLocation;
private FloatBuffer matrixBuffer = MemoryUtil.memAllocFloat(16);
private boolean isOrtho = false;
UniformLocation uniformLocation;
FloatBuffer matrixBuffer = MemoryUtil.memAllocFloat(16);
public Camera(Shader shader) {
uniformLocation = shader.getUniformLocation("projViewModel");
......@@ -52,69 +50,60 @@ public class Camera {
viewMatrix = new Matrix4f();
projMatrix = new Matrix4f();
up.z = 1;
eyePos.x = distance;
}
public void reshape(int width, int height, float distance) {
if (isOrtho) {
projMatrix.setOrtho(0, width, height, 0, 0, distance);
} else {
// 90 degree fow
float fow = PI / 2f;
float aspectRatio = (float) width / height;
projMatrix.setPerspective(fow, aspectRatio, MIN_DISTANCE, distance);
}
// 90 degree fow
float fow = PI / 2f;
float aspectRatio = (float) width / height;
projMatrix.setPerspective(fow, aspectRatio, MIN_DISTANCE, distance);
updateMatrix();
}
public void setOrtho(boolean isOrtho) {
this.isOrtho = isOrtho;
}
private void updateMatrix() {
// view matrix
if (isOrtho) {
projMatrix.get(matrixBuffer);
} else {
float sx = Math.sin(rotateAroundX);
float cx = Math.cos(rotateAroundX);
float sy = Math.sin(rotateAroundZ);
float cy = Math.cos(rotateAroundZ);
float sxDistance = distance * sx;
eyeVec.x = sxDistance * cy;
eyeVec.y = sxDistance * sy;
eyeVec.z = distance * cx;
viewMatrix.identity();
viewMatrix.translate(0, 0, distance);
viewMatrix.lookAt(eyeVec, center, up);
projMatrix.mul(viewMatrix, projViewMatrix);
// model matrix is identity
projViewMatrix.get(matrixBuffer);
}
viewMatrix.setLookAt(eyePos, centerPos, up);
projMatrix.mul(viewMatrix, projViewMatrix);
// model matrix is identity
projViewMatrix.get(matrixBuffer);
uniformLocation.uploadMat4(matrixBuffer);
}
public void drag(double dragDiffX, double dragDiffY) {
rotateAroundX += dragDiffY / 500f;
rotateAroundZ -= dragDiffX / 500f;
if (rotateAroundX > Math.PI) {
rotateAroundX = (float) Math.PI - 0.001f;
} else if (rotateAroundX < 0.001) {
rotateAroundX = (float) 0.001;
public void rotate(double dragDiffX, double dragDiffY) {
float rotationX = (float) (-dragDiffX / 500f);
float rotationZ = (float) (dragDiffY / 500f);
float tempRotationValue = rotateAroundZ + rotationZ;
if (tempRotationValue < -Math.PI / 2 + 0.0001 || tempRotationValue > Math.PI / 2 - 0.0001) {
// to close to 90 degree, stop rotation
rotationZ = 0;
}
rotateAroundZ += rotationZ;
Vector3f res = new Vector3f();
eyePos.sub(centerPos, res);
res.rotateZ(rotationX);
Vector3f rotAxis = new Vector3f(res.x, res.y, res.z + 5);
rotAxis.cross(res);
rotAxis.normalize();
res.rotateAxis(rotationZ, rotAxis.x, rotAxis.y, rotAxis.z);
centerPos.add(res, eyePos);
updateMatrix();
}
public void setDistance(float distance) {
this.distance = distance;
Vector3f res = new Vector3f();
eyePos.sub(centerPos, res);
res.normalize().mul(distance);
centerPos.add(res, eyePos);
updateMatrix();
}
public void scroll(int scroll) {
int addedDistance = (int) (distance * scroll * SCROLL_PERCENTAGE);
distance += addedDistance;
updateMatrix();
setDistance(distance);
}
public void free() {
......@@ -122,6 +111,27 @@ public class Camera {
}
public void move(double dragDiffX, double dragDiffY) {
Vector3f res = new Vector3f();
centerPos.sub(eyePos, res);
Vector2f dir = new Vector2f(res.x, res.y);
dir.normalize();
Vector2f yDrag = new Vector2f();
dir.mul((float) -dragDiffY * 0.5f, yDrag);
// handle diffY
centerPos.add(yDrag.x, yDrag.y, 0);
eyePos.add(yDrag.x, yDrag.y, 0);
// handle diffX
float temp = dir.x;
dir.x = dir.y;
dir.y = -temp;
dir.mul((float) dragDiffX * 0.5f);
centerPos.add(dir.x, dir.y, 0);
eyePos.add(dir.x, dir.y, 0);
updateMatrix();
}
}
......@@ -68,8 +68,6 @@ import org.lwjgl.system.MemoryUtil;
import org.lwjgl.util.nfd.NativeFileDialog;
import org.xml.sax.SAXException;
import com.jogamp.opengl.GLException;
import de.hft.stuttgart.citygml.viewer.datastructure.BoundingBox;
import de.hft.stuttgart.citygml.viewer.datastructure.Polygon;
import de.hft.stuttgart.citygml.viewer.math.Vector3d;
......@@ -118,7 +116,7 @@ public class CityGMLViewer {
public static void main(String[] args) {
File f = null;
f = parseArguments(args, f);
try {
setupWindow(f, useDebug);
} catch (Exception e) {
......@@ -175,7 +173,7 @@ public class CityGMLViewer {
}
}
}
// default values for missing parameters
if (colorsPath == null) {
colorsPath = Paths.get("color.properties");
......@@ -186,7 +184,7 @@ public class CityGMLViewer {
if (f == null) {
f = showFileChooserDialog();
}
colorMapper = new PolygonColorMapper(mappingPath);
colorHandler = new ColorHandler(colorsPath);
return f;
......@@ -315,7 +313,7 @@ public class CityGMLViewer {
}
} else if (button == GLFW.GLFW_MOUSE_BUTTON_1 && action == GLFW.GLFW_RELEASE) {
mouse1Down = false;
} else if (button == GLFW.GLFW_MOUSE_BUTTON_2 && action == GLFW.GLFW_PRESS) {
} else if (button == GLFW.GLFW_MOUSE_BUTTON_RIGHT && action == GLFW.GLFW_PRESS) {
mouse2Down = true;
try (MemoryStack stack = MemoryStack.stackPush()) {
DoubleBuffer xBuffer = stack.mallocDouble(1);
......@@ -324,7 +322,7 @@ public class CityGMLViewer {
x = xBuffer.get(0);
y = yBuffer.get(0);
}
} else if (button == GLFW.GLFW_MOUSE_BUTTON_2 && action == GLFW.GLFW_RELEASE) {
} else if (button == GLFW.GLFW_MOUSE_BUTTON_RIGHT && action == GLFW.GLFW_RELEASE) {
mouse2Down = false;
}
}
......@@ -340,21 +338,17 @@ public class CityGMLViewer {
GLFW.glfwSetCursorPosCallback(windowId, (window, xPos, yPos) -> {
if (mouse1Down) {
try (MemoryStack stack = MemoryStack.stackPush()) {
double dragDiffX = xPos - x;
double dragDiffY = yPos - y;
camera.drag(dragDiffX, dragDiffY);
x = xPos;
y = yPos;
}
double dragDiffX = xPos - x;
double dragDiffY = yPos - y;
camera.rotate(dragDiffX, dragDiffY);
x = xPos;
y = yPos;
} else if (mouse2Down) {
try (MemoryStack stack = MemoryStack.stackPush()) {
double dragDiffX = xPos - x;
double dragDiffY = yPos - y;
camera.move(dragDiffX, dragDiffY);
x = xPos;
y = yPos;
}
double dragDiffX = xPos - x;
double dragDiffY = yPos - y;
camera.move(dragDiffX, dragDiffY);
x = xPos;
y = yPos;
}
});
......@@ -391,20 +385,25 @@ public class CityGMLViewer {
Shader program = new Shader("vertex.vert", "fragment.frag", useDebug);
program.use();
log.fine(() -> "OpenGL error code after shader loading: " + GL11.glGetError());
camera = new Camera(program);
camera.setOrtho(true);
camera = new OrthogonalCamera(program);
camera.reshape(width, height, cameraViewDistance);
bar = new ProgressBar(windowId, width, height);
bar.drawProgress(0);
log.fine(() -> "OpenGL error code after drawing initial progress bar: " + GL11.glGetError());
loadGmlFile(f);
double longestSide = loadGmlFile(f);
log.fine(() -> "OpenGL error code after loading GML file: " + GL11.glGetError());
bar.free();
bar = null;
camera.setOrtho(false);
camera.free();
camera = new Camera(program);
camera.reshape(width, height, cameraViewDistance);
double d = longestSide / Math.tan(Math.toRadians(30) / 2);
double translateZ = -d;
camera.setDistance((float) translateZ);
cameraViewDistance = (float) longestSide * 20f;
camera.rotate(0, -300);
clearColor = MemoryUtil.memAllocFloat(4);
clearColor.put(0, 0.9411765f).put(1, 1f).put(2, 1f).put(3, 1f);
......@@ -429,6 +428,16 @@ public class CityGMLViewer {
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
} catch (CityGMLContextException e) {
e.printStackTrace();
} catch (CityGMLReadException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} finally {
MemoryUtil.memFree(clearColor);
MemoryUtil.memFree(clearDepth);
......@@ -445,8 +454,7 @@ public class CityGMLViewer {
GLFW.glfwTerminate();
}
private static void loadGmlFile(File f) {
try {
private static double loadGmlFile(File f) throws InterruptedException, CityGMLContextException, CityGMLReadException, IOException, ParserConfigurationException, SAXException {
File file = f;
ParserConfiguration config = new ParserConfiguration();
CityGMLParser.parseEpsgCodeFromFile(file, config);
......@@ -523,19 +531,10 @@ public class CityGMLViewer {
viewing.add(lod4ViewInfo);
}
double longestSide = bbox.getDiagonalLength() * 0.2;
double d = longestSide / Math.tan(Math.toRadians(30) / 2);
double translateZ = -d;
camera.setDistance((float) translateZ);
cameraViewDistance = (float) longestSide * 20f;
camera.reshape(width, height, cameraViewDistance);
return bbox.getDiagonalLength() * 0.2;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.severe("Could not finish parsing file in 20 minutes, aborting");
throw e;
}
} catch (GLException | IOException | ParserConfigurationException | SAXException | CityGMLContextException
| CityGMLReadException e) {
e.printStackTrace();
}
}
}
package de.hft.stuttgart.citygml.viewer;
public class OrthogonalCamera extends Camera {
public OrthogonalCamera(Shader shader) {
super(shader);
}
@Override
public void reshape(int width, int height, float distance) {
projMatrix.setOrtho(0, width, height, 0, 0, distance);
projMatrix.get(matrixBuffer);
uniformLocation.uploadMat4(matrixBuffer);
}
@Override
public void rotate(double dragDiffX, double dragDiffY) {
}
@Override
public void move(double dragDiffX, double dragDiffY) {
}
@Override
public void scroll(int scroll) {
}
@Override
public void setDistance(float distance) {
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment