diff --git a/client/src/main/java/core/engine/Engine.java b/client/src/main/java/core/engine/Engine.java index 9a9ae45..fdf5cf0 100644 --- a/client/src/main/java/core/engine/Engine.java +++ b/client/src/main/java/core/engine/Engine.java @@ -9,6 +9,7 @@ import core.engine.model.TexturedModel; import core.engine.renderer.MasterRenderer; import core.engine.terrain.Terrain; import core.engine.textures.ModelTexture; +import core.engine.toolbox.MousePicker; import org.lwjgl.BufferUtils; import org.lwjgl.Version; import org.lwjgl.glfw.*; @@ -134,7 +135,8 @@ public class Engine { // Run the rendering loop until the user has attempted to close // the window or has pressed the ESCAPE key. MasterRenderer renderer = new MasterRenderer(); - input(camera, renderer); + MousePicker mousePicker = new MousePicker(camera, renderer.getProjectionMatrix()); + input(camera, renderer, mousePicker); while ( !glfwWindowShouldClose(window) ) { renderer.processTerrain(terrain); //renderer.processEntity(hexagonEntity); @@ -148,7 +150,7 @@ public class Engine { loader.cleanUp(); } - private void input(Camera camera, MasterRenderer masterRenderer) { + private void input(Camera camera, MasterRenderer masterRenderer, MousePicker mousePicker) { GLFWScrollCallback glfwScrollCallback = new GLFWScrollCallback() { @Override @@ -172,6 +174,16 @@ public class Engine { // Middle mouse button released isMouseWheelPressed = false; } + + if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) { + //Track mouse position + DoubleBuffer posX = BufferUtils.createDoubleBuffer(1); + DoubleBuffer posY = BufferUtils.createDoubleBuffer(1); + glfwGetCursorPos(window, posX, posY); + System.out.println(posX.get(0) + "|" + posY.get(0)); + mousePicker.update((float) posX.get(0), (float) posY.get(0)); + System.out.println(mousePicker.getCurrentRay()); + } } }; @@ -235,6 +247,8 @@ public class Engine { } }); + + } } diff --git a/client/src/main/java/core/engine/renderer/MasterRenderer.java b/client/src/main/java/core/engine/renderer/MasterRenderer.java index c0080db..889bf6a 100644 --- a/client/src/main/java/core/engine/renderer/MasterRenderer.java +++ b/client/src/main/java/core/engine/renderer/MasterRenderer.java @@ -110,4 +110,8 @@ public class MasterRenderer { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } + + public Matrix4f getProjectionMatrix() { + return projectionMatrix; + } } diff --git a/client/src/main/java/core/engine/toolbox/MousePicker.java b/client/src/main/java/core/engine/toolbox/MousePicker.java new file mode 100644 index 0000000..e25c6f3 --- /dev/null +++ b/client/src/main/java/core/engine/toolbox/MousePicker.java @@ -0,0 +1,60 @@ +package core.engine.toolbox; + +import core.engine.Engine; +import core.engine.entity.Camera; +import org.lwjgl.system.windows.MOUSEINPUT; +import utils.MatrixGraphicUtils; +import utils.vectors.Matrix4f; +import utils.vectors.Vector2f; +import utils.vectors.Vector3f; +import utils.vectors.Vector4f; + +public class MousePicker { + + private Vector3f currentRay; + private Matrix4f projectionMatrix; + private Matrix4f viewMatrix; + private Camera camera; + + public MousePicker(Camera camera, Matrix4f projectionMatrix) { + this.camera = camera; + this.projectionMatrix = projectionMatrix; + this.viewMatrix = MatrixGraphicUtils.createViewMatrix(camera); + } + + public Vector3f getCurrentRay() { + return currentRay; + } + + public void update(float mouseX, float mouseY) { + this.viewMatrix = MatrixGraphicUtils.createViewMatrix(camera); + this.currentRay = calculateMouseRay(mouseX, mouseY); + } + + public Vector3f calculateMouseRay(float mouseX, float mouseY) { + Vector2f normalizedDeviceCoords = getNormalizedDeviceCoords(mouseX, mouseY); + Vector4f clipCoords = new Vector4f(normalizedDeviceCoords.x, normalizedDeviceCoords.y, -1f, 1f); + Vector4f eyeCoords = toEyeCoords(clipCoords); + return toWorldCoords(eyeCoords); + } + + private Vector2f getNormalizedDeviceCoords(float mouseX, float mouseY) { + float x = (2f* mouseX) / Engine.WINDOW_WIDTH -1; + float y = (2f * mouseY) / Engine.WINDOW_HEIGHT -1; + return new Vector2f(x, y); + } + + private Vector4f toEyeCoords(Vector4f clipCoords) { + Matrix4f invertedProjectionMatrix = Matrix4f.invert(projectionMatrix, null); + Vector4f eyeCoords = Matrix4f.transform(invertedProjectionMatrix, clipCoords, null); + return new Vector4f(eyeCoords.x, eyeCoords.y, -1f, 0f); + } + + private Vector3f toWorldCoords (Vector4f eyeCoords) { + Matrix4f invertedViewMatrix = Matrix4f.invert(viewMatrix, null); + Vector4f rayWorld = Matrix4f.transform(invertedViewMatrix, eyeCoords, null); + Vector3f worldCoords = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z); + worldCoords.normalise(); + return worldCoords; + } +}