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