diff --git a/assets/Data/entity/objects/furniture.json b/assets/Data/entity/objects/furniture.json index 1fbab179..ef81fada 100644 --- a/assets/Data/entity/objects/furniture.json +++ b/assets/Data/entity/objects/furniture.json @@ -203,8 +203,8 @@ "collidable": { "type" : "CUBE", "dimension1" : 1.0, - "dimension2" : 1.0, - "dimension3" : 2.0, + "dimension2" : 0.85, + "dimension3" : 1.12, "rotX": 0, "rotY": 0, "rotZ": 0, @@ -255,20 +255,7 @@ } }, "buttonInteraction" : { - "onInteract" : "inventory", - "interactionShape" : { - "type" : "CUBE", - "dimension1" : 0.3, - "dimension2" : 0.3, - "dimension3" : 0.3, - "rotX": 0, - "rotY": 0, - "rotZ": 0, - "rotW": 1, - "offsetX" : 0.0, - "offsetY" : 0.1, - "offsetZ" : 0.0 - } + "onInteract" : "inventory" }, "gridAlignedData" : { "width" : 10, diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 3647a13b..f32c7d97 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1771,6 +1771,9 @@ Recipes for spawn items defined in parent entity Spawn items have stack/charge Spawn items respect charge state Chest furniture +Interaction editing debug menu +Fix chest physics&interaction data +Break out collidable template edit into dedicated component diff --git a/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java b/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java index a11b4b41..54f9cb64 100644 --- a/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java +++ b/src/main/java/electrosphere/client/interact/ClientInteractionEngine.java @@ -309,6 +309,33 @@ public class ClientInteractionEngine { } } + /** + * Checks whether the entity has an interaction body or not + * @param entity The entity + * @return true if it has an interaction body, false otherwise + */ + public static boolean hasInteractionBody(Entity entity){ + return entity.containsKey(EntityDataStrings.INTERACTION_BODY); + } + + /** + * Gets the interaction body on the entity + * @param entity The entity + * @return The body if it exists, null otherwise + */ + public static DBody getInteractionBody(Entity entity){ + return (DBody)entity.getData(EntityDataStrings.INTERACTION_BODY); + } + + /** + * Gets the template for the interaction body + * @param entity The entity + * @return The tempalte if it exists, null otherwise + */ + public static CollidableTemplate getInteractionTemplate(Entity entity){ + return (CollidableTemplate)entity.getData(EntityDataStrings.INTERACTION_TEMPLATE); + } + /** * Gets the number of interactibles on the client * @return The number of interactibles diff --git a/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java b/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java new file mode 100644 index 00000000..efb50d61 --- /dev/null +++ b/src/main/java/electrosphere/client/ui/components/imgui/CollidableEditBlock.java @@ -0,0 +1,126 @@ +package electrosphere.client.ui.components.imgui; + +import org.ode4j.ode.DBody; +import org.ode4j.ode.DBox; +import org.ode4j.ode.DCylinder; +import org.ode4j.ode.DGeom; +import org.ode4j.ode.DMass; + +import electrosphere.data.collidable.CollidableTemplate; +import imgui.ImGui; + +/** + * Block for editing collidable data + */ +public class CollidableEditBlock { + + /** + * The minimum offset + */ + static final float MIN_OFFSET = -10; + + /** + * The maximum offset + */ + static final float MAX_OFFSET = 10; + + /** + * Min scale + */ + static final float MIN_SCALE = 0.001f; + + /** + * Max scale + */ + static final float MAX_SCALE = 10f; + + /** + * Minimum mass value + */ + static final float MIN_MASS = 0; + + /** + * Maximum mass value + */ + static final float MAX_MASS = 1.0f; + + /** + * Storage for the modified scale of the collidable + */ + static float[] scale = new float[3]; + + /** + * Storage for the modified offset of the collidable + */ + static float[] offset = new float[3]; + + /** + * Radius slider + */ + static float[] radius = new float[1]; + + /** + * Length slider + */ + static float[] length = new float[1]; + + /** + * Mass slider + */ + static float[] mass = new float[1]; + + /** + * Draws collidable editing controls + * @param physicsBody The body to edit + * @param template The template data to edit + */ + public static void drawCollidableEdit(DBody physicsBody, CollidableTemplate template){ + if(physicsBody != null && physicsBody.getFirstGeom() != null && ImGui.collapsingHeader("Modify")){ + DGeom geom = physicsBody.getFirstGeom(); + if(geom instanceof DBox){ + DBox box = (DBox)geom; + if(ImGui.sliderFloat3("Offset", offset, MIN_OFFSET, MAX_OFFSET)){ + box.setOffsetPosition(offset[0], offset[1], offset[2]); + template.setOffsetX(offset[0]); + template.setOffsetY(offset[1]); + template.setOffsetZ(offset[2]); + } + if(ImGui.sliderFloat3("Scale",scale,MIN_SCALE,MAX_SCALE)){ + box.setLengths(scale[0], scale[1], scale[2]); + template.setDimension1(scale[0]); + template.setDimension2(scale[1]); + template.setDimension3(scale[2]); + } + if(physicsBody.getMass() instanceof DMass && ImGui.sliderFloat("Mass",mass,MIN_MASS,MAX_MASS)){ + DMass massObj = (DMass)physicsBody.getMass(); + float adjusted = (float)Math.log(mass[0] + 1); + massObj.setMass(adjusted); + } + } else if(geom instanceof DCylinder){ + DCylinder cylinder = (DCylinder)geom; + if(ImGui.sliderFloat3("Offset", offset, MIN_OFFSET, MAX_OFFSET)){ + cylinder.setOffsetPosition(offset[0], offset[1], offset[2]); + template.setOffsetX(offset[0]); + template.setOffsetY(offset[1]); + template.setOffsetZ(offset[2]); + } + if(ImGui.sliderFloat("Radius",radius,MIN_SCALE,MAX_SCALE)){ + cylinder.setParams(radius[0], cylinder.getLength()); + template.setDimension1(radius[0]); + } + if(ImGui.sliderFloat("Length",length,MIN_SCALE,MAX_SCALE)){ + cylinder.setParams(cylinder.getRadius(), length[0]); + template.setDimension2(length[0]); + } + if(physicsBody.getMass() instanceof DMass && ImGui.sliderFloat("Mass",mass,MIN_MASS,MAX_MASS)){ + DMass massObj = (DMass)physicsBody.getMass(); + float adjusted = (float)Math.log(mass[0] + 1); + massObj.setMass(adjusted); + } + } else { + throw new Error("Unsupported geom type! " + geom); + } + } + } + +} diff --git a/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityInteractionTab.java b/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityInteractionTab.java new file mode 100644 index 00000000..abc87ba2 --- /dev/null +++ b/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityInteractionTab.java @@ -0,0 +1,34 @@ +package electrosphere.client.ui.menu.debug.entity; + +import org.ode4j.ode.DBody; + +import electrosphere.client.interact.ClientInteractionEngine; +import electrosphere.client.ui.components.imgui.CollidableEditBlock; +import electrosphere.data.collidable.CollidableTemplate; +import electrosphere.entity.Entity; +import imgui.ImGui; + +/** + * Tab for interaction engine data + */ +public class ImGuiEntityInteractionTab { + + /** + * Interaction view + */ + protected static void drawInteractionTab(boolean show, Entity detailViewEntity){ + if(detailViewEntity == null){ + return; + } + if(show && ImGui.collapsingHeader("Interaction Data")){ + ImGui.indent(); + if(ClientInteractionEngine.getInteractionBody(detailViewEntity) != null){ + DBody body = ClientInteractionEngine.getInteractionBody(detailViewEntity); + CollidableTemplate template = ClientInteractionEngine.getInteractionTemplate(detailViewEntity); + CollidableEditBlock.drawCollidableEdit(body, template); + } + ImGui.unindent(); + } + } + +} diff --git a/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityMacros.java b/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityMacros.java index a207c932..56eec68e 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityMacros.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityMacros.java @@ -9,6 +9,7 @@ import org.joml.Vector3d; import org.ode4j.ode.DBody; import electrosphere.client.entity.debug.DebugVisualizerUtils; +import electrosphere.client.interact.ClientInteractionEngine; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.data.creature.equip.EquipPoint; import electrosphere.data.foliage.FoliageType; @@ -75,6 +76,7 @@ public class ImGuiEntityMacros { private static boolean showFoliageTab = false; //show foliage data private static boolean showToolbarTab = false; //show toolbar data private static boolean showInventoryTab = false; //show inventory data + private static boolean showInteractionTab = false; //show inventory data private static boolean showDebugActionsTab = false; //show debug actions /** @@ -201,6 +203,9 @@ public class ImGuiEntityMacros { if(ClientToolbarState.getClientToolbarState(detailViewEntity) != null && ImGui.checkbox("Toolbar Data", showToolbarTab)){ showToolbarTab = !showToolbarTab; } + if(ClientInteractionEngine.hasInteractionBody(detailViewEntity) && ImGui.checkbox("Interaction Data", showInteractionTab)){ + showInteractionTab = !showInteractionTab; + } if( (InventoryUtils.hasNaturalInventory(detailViewEntity) || InventoryUtils.hasEquipInventory(detailViewEntity) || InventoryUtils.hasToolbarInventory(detailViewEntity)) && ImGui.checkbox("Inventory Data", showInventoryTab) @@ -226,6 +231,7 @@ public class ImGuiEntityMacros { ImGuiEntityFoliageTab.drawFoliageView(showFoliageTab, detailViewEntity); ImGuiEntityToolbarTab.drawToolbarTab(showToolbarTab, detailViewEntity); ImGuiEntityInventoryTab.drawInventoryTab(showInventoryTab, detailViewEntity); + ImGuiEntityInteractionTab.drawInteractionTab(showInteractionTab, detailViewEntity); ImGuiEntityDebugActions.drawDebugActions(showDebugActionsTab, detailViewEntity); ImGuiEntityMacros.drawDataView(); } diff --git a/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityPhysicsTab.java b/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityPhysicsTab.java index 4102953c..e5ead481 100644 --- a/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityPhysicsTab.java +++ b/src/main/java/electrosphere/client/ui/menu/debug/entity/ImGuiEntityPhysicsTab.java @@ -1,11 +1,8 @@ package electrosphere.client.ui.menu.debug.entity; import org.ode4j.ode.DBody; -import org.ode4j.ode.DBox; -import org.ode4j.ode.DCylinder; -import org.ode4j.ode.DGeom; -import org.ode4j.ode.DMass; +import electrosphere.client.ui.components.imgui.CollidableEditBlock; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.data.collidable.CollidableTemplate; import electrosphere.engine.Globals; @@ -20,51 +17,6 @@ import imgui.ImGui; * Tab for both exploring and editing physics on this entity */ public class ImGuiEntityPhysicsTab { - - /** - * The minimum offset - */ - static final float MIN_OFFSET = -10; - - /** - * The maximum offset - */ - static final float MAX_OFFSET = 10; - - /** - * Minimum mass value - */ - static final float MIN_MASS = 0; - - /** - * Maximum mass value - */ - static final float MAX_MASS = 1.0f; - - /** - * Storage for the modified scale of the collidable - */ - static float[] scale = new float[3]; - - /** - * Storage for the modified offset of the collidable - */ - static float[] offset = new float[3]; - - /** - * Radius slider - */ - static float[] radius = new float[1]; - - /** - * Length slider - */ - static float[] length = new float[1]; - - /** - * Mass slider - */ - static float[] mass = new float[1]; /** * Physics view @@ -133,51 +85,8 @@ public class ImGuiEntityPhysicsTab { } //Collidable editing if(physicsBody != null && physicsBody.getFirstGeom() != null && ImGui.collapsingHeader("Modify")){ - DGeom geom = physicsBody.getFirstGeom(); CollidableTemplate template = (CollidableTemplate)detailViewEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE); - if(geom instanceof DBox){ - DBox box = (DBox)geom; - if(ImGui.sliderFloat3("Offset", offset, MIN_OFFSET, MAX_OFFSET)){ - box.setOffsetPosition(offset[0], offset[1], offset[2]); - template.setOffsetX(offset[0]); - template.setOffsetY(offset[1]); - template.setOffsetZ(offset[2]); - } - if(ImGui.sliderFloat3("Scale",scale,MIN_OFFSET,MAX_OFFSET)){ - box.setLengths(scale[0], scale[1], scale[2]); - template.setDimension1(scale[0]); - template.setDimension2(scale[1]); - template.setDimension3(scale[2]); - } - if(physicsBody.getMass() instanceof DMass && ImGui.sliderFloat("Mass",mass,MIN_MASS,MAX_MASS)){ - DMass massObj = (DMass)physicsBody.getMass(); - float adjusted = (float)Math.log(mass[0] + 1); - massObj.setMass(adjusted); - } - } else if(geom instanceof DCylinder){ - DCylinder cylinder = (DCylinder)geom; - if(ImGui.sliderFloat3("Offset", offset, MIN_OFFSET, MAX_OFFSET)){ - cylinder.setOffsetPosition(offset[0], offset[1], offset[2]); - template.setOffsetX(offset[0]); - template.setOffsetY(offset[1]); - template.setOffsetZ(offset[2]); - } - if(ImGui.sliderFloat("Radius",radius,MIN_OFFSET,MAX_OFFSET)){ - cylinder.setParams(radius[0], cylinder.getLength()); - template.setDimension1(radius[0]); - } - if(ImGui.sliderFloat("Length",length,MIN_OFFSET,MAX_OFFSET)){ - cylinder.setParams(cylinder.getRadius(), length[0]); - template.setDimension2(length[0]); - } - if(physicsBody.getMass() instanceof DMass && ImGui.sliderFloat("Mass",mass,MIN_MASS,MAX_MASS)){ - DMass massObj = (DMass)physicsBody.getMass(); - float adjusted = (float)Math.log(mass[0] + 1); - massObj.setMass(adjusted); - } - } else { - throw new Error("Unsupported geom type! " + geom); - } + CollidableEditBlock.drawCollidableEdit(physicsBody, template); } } ImGui.unindent(); diff --git a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java index 7ad03349..a54efdba 100644 --- a/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/debug/DebugContentPipeline.java @@ -12,6 +12,7 @@ import org.ode4j.ode.DGeom; import org.ode4j.ode.DSphere; import electrosphere.client.entity.camera.CameraEntityUtils; +import electrosphere.collision.CollisionEngine; import electrosphere.collision.PhysicsUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.data.collidable.CollidableTemplate; @@ -181,7 +182,8 @@ public class DebugContentPipeline implements RenderPipeline { if(Globals.userSettings.graphicsDebugDrawPhysicsObjects()){ Model physicsGraphicsModel; - for(Collidable collidable : Globals.clientSceneWrapper.getCollisionEngine().getCollidables()){ + CollisionEngine engine = Globals.clientSceneWrapper.getCollisionEngine(); + for(Collidable collidable : engine.getCollidables()){ Entity physicsEntity = collidable.getParent(); if((boolean)physicsEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE) != null){ CollidableTemplate template = (CollidableTemplate)physicsEntity.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);