Updated Mousepicker

This commit is contained in:
Sebastian 2023-10-05 16:39:59 +02:00
parent ed6a4e8472
commit 3d4d0485f3
4 changed files with 104 additions and 30 deletions

View File

@ -135,10 +135,15 @@ public class Engine {
// Run the rendering loop until the user has attempted to close // Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key. // the window or has pressed the ESCAPE key.
MasterRenderer renderer = new MasterRenderer(); MasterRenderer renderer = new MasterRenderer();
MousePicker mousePicker = new MousePicker(camera, renderer.getProjectionMatrix()); MousePicker mousePicker = new MousePicker(camera, renderer.getProjectionMatrix(), terrain);
input(camera, renderer, mousePicker); input(camera, renderer, mousePicker);
while ( !glfwWindowShouldClose(window) ) { while ( !glfwWindowShouldClose(window) ) {
DoubleBuffer posX = BufferUtils.createDoubleBuffer(1);
DoubleBuffer posY = BufferUtils.createDoubleBuffer(1);
glfwGetCursorPos(window, posX, posY);
mousePicker.update((float) posX.get(0), (float) posY.get(0));
renderer.processTerrain(terrain); renderer.processTerrain(terrain);
//renderer.processEntity(hexagonEntity); //renderer.processEntity(hexagonEntity);
renderer.render(light, camera); renderer.render(light, camera);
glfwSwapBuffers(window); // swap the color buffers glfwSwapBuffers(window); // swap the color buffers

View File

@ -1,6 +1,7 @@
package core.engine.terrain; package core.engine.terrain;
import core.engine.Loader; import core.engine.Loader;
import core.engine.entity.Camera;
import core.engine.model.HexagonModel; import core.engine.model.HexagonModel;
import core.engine.model.RawModel; import core.engine.model.RawModel;
import core.engine.model.TexturedModel; import core.engine.model.TexturedModel;
@ -33,8 +34,6 @@ public class Terrain {
} }
} }
public List<TerrainTile> getTerrainTiles() { public List<TerrainTile> getTerrainTiles() {
return terrainTiles; return terrainTiles;
} }

View File

@ -1,6 +1,7 @@
package core.engine.terrain; package core.engine.terrain;
import core.engine.Loader; import core.engine.Loader;
import core.engine.entity.Camera;
import core.engine.model.RawModel; import core.engine.model.RawModel;
import core.engine.model.TexturedModel; import core.engine.model.TexturedModel;
import core.engine.textures.ModelTexture; import core.engine.textures.ModelTexture;

View File

@ -2,24 +2,34 @@ package core.engine.toolbox;
import core.engine.Engine; import core.engine.Engine;
import core.engine.entity.Camera; import core.engine.entity.Camera;
import core.engine.terrain.Terrain;
import org.lwjgl.system.windows.MOUSEINPUT; import org.lwjgl.system.windows.MOUSEINPUT;
import utils.MatrixGraphicUtils; import utils.MatrixGraphicUtils;
import utils.vectors.Matrix4f; import utils.vectors.*;
import utils.vectors.Vector2f;
import utils.vectors.Vector3f;
import utils.vectors.Vector4f;
public class MousePicker { public class MousePicker {
private Vector3f currentRay; private static final int RECURSION_COUNT = 200;
private static final float RAY_RANGE = 600;
private Vector3f currentRay = new Vector3f();
private Matrix4f projectionMatrix; private Matrix4f projectionMatrix;
private Matrix4f viewMatrix; private Matrix4f viewMatrix;
private Camera camera; private Camera camera;
public MousePicker(Camera camera, Matrix4f projectionMatrix) { private Terrain terrain;
this.camera = camera; private Vector3f currentTerrainPoint;
this.projectionMatrix = projectionMatrix;
this.viewMatrix = MatrixGraphicUtils.createViewMatrix(camera); public MousePicker(Camera cam, Matrix4f projection, Terrain terrain) {
camera = cam;
projectionMatrix = projection;
viewMatrix = MatrixGraphicUtils.createViewMatrix(camera);
this.terrain = terrain;
}
public Vector3f getCurrentTerrainPoint() {
return currentTerrainPoint;
} }
public Vector3f getCurrentRay() { public Vector3f getCurrentRay() {
@ -27,34 +37,93 @@ public class MousePicker {
} }
public void update(float mouseX, float mouseY) { public void update(float mouseX, float mouseY) {
this.viewMatrix = MatrixGraphicUtils.createViewMatrix(camera); viewMatrix = MatrixGraphicUtils.createViewMatrix(camera);
this.currentRay = calculateMouseRay(mouseX, mouseY); currentRay = calculateMouseRay(mouseX, mouseY);
if (intersectionInRange(0, RAY_RANGE, currentRay)) {
currentTerrainPoint = binarySearch(0, 0, RAY_RANGE, currentRay);
} else {
currentTerrainPoint = null;
}
} }
public Vector3f calculateMouseRay(float mouseX, float mouseY) { private Vector3f calculateMouseRay(float mouseX, float mouseY) {
Vector2f normalizedDeviceCoords = getNormalizedDeviceCoords(mouseX, mouseY);
Vector4f clipCoords = new Vector4f(normalizedDeviceCoords.x, normalizedDeviceCoords.y, -1f, 1f); Vector2f normalizedCoords = getNormalisedDeviceCoordinates(mouseX, mouseY);
Vector4f clipCoords = new Vector4f(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f);
Vector4f eyeCoords = toEyeCoords(clipCoords); Vector4f eyeCoords = toEyeCoords(clipCoords);
return toWorldCoords(eyeCoords); Vector3f worldRay = toWorldCoords(eyeCoords);
System.out.println(worldRay);
return worldRay;
} }
private Vector2f getNormalizedDeviceCoords(float mouseX, float mouseY) { private Vector3f toWorldCoords(Vector4f eyeCoords) {
float x = (2f* mouseX) / Engine.WINDOW_WIDTH -1; Matrix4f invertedView = Matrix4f.invert(viewMatrix, null);
float y = (2f * mouseY) / Engine.WINDOW_HEIGHT -1; Vector4f rayWorld = Matrix4f.transform(invertedView, eyeCoords, null);
return new Vector2f(x, y); Vector3f mouseRay = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z);
mouseRay.normalise();
return mouseRay;
} }
private Vector4f toEyeCoords(Vector4f clipCoords) { private Vector4f toEyeCoords(Vector4f clipCoords) {
Matrix4f invertedProjectionMatrix = Matrix4f.invert(projectionMatrix, null); Matrix4f invertedProjection = Matrix4f.invert(projectionMatrix, null);
Vector4f eyeCoords = Matrix4f.transform(invertedProjectionMatrix, clipCoords, null); Vector4f eyeCoords = Matrix4f.transform(invertedProjection, clipCoords, null);
return new Vector4f(eyeCoords.x, eyeCoords.y, -1f, 0f); return new Vector4f(eyeCoords.x, eyeCoords.y, -1f, 0f);
} }
private Vector3f toWorldCoords (Vector4f eyeCoords) { private Vector2f getNormalisedDeviceCoordinates(float mouseX, float mouseY) {
Matrix4f invertedViewMatrix = Matrix4f.invert(viewMatrix, null); float x = (2.0f * mouseX) / Engine.WINDOW_WIDTH - 1f;
Vector4f rayWorld = Matrix4f.transform(invertedViewMatrix, eyeCoords, null); float y = (2.0f * mouseY) / Engine.WINDOW_HEIGHT - 1f;
Vector3f worldCoords = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z); return new Vector2f(x, y);
worldCoords.normalise(); }
return worldCoords;
//**********************************************************
private Vector3f getPointOnRay(Vector3f ray, float distance) {
Vector3f camPos = camera.getPosition();
Vector3f start = new Vector3f(camPos.x, camPos.y, camPos.z);
Vector3f scaledRay = new Vector3f(ray.x * distance, ray.y * distance, ray.z * distance);
return Vector3f.add(start, scaledRay, null);
}
private Vector3f binarySearch(int count, float start, float finish, Vector3f ray) {
float half = start + ((finish - start) / 2f);
if (count >= RECURSION_COUNT) {
Vector3f endPoint = getPointOnRay(ray, half);
Terrain terrain = getTerrain(endPoint.getX(), endPoint.getZ());
if (terrain != null) {
return endPoint;
} else {
return null;
}
}
if (intersectionInRange(start, half, ray)) {
return binarySearch(count + 1, start, half, ray);
} else {
return binarySearch(count + 1, half, finish, ray);
}
}
private boolean intersectionInRange(float start, float finish, Vector3f ray) {
Vector3f startPoint = getPointOnRay(ray, start);
Vector3f endPoint = getPointOnRay(ray, finish);
if (!isUnderGround(startPoint) && isUnderGround(endPoint)) {
return true;
} else {
return false;
}
}
private boolean isUnderGround(Vector3f testPoint) {
Terrain terrain = getTerrain(testPoint.getX(), testPoint.getZ());
float height = 0;
if (testPoint.y < height) {
return true;
} else {
return false;
}
}
private Terrain getTerrain(float worldX, float worldZ) {
return terrain;
} }
} }