interaction target ui element
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-04-26 15:12:47 -04:00
parent 2d26a8e73a
commit 589833b32f
19 changed files with 208 additions and 81 deletions

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
#Wed Apr 16 16:24:00 EDT 2025
buildNumber=619
#Sat Apr 26 14:36:52 EDT 2025
buildNumber=620

View File

@ -17,5 +17,7 @@
+ bug fixes
- Terrain edits do not save
- Panel does not draw its decoration if target framebuffer is the framebuffer of the window (maybe window isnt drawings its content framebuffer?)
- Window does not play nice with its minWidth/minHeight being set differently
+ unreproducible bugs

View File

@ -1546,6 +1546,7 @@ Fab selection tool
Fab selection tool actually loads fab files
Fix fab file reading
Fab tool can show transparent, loaded version of fab file
Interaction target tooltip at top of window

View File

@ -9,6 +9,8 @@ import org.joml.Quaterniond;
import org.joml.Vector3d;
import org.ode4j.ode.DBody;
import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.ui.menu.ingame.InteractionTargetMenu;
import electrosphere.collision.CollisionBodyCreation;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
@ -17,6 +19,7 @@ import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.game.data.collidable.CollidableTemplate;
/**
@ -210,4 +213,25 @@ public class ClientInteractionEngine {
return target;
}
/**
* Updates the interaction target label
*/
public static void updateInteractionTargetLabel(){
if(Globals.playerEntity != null && Globals.playerCamera != null){
boolean set = false;
Entity camera = Globals.playerCamera;
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera)).mul(-1.0);
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
Entity target = ClientInteractionEngine.rayCast(centerPos, eyePos);
if(target != null){
String text = CommonEntityUtils.getEntitySubtype(target);
InteractionTargetMenu.setInteractionTargetString(text);
set = true;
}
if(!set){
InteractionTargetMenu.setInteractionTargetString("");
}
}
}
}

View File

@ -6,6 +6,7 @@ import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.entity.crosshair.Crosshair;
import electrosphere.client.fluid.manager.ClientFluidManager;
import electrosphere.client.instancing.InstanceUpdater;
import electrosphere.client.interact.ClientInteractionEngine;
import electrosphere.client.terrain.manager.ClientTerrainManager;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
@ -117,6 +118,9 @@ public class ClientSimulation {
Globals.profiler.endCpuSample();
}
/**
* Client functions
*/
public void runClientFunctions(){
Globals.profiler.beginCpuSample("client functions");
ClientTerrainManager.generateTerrainChunkGeometry();
@ -128,6 +132,7 @@ public class ClientSimulation {
this.updateFirstPersonAttachments();
//bones have potenitally moved, so need to update where attached entities actually are before drawing
AttachUtils.clientUpdateAttachedEntityPositions();
ClientInteractionEngine.updateInteractionTargetLabel();
// updateCellManager();
Globals.profiler.endCpuSample();
}

View File

@ -195,9 +195,7 @@ public class NaturalInventoryPanel {
Entity itemEntity = finalEnt;
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(itemEntity);
Globals.signalSystem.post(SignalType.UI_MODIFICATION,()->{
itemTooltip = Tooltip.create(null,
Div.createCol(Label.createLabel(itemData.getId()))
);
itemTooltip = Tooltip.create(Div.createCol(Label.createLabel(itemData.getId())));
itemTooltip.setPositionX(panel.getAbsoluteX() + panelWidth);
itemTooltip.setPositionY(panel.getAbsoluteY());
});

View File

@ -36,11 +36,7 @@ public class PlayerInventoryWindow {
* @return The panel component
*/
public static Window createPlayerInventoryWindow(Entity entity){
int width = 750;
int height = 750;
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState(), width, height);
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState());
rVal.setParentAlignItem(YogaAlignment.Center);
rVal.setParentJustifyContent(YogaJustification.Center);

View File

@ -196,9 +196,7 @@ public class ToolbarInventoryPanel {
Entity itemEntity = inventory.getItemSlot("" + itemId) ;
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(itemEntity);
Globals.signalSystem.post(SignalType.UI_MODIFICATION,()->{
itemTooltip = Tooltip.create(null,
Div.createCol(Label.createLabel(itemData.getId()))
);
itemTooltip = Tooltip.create(Div.createCol(Label.createLabel(itemData.getId())));
itemTooltip.setPositionX(panel.getAbsoluteX() + panelWidth);
itemTooltip.setPositionY(panel.getAbsoluteY());
});

View File

@ -80,4 +80,9 @@ public class WindowStrings {
*/
public static final String CRAFTING = "crafting";
/**
* Window for displaying the current target
*/
public static final String TARGET_TOOLTIP = "targetTooltip";
}

View File

@ -3,6 +3,7 @@ package electrosphere.client.ui.menu;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.ui.components.PlayerInventoryWindow;
import electrosphere.client.ui.menu.ingame.CraftingWindow;
import electrosphere.client.ui.menu.ingame.InteractionTargetMenu;
import electrosphere.client.ui.menu.ingame.MenuGeneratorsInventory;
import electrosphere.client.ui.menu.mainmenu.MenuGeneratorsTitleMenu;
import electrosphere.controls.ControlHandler.ControlsState;
@ -204,11 +205,12 @@ public class WindowUtils {
* Inits all base windows
*/
public static void initBaseWindows(){
initLoadingWindow();
initItemDropWindow();
initItemDragContainerWindow();
initMainMenuWindow();
initTooltipWindow();
WindowUtils.initLoadingWindow();
WindowUtils.initItemDropWindow();
WindowUtils.initItemDragContainerWindow();
WindowUtils.initMainMenuWindow();
WindowUtils.initTooltipWindow();
Globals.elementService.registerWindow(WindowStrings.TARGET_TOOLTIP, InteractionTargetMenu.createInteractionTargetTooltipWindow());
}
/**
@ -223,6 +225,9 @@ public class WindowUtils {
WindowUtils.recursiveSetVisible(loadingWindow, true);
}
/**
* Inits the main menu
*/
public static void initMainMenuWindow(){
Window mainMenuWindow = Window.create(Globals.renderingEngine.getOpenGLState(), 0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, false);
Globals.elementService.registerWindow(WindowStrings.WINDOW_MENU_MAIN, mainMenuWindow);

View File

@ -20,16 +20,6 @@ import electrosphere.renderer.ui.events.NavigationEvent;
* Creates a crafting window
*/
public class CraftingWindow {
/**
* Minimum width of the component
*/
public static final int MIN_WIDTH = 500;
/**
* Minimum height of the component
*/
public static final int MIN_HEIGHT = 500;
/**
* The data for crafting with your hands
@ -41,11 +31,7 @@ public class CraftingWindow {
* @return The panel component
*/
public static Window createCraftingWindow(String data){
int width = MIN_WIDTH;
int height = MIN_HEIGHT;
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState(), width, height);
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState());
rVal.setParentAlignItem(YogaAlignment.Center);
rVal.setParentJustifyContent(YogaJustification.Center);

View File

@ -0,0 +1,64 @@
package electrosphere.client.ui.menu.ingame;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Panel;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
/**
* Menu for displaying a tooltip that shows the current interaction target
*/
public class InteractionTargetMenu {
/**
* Width of window
*/
static final int WINDOW_WIDTH = 100;
/**
* Height of window
*/
static final int WINDOW_HEIGHT = 100;
/**
* Creates the main in game menu that shows up when you (typically) hit the escape key
* @return The window for the menu
*/
public static Window createInteractionTargetTooltipWindow(){
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState(), false);
rVal.setAlignItems(YogaAlignment.Center);
Label label = Label.createLabel("");
rVal.addChild(Panel.createPanel(label));
Globals.signalSystem.post(SignalType.YOGA_APPLY,rVal);
return rVal;
}
/**
* Sets the text for the interaction target tooltip
* @param text The text, pass an empty string to hide the tooltip
*/
public static void setInteractionTargetString(String text){
Window interactionTooltipWindow = (Window)Globals.elementService.getWindow(WindowStrings.TARGET_TOOLTIP);
Panel container = (Panel)interactionTooltipWindow.getChildren().get(0);
Label label = (Label)container.getChildren().get(0);
if(text.length() == 0){
if(label.getText().length() != 0){
label.setText("");
}
interactionTooltipWindow.setVisible(false);
} else {
interactionTooltipWindow.setVisible(true);
if(!label.getText().contains(text)){
label.setText(text);
Globals.signalSystem.post(SignalType.YOGA_APPLY, interactionTooltipWindow);
}
}
}
}

View File

@ -60,7 +60,7 @@ public class MenuGeneratorsInGame {
* @return The window for the menu
*/
public static Window createInGameMainMenu(){
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState(), WINDOW_WIDTH, WINDOW_HEIGHT);
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState());
Div div = Div.createDiv();
rVal.addChild(div);
@ -154,7 +154,7 @@ public class MenuGeneratorsInGame {
* @return
*/
public static Window createInGameDebugMainMenu(){
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState(), WINDOW_WIDTH, WINDOW_HEIGHT);
Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState());
VirtualScrollable scrollable = new VirtualScrollable(WINDOW_WIDTH, WINDOW_HEIGHT);
rVal.addChild(scrollable);

View File

@ -491,7 +491,7 @@ public class RenderingEngine {
//calculate render angle for frustum culling
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
updateFrustumBox();
this.updateFrustumBox();
}
//generate depth map
@ -506,7 +506,7 @@ public class RenderingEngine {
//Update light buffer
lightManager.update(renderPipelineState,openGLState,Globals.playerCamera);
checkError();
this.checkError();
//Render content to the game framebuffer
@ -516,19 +516,19 @@ public class RenderingEngine {
} else {
mainContentNoOITPipeline.render(openGLState, renderPipelineState);
}
checkError();
this.checkError();
debugContentPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
normalsForOutlinePipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
firstPersonItemsPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
outlineNormalsPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
compositePipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
postProcessingPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
}
@ -537,12 +537,12 @@ public class RenderingEngine {
//Render the game framebuffer texture to a quad
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER){
renderScreenPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
}
//render ui
uiPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
//Render boundaries of ui elements
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){
@ -553,7 +553,7 @@ public class RenderingEngine {
* Render imgui
*/
imGuiPipeline.render(openGLState, renderPipelineState);
checkError();
this.checkError();
//check for errors
@ -565,13 +565,13 @@ public class RenderingEngine {
LoggerInterface.loggerRenderer.DEBUG_LOOP("GLFW Poll Events");
GLFW.glfwPollEvents();
LoggerInterface.loggerRenderer.DEBUG_LOOP("Check OpenGL Errors");
checkError();
this.checkError();
}
/**
* Updates the frustum box of the render pipeline
*/
void updateFrustumBox(){
private void updateFrustumBox(){
renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix);
}

View File

@ -71,7 +71,7 @@ public class Label extends StandardContainerElement implements DrawableElement {
this.font = Globals.fontManager.getFont("default");
this.setHeight((int)(font.getFontHeight() * fontSize));
this.fontSize = fontSize;
Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow);
this.setFlexDirection(YogaFlexDirection.Row);
}
/**

View File

@ -37,7 +37,6 @@ public class Panel extends StandardContainerElement implements DrawableElement {
/**
* Creates a label element
* @param text the text for the label
* @return the label element
*/
public static Panel createPanel(){
@ -49,6 +48,23 @@ public class Panel extends StandardContainerElement implements DrawableElement {
return rVal;
}
/**
* Creates a label element
* @param children The child elements
* @return the label element
*/
public static Panel createPanel(Element ... children){
Panel rVal = new Panel();
rVal.setPaddingTop(DEFAULT_PADDING);
rVal.setPaddingRight(DEFAULT_PADDING);
rVal.setPaddingLeft(DEFAULT_PADDING);
rVal.setPaddingBottom(DEFAULT_PADDING);
for(Element child : children){
rVal.addChild(child);
}
return rVal;
}
/**
* Constructor
*/

View File

@ -49,6 +49,13 @@ public class StandardContainerElement extends StandardElement implements Contain
@Override
public void addChild(Element child) {
if(child.getParent() != null){
String message = "Tried adding a child to a that already has a parent!\n" +
"this: " + this + "\n" +
"child: " + child + "\n" +
"child parent: " + child.getParent() + "\n";
throw new Error(message);
}
childList.add(child);
child.setParent(this);
if(child instanceof DrawableElement){

View File

@ -60,6 +60,28 @@ public class Tooltip extends StandardDrawableContainerElement {
}
return tooltip;
}
/**
* Creates a tooltip
* @param children The children of the tooltip
* @return The tooltip
*/
public static Tooltip create(Element ... children){
Tooltip tooltip = new Tooltip();
tooltip.setAbsolutePosition(true);
tooltip.setPositionX(0);
tooltip.setPositionY(0);
for(Element child : children){
tooltip.addChild(child);
}
Element windowElement = Globals.elementService.getWindow(WindowStrings.TOOLTIP_WINDOW);
if(windowElement instanceof Window){
Window windowView = (Window)windowElement;
windowView.addChild(tooltip);
Globals.signalSystem.post(SignalType.YOGA_APPLY,windowView);
}
return tooltip;
}
@Override

View File

@ -121,9 +121,9 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
//yoga node for placement
this.parentWindowYogaNode = Yoga.YGNodeNew();
Yoga.YGNodeInsertChild(this.parentWindowYogaNode, this.yogaNode, 0);
setParentAlignContent(YogaAlignment.Start);
setParentAlignItem(YogaAlignment.Start);
setParentJustifyContent(YogaJustification.Start);
this.setParentAlignContent(YogaAlignment.Start);
this.setParentAlignItem(YogaAlignment.Start);
this.setParentJustifyContent(YogaJustification.Start);
this.setFlexDirection(YogaFlexDirection.Column);
this.setWidth(width);
this.setHeight(height);
@ -146,9 +146,9 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
//yoga node for placement
this.parentWindowYogaNode = Yoga.YGNodeNew();
Yoga.YGNodeInsertChild(this.parentWindowYogaNode, this.yogaNode, 0);
setParentAlignContent(YogaAlignment.Start);
setParentAlignItem(YogaAlignment.Start);
setParentJustifyContent(YogaJustification.Start);
this.setParentAlignContent(YogaAlignment.Start);
this.setParentAlignItem(YogaAlignment.Start);
this.setParentJustifyContent(YogaJustification.Start);
this.setFlexDirection(YogaFlexDirection.Column);
this.setMinWidth(DEFAULT_POPUP_WIDTH);
this.setMinHeight(DEFAULT_POPUP_HEIGHT);
@ -172,13 +172,9 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
/**
* Creates an expandable window
* @param openGLState The opengl state
* @param posX The x position of the window
* @param posY The y position of the window
* @param width The width of the window
* @param height The height of the window
* @return The window element
*/
public static Window createExpandable(OpenGLState openGLState, int posX, int posY, int width, int height){
public static Window createExpandable(OpenGLState openGLState){
Window rVal = new Window(openGLState);
return rVal;
}
@ -186,19 +182,29 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
/**
* Creates an expandable window
* @param openGLState The opengl state
* @param posX The x position of the window
* @param posY The y position of the window
* @param width The width of the window
* @param height The height of the window
* @return The window element
*/
public static Window createExpandableCenterAligned(OpenGLState openGLState, int width, int height){
public static Window createExpandableCenterAligned(OpenGLState openGLState){
Window rVal = new Window(openGLState);
rVal.setParentAlignItem(YogaAlignment.Center);
rVal.setParentJustifyContent(YogaJustification.Center);
return rVal;
}
/**
* Creates an expandable window
* @param openGLState The opengl state
* @param showDecorations true to show decorations for window, false to not draw them
* @return The window element
*/
public static Window createExpandableCenterAligned(OpenGLState openGLState, boolean showDecorations){
Window rVal = new Window(openGLState);
rVal.setParentAlignItem(YogaAlignment.Center);
rVal.setParentJustifyContent(YogaJustification.Center);
rVal.showDecorations = showDecorations;
return rVal;
}
@Override
public void draw(
RenderPipelineState renderPipelineState,
@ -241,20 +247,12 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
}
//render background of window
if(planeModel != null && windowFrame != null && showDecorations){
UIFrameUtils.drawFrame(
AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_3, color, 48, 12,
this.getAbsoluteX(), this.getAbsoluteY(), this.getWidth(), this.getHeight(),
framebuffer, framebufferPosX, framebufferPosY
);
// planeModel.prawUI(ushUniformToMesh("plane", "mPosition", boxPosition);
// planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
// planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
// planeModel.pushUniformToMesh("plane", "tDimension", texScale);
// planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color);
// customMat.setTexturePointer(windowFrame.getTexturePointer());
// planeModel.getMeshes().get(0).setMaterial(customMat);
// planeModel.d);
if(planeModel != null && windowFrame != null && this.showDecorations){
UIFrameUtils.drawFrame(
AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_3, color, 48, 12,
this.getAbsoluteX(), this.getAbsoluteY(), this.getWidth(), this.getHeight(),
framebuffer, framebufferPosX, framebufferPosY
);
}
//render content of window