Ver Fonte

Model selection fix + model movement

tbvns há 6 meses atrás
pai
commit
91f65b6e71

+ 5 - 0
PowerGDEditor/src/main/java/xyz/tbvns/Editor/ModelsManager.java

@@ -73,4 +73,9 @@ public class ModelsManager {
         selectedModelInstance = model;
         selectedModel = model.model;
     }
+
+    public static void deselect() {
+        selectedModelInstance = null;
+        selectedModel = null;
+    }
 }

+ 65 - 16
PowerGDEditor/src/main/java/xyz/tbvns/Inputs/inputManager.java

@@ -3,14 +3,24 @@ package xyz.tbvns.Inputs;
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.Input;
 import com.badlogic.gdx.graphics.Camera;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.g3d.Material;
+import com.badlogic.gdx.graphics.g3d.Model;
+import com.badlogic.gdx.graphics.g3d.ModelInstance;
 import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
+import com.badlogic.gdx.graphics.g3d.utils.MeshPartBuilder;
+import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
+import com.badlogic.gdx.math.Intersector;
 import com.badlogic.gdx.math.Octree;
 import com.badlogic.gdx.math.Vector3;
+import com.badlogic.gdx.math.collision.BoundingBox;
 import com.badlogic.gdx.math.collision.Ray;
 import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
 import xyz.tbvns.Editor.ModelsManager;
 import xyz.tbvns.Main;
 import xyz.tbvns.Physics.BulletManager;
+import xyz.tbvns.ui.UIManager;
+import xyz.tbvns.ui.Windows.ObjectEdit;
 
 public class inputManager extends CameraInputController {
     private float startX, startY;
@@ -69,23 +79,62 @@ public class inputManager extends CameraInputController {
 
     @Override
     public boolean touchDown(float x, float y, int pointer, int button) {
-        x-=100;
-        y+=100;
-        Vector3 unprojected = Main.getCamera().unproject(new Vector3(x, y, 0));
-        Vector3 pos = Main.getCamera().position;
-
-        float x3 = unprojected.x + (unprojected.x - pos.x) * 10000;
-        float y3 = unprojected.y + (unprojected.y - pos.y) * 10000;
-        float z3 = unprojected.z + (unprojected.z - pos.z) * 10000;
-
-        btCollisionObject object = BulletManager.raycast(pos, new Vector3(x3, y3, z3));
-        if (object != null) {
-            BulletManager.getModelCollisiontHashMap().forEach((k, v) -> {
-                if (v == object) {
-                    ModelsManager.select(k);
-                }
-            });
+        x-=200;
+
+        Ray ray = Main.getCamera().getPickRay(x, y, 0, 200, Main.getCamera().viewportWidth, Main.getCamera().viewportHeight);
+
+        Vector3 rayStart = ray.origin;
+        Vector3 rayEnd = ray.origin.cpy().add(ray.direction.cpy().scl(1000f));  // Long ray to ensure it reaches objects
+
+        ray.set(rayStart, rayEnd);
+
+        int hit = 0;
+
+        for (ModelInstance model : ModelsManager.getLoadedModels()) {
+            BoundingBox boundingBox = new BoundingBox();
+            model.calculateBoundingBox(boundingBox);
+            Vector3 pos = model.transform.getTranslation(Vector3.Zero);
+
+            Vector3 min = new Vector3(pos.x + boundingBox.min.x, pos.y + boundingBox.min.y, pos.z + + boundingBox.min.z);
+            Vector3 max = new Vector3(pos.x + boundingBox.max.x, pos.y + boundingBox.max.y, pos.z + + boundingBox.max.z);
+
+            boundingBox.set(min, max);
+            if (Intersector.intersectRayBoundsFast(ray, boundingBox)) {
+                ModelsManager.select(model);
+                UIManager.getActiveUI().put(ObjectEdit.class, true);
+                hit++;
+            }
+        }
+
+        if (hit == 0) {
+            ModelsManager.deselect();
+            UIManager.getActiveUI().put(ObjectEdit.class, false);
         }
+//        Uncomment for debug line for raycast
+//        ModelBuilder modelBuilder = new ModelBuilder();
+//        modelBuilder.begin();
+//        MeshPartBuilder builder = modelBuilder.part("line", 1, 3, new Material());
+//        builder.setColor(Color.RED);
+//        builder.line(rayStart, rayEnd);
+//        Model lineModel = modelBuilder.end();
+//        Main.LineModel = lineModel;
+
+//        This doesn't work for some reason.
+//        TODO: Make this work
+
+//        btCollisionObject object = BulletManager.raycast(rayStart, rayEnd);
+//        if (object != null) {
+//            BulletManager.getModelCollisiontHashMap().forEach((k, v) -> {
+//                if (v == object) {
+//                    ModelsManager.select(k);
+//                    UIManager.getActiveUI().put(ObjectEdit.class, true);
+//                }
+//            });
+//        } else {
+//            if (ModelsManager.getSelectedModelInstance() != null) {
+//                ModelsManager.deselect();
+//            }
+//        }
 
         return super.touchDown(x, y, pointer, button);
     }

+ 5 - 1
PowerGDEditor/src/main/java/xyz/tbvns/LWJGL3/CustomViewport.java

@@ -1,5 +1,6 @@
 package xyz.tbvns.LWJGL3;
 
+import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.graphics.Camera;
 import com.badlogic.gdx.utils.viewport.ScreenViewport;
 
@@ -8,10 +9,13 @@ public class CustomViewport extends ScreenViewport {
         setCamera(camera);
     }
 
+
+
     @Override
     public void update(int screenWidth, int screenHeight, boolean centerCamera) {
         setScreenBounds(200, 200, screenWidth, screenHeight - 200);
-        setWorldSize(screenWidth - 200, screenHeight - 300);
+//        setScreenPosition();
+        setWorldSize(Gdx.graphics.getWidth() - 200, Gdx.graphics.getHeight() - 200);
         apply(centerCamera);
     }
 

+ 5 - 2
PowerGDEditor/src/main/java/xyz/tbvns/Main.java

@@ -40,7 +40,6 @@ public class Main extends ApplicationAdapter {
     private InputProcessor cameraInputController;
     private Viewport viewport;
     public static ModelCache modelCache;
-    public static Model selectedModel;
 
     @Override
     public void create() {
@@ -52,7 +51,7 @@ public class Main extends ApplicationAdapter {
         UIManager.getActiveUI().put(LevelSelector.class, true);
         TexturesManager.idFileMap.size();
         batch = new ModelBatch();
-        camera = new PerspectiveCamera(80, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
+        camera = new PerspectiveCamera(60, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
         camera.far = 1000;
         camera.near = 0.01f;
         viewport = new CustomViewport(camera);
@@ -120,6 +119,10 @@ public class Main extends ApplicationAdapter {
 
         Ui.render();
         Shortcut.check();
+
+//        BulletManager.debugDrawer.begin(camera);
+//        BulletManager.getDynamicsWorld().debugDrawWorld();
+//        BulletManager.debugDrawer.end();
     }
 
     @Override

+ 6 - 7
PowerGDEditor/src/main/java/xyz/tbvns/Models/Shaders.java

@@ -8,6 +8,7 @@ import com.badlogic.gdx.graphics.g3d.ModelInstance;
 import com.badlogic.gdx.graphics.g3d.model.Node;
 import com.badlogic.gdx.graphics.g3d.model.NodePart;
 import com.badlogic.gdx.graphics.glutils.ShaderProgram;
+import com.badlogic.gdx.math.Vector3;
 import com.badlogic.gdx.utils.GdxRuntimeException;
 import org.apache.commons.codec.Resources;
 import xyz.tbvns.Main;
@@ -33,15 +34,16 @@ public class Shaders {
     public static void renderOutline(ModelInstance instance) {
         // Enable face culling (front-face culling to show only backfaces)
         Gdx.gl.glEnable(GL20.GL_CULL_FACE);
-        Gdx.gl.glCullFace(GL20.GL_FRONT);  // Cull front faces to render only the back
+        Gdx.gl.glCullFace(GL20.GL_FRONT);  // Cull front faces to render only the backfaces
 
         // Bind the outline shader
         outlineShader.bind();
 
         // Set shader uniforms
-        outlineShader.setUniformMatrix("u_projTrans", Main.getCamera().combined);
-        outlineShader.setUniformf("u_outlineThickness", 0.02f);  // Adjust this for outline thickness
-        outlineShader.setUniformf("u_outlineColor", new Color(1f, 0.5f, 0, 0));  // Outline color
+        outlineShader.setUniformMatrix("u_projTrans", Main.getCamera().combined);  // Camera's projection-view matrix
+        outlineShader.setUniformMatrix("u_modelTrans", instance.transform);  // Model's transformation matrix
+        outlineShader.setUniformf("u_outlineThickness", 0.1f);  // Adjust thickness as needed
+        outlineShader.setUniformf("u_outlineColor", new Color(1, 0.5f, 0, 0));  // Set outline color
 
         // Render the modelInstance with the outline shader
         for (Node node : instance.nodes) {
@@ -54,8 +56,5 @@ public class Shaders {
                 }
             }
         }
-
-        // Disable face culling after rendering
-        Gdx.gl.glDisable(GL20.GL_CULL_FACE);
     }
 }

+ 21 - 2
PowerGDEditor/src/main/java/xyz/tbvns/Physics/BulletManager.java

@@ -9,6 +9,7 @@ import com.badlogic.gdx.physics.bullet.dynamics.btConstraintSolver;
 import com.badlogic.gdx.physics.bullet.dynamics.btDiscreteDynamicsWorld;
 import com.badlogic.gdx.physics.bullet.dynamics.btDynamicsWorld;
 import com.badlogic.gdx.physics.bullet.dynamics.btSequentialImpulseConstraintSolver;
+import com.badlogic.gdx.physics.bullet.linearmath.btIDebugDraw;
 import lombok.Getter;
 
 import javax.annotation.Nullable;
@@ -17,7 +18,7 @@ import java.util.HashMap;
 import java.util.List;
 
 public class BulletManager {
-    private static btDynamicsWorld dynamicsWorld;
+    @Getter private static btDiscreteDynamicsWorld dynamicsWorld;
     private static btConstraintSolver constraintSolver;
     private static btDefaultCollisionConfiguration collisionConfig;
     private static btCollisionDispatcher dispatcher;
@@ -37,12 +38,17 @@ public class BulletManager {
         constraintSolver = new btSequentialImpulseConstraintSolver();
         dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, constraintSolver, collisionConfig);
         dynamicsWorld.setGravity(new Vector3(0, -20f, 0));
+
+        debugDrawer = new DebugDrawer();
+        dynamicsWorld.setDebugDrawer(debugDrawer);
+        debugDrawer.setDebugMode(btIDebugDraw.DebugDrawModes.DBG_MAX_DEBUG_DRAW_MODE);
     }
 
     public static void update() {
         modelCollisiontHashMap.forEach((i, o) -> {
             o.setWorldTransform(i.transform);
         });
+
     }
 
     public static btCollisionObject addModel(ModelInstance instance) {
@@ -50,6 +56,7 @@ public class BulletManager {
         btCollisionObject collisionObject = new btCollisionObject();
         collisionObject.setCollisionShape(shape);
         collisionObject.setWorldTransform(instance.transform);
+
         dynamicsWorld.addCollisionObject(collisionObject);
         objects.add(collisionObject);
         shapes.add(shape);
@@ -69,8 +76,20 @@ public class BulletManager {
 
     @Nullable
     public static btCollisionObject raycast(Vector3 start, Vector3 end) {
-        rayResultCallback = new ClosestRayResultCallback(start, end);
+        rayResultCallback = new AllHitsRayResultCallback(start, end);
         dynamicsWorld.rayTest(start, end, rayResultCallback);
+
+
+        for (btCollisionObject object : objects) {
+            object.activate(true);
+        }
+
+        if (rayResultCallback.hasHit()) {
+            System.out.println("Hit object: " + rayResultCallback.getCollisionObject());
+        } else {
+            System.out.println("No hit detected");
+        }
+
         return rayResultCallback.getCollisionObject();
     }
 

+ 4 - 0
PowerGDEditor/src/main/java/xyz/tbvns/ui/Element.java

@@ -3,6 +3,10 @@ package xyz.tbvns.ui;
 import imgui.ImGui;
 
 public interface Element {
+    default void setup() {
+
+    }
+
     default void render() {
         ImGui.begin("Default UIElement");
         ImGui.text("This is the default UI !");

+ 7 - 0
PowerGDEditor/src/main/java/xyz/tbvns/ui/UIManager.java

@@ -2,6 +2,7 @@ package xyz.tbvns.ui;
 
 import lombok.Getter;
 import org.reflections.Reflections;
+import xyz.tbvns.ui.Windows.ObjectEdit;
 
 import java.util.*;
 
@@ -47,6 +48,12 @@ public class UIManager {
         }
     }
 
+    public static void setup() {
+        for (Element element : registeredElements) {
+            element.setup();
+        }
+    }
+
     public static void renderMenuBarTabs() {
         for (MenuBarTab tab : registeredMenuBarTabs) {
             tab.render();

+ 4 - 0
PowerGDEditor/src/main/java/xyz/tbvns/ui/Ui.java

@@ -33,6 +33,10 @@ public class Ui {
         io.getFonts().build();
         imGuiGlfw.init(windowHandle, true);
         imGuiGl3.init("#version 150");
+
+        startImGui();
+        UIManager.setup();
+        endImGui();
     }
 
     public static void startImGui() {

+ 142 - 0
PowerGDEditor/src/main/java/xyz/tbvns/ui/Windows/ObjectEdit.java

@@ -0,0 +1,142 @@
+package xyz.tbvns.ui.Windows;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.math.Vector3;
+import imgui.ImGui;
+import imgui.flag.ImGuiWindowFlags;
+import xyz.tbvns.Editor.ModelsManager;
+import xyz.tbvns.ui.Element;
+
+public class ObjectEdit implements Element {
+    @Override
+    public void setup() {
+    }
+
+    @Override
+    public void render() {
+        ImGui.begin("Edit model:", ImGuiWindowFlags.NoMove);
+        ImGui.setWindowPos(Gdx.graphics.getWidth() - ImGui.getWindowWidth(), 19);
+
+        if (ImGui.button("-100")) {
+            move(axis.X, -100);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-10")) {
+            move(axis.X, -10);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-5")) {
+            move(axis.X, -5);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-1")) {
+            move(axis.X, -1);
+        }
+        ImGui.sameLine();
+        ImGui.text("X");
+        ImGui.sameLine();
+        if (ImGui.button("+1")) {
+            move(axis.X, 1);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+5")) {
+            move(axis.X, 5);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+10")) {
+            move(axis.X, 10);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+100")) {
+            move(axis.X, 100);
+        }
+
+
+
+        if (ImGui.button("-100##2")) {
+            move(axis.Y, -100);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-10##2")) {
+            move(axis.Y, -10);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-5##2")) {
+            move(axis.Y, -5);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-1##2")) {
+            move(axis.Y, -1);
+        }
+        ImGui.sameLine();
+        ImGui.text("Y");
+        ImGui.sameLine();
+        if (ImGui.button("+1##2")) {
+            move(axis.Y, 1);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+5##2")) {
+            move(axis.Y, 5);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+10##2")) {
+            move(axis.Y, 10);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+100##2")) {
+            move(axis.Y, 100);
+        }
+
+
+
+        if (ImGui.button("-100##3")) {
+            move(axis.Z, -100);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-10##3")) {
+            move(axis.Z, -10);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-5##3")) {
+            move(axis.Z, -5);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("-1##3")) {
+            move(axis.Z, -1);
+        }
+        ImGui.sameLine();
+        ImGui.text("Z");
+        ImGui.sameLine();
+        if (ImGui.button("+1##3")) {
+            move(axis.Z, 1);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+5##3")) {
+            move(axis.Z, 5);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+10##3")) {
+            move(axis.Z, 10);
+        }
+        ImGui.sameLine();
+        if (ImGui.button("+100##3")) {
+            move(axis.Z, 100);
+        }
+        ImGui.end();
+    }
+
+    public void move(axis axis, int d) {
+        Vector3 pos = ModelsManager.getSelectedModelInstance().transform.getTranslation(Vector3.Zero);
+        if (axis == ObjectEdit.axis.X) {
+            ModelsManager.getSelectedModelInstance().transform.setToTranslation(pos.x + d, pos.y, pos.z);
+        } else if (axis == ObjectEdit.axis.Y) {
+            ModelsManager.getSelectedModelInstance().transform.setToTranslation(pos.x, pos.y + d, pos.z);
+        } else if (axis == ObjectEdit.axis.Z) {
+            ModelsManager.getSelectedModelInstance().transform.setToTranslation(pos.x, pos.y, pos.z + d);
+        }
+    }
+
+    public enum axis {
+        X, Y, Z
+    }
+}

+ 11 - 6
PowerGDEditor/src/main/resources/shaders/outline.vs.glsl

@@ -1,13 +1,18 @@
 #version 330 core
 
-uniform mat4 u_projTrans;  // Projection-view transformation matrix
-uniform float u_outlineThickness;  // Thickness of the outline
+// Uniforms
+uniform mat4 u_projTrans;        // Projection-view transformation matrix
+uniform mat4 u_modelTrans;       // Model transformation matrix (new)
+uniform float u_outlineThickness; // Thickness of the outline
 
-in vec3 a_position;  // Vertex position
-in vec3 a_normal;    // Vertex normal
+// Vertex attributes
+in vec3 a_position; // Vertex position
+in vec3 a_normal;   // Vertex normal
 
 void main() {
-    // Slightly push the vertices along their normals to "expand" the model for the outline
+    // Calculate the transformed position with model transformation and outline thickness
     vec3 scaledPosition = a_position + a_normal * u_outlineThickness;
-    gl_Position = u_projTrans * vec4(scaledPosition, 0.9);
+
+    // Apply both the model transformation and the projection-view transformation
+    gl_Position = u_projTrans * u_modelTrans * vec4(scaledPosition, 0.9);
 }