environment controls in level editor
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-04-13 22:18:22 -04:00
parent 34403c3155
commit 788a71d1e1
12 changed files with 337 additions and 49 deletions

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
#Thu Apr 04 18:08:22 EDT 2024
buildNumber=94
#Sat Apr 13 21:46:23 EDT 2024
buildNumber=96

View File

@ -142,6 +142,8 @@ public class ControlHandler {
public static final String DATA_STRING_INPUT_CODE_MENU_BACKOUT = "menuBackout";
public static final String MENU_MOUSE_MOVE = "menuMouseMove";
public static final String MENU_SCROLL = "menuScroll";
public static final String MENU_DRAG_MANIPULATE = "menuDragManipulate";
public static final String MENU_DRAG_START = "menuDragStart";
@ -286,6 +288,8 @@ public class ControlHandler {
handler.addControl(MENU_MOUSE_MOVE, new Control(ControlType.MOUSE_MOVEMENT,0));
handler.addControl(INPUT_CODE_MENU_MOUSE_PRIMARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_LEFT));
handler.addControl(MENU_SCROLL, new Control(ControlType.MOUSE_SCROLL,0));
handler.addControl(MENU_DRAG_START, new Control(ControlType.MOUSE_MOVEMENT,0));
handler.addControl(MENU_DRAG_MANIPULATE, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_1));
/*
Map the typing controls
@ -1104,6 +1108,34 @@ public class ControlHandler {
Globals.elementManager.fireEvent(scrollEvent, GLFW_KEY_X, GLFW_KEY_Z);
}});
//dragging the cursor
menuNavigationControlList.add(controls.get(MENU_DRAG_MANIPULATE));
controls.get(MENU_DRAG_MANIPULATE).setOnPress(new ControlMethod(){public void execute(){
}});
controls.get(MENU_DRAG_MANIPULATE).setOnRelease(new ControlMethod(){public void execute(){
if(dragging){
dragging = false;
//fire dragrelease event to elementmanager
Globals.elementManager.dragRelease((int)xpos,(int)ypos,(int)mouse_lastX,(int)mouse_lastY,(int)(xpos - mouse_lastX),(int)(mouse_lastY - ypos));
}
}});
/*
item dragging
*/
menuNavigationControlList.add(controls.get(MENU_DRAG_START));
controls.get(MENU_DRAG_START).setOnMove(new Control.MouseCallback(){public void execute(MouseEvent event){
if(!dragging && event.getButton1()){
dragging = true;
//fire dragstart event to elementmanager
Globals.elementManager.dragStart((int)xpos,(int)ypos,(int)mouse_lastX,(int)mouse_lastY,(int)(xpos - mouse_lastX),(int)(mouse_lastY - ypos));
}
if(dragging){
//fire drag event to elementmanager
Globals.elementManager.drag((int)xpos,(int)ypos,(int)mouse_lastX,(int)mouse_lastY,(int)(xpos - mouse_lastX),(int)(mouse_lastY - ypos));
}
}});
//Decrementing a menu element

View File

@ -3,6 +3,7 @@ package electrosphere.menu.ingame;
import java.util.Random;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
@ -18,15 +19,20 @@ import electrosphere.game.data.foliage.type.FoliageType;
import electrosphere.logger.LoggerInterface;
import electrosphere.menu.WindowStrings;
import electrosphere.menu.WindowUtils;
import electrosphere.renderer.light.DirectionalLight;
import electrosphere.renderer.light.LightManager;
import electrosphere.renderer.ui.elements.Button;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.NavigationEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
@ -110,6 +116,13 @@ public class MenuGeneratorsLevelEditor {
return false;
}}));
//entity tree view
scrollable.addChild(Button.createButton("Atmospheric Control", new ClickEventCallback() {public boolean execute(ClickEvent event){
fillInAtmosphericControlContent(scrollable);
return false;
}}));
mainSidePanel.applyYoga();
}
@ -243,4 +256,65 @@ public class MenuGeneratorsLevelEditor {
}
/**
* Creates atmospheric controls
* @param scrollable
*/
private static void fillInAtmosphericControlContent(VirtualScrollable scrollable){
scrollable.clearChildren();
//back button
scrollable.addChild(Button.createButton("Close", new ClickEventCallback() {public boolean execute(ClickEvent event){
fillInDefaultContent(scrollable);
return false;
}}));
//global light direction
scrollable.addChild(Label.createLabel("Global Light Direction"));
Div xDiv = new Div();
xDiv.setMaxHeight(50);
xDiv.setFlexDirection(Yoga.YGFlexDirectionRow);
xDiv.addChild(Label.createLabel("X: "));
xDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
LightManager lightManager = Globals.renderingEngine.getLightManager();
DirectionalLight directionalLight = lightManager.getDirectionalLight();
Vector3f direction = directionalLight.getDirection();
direction.x = event.getAsFloat() * 2 - 1;
directionalLight.setDirection(direction);
}}));
scrollable.addChild(xDiv);
Div yDiv = new Div();
yDiv.setMaxHeight(50);
yDiv.setFlexDirection(Yoga.YGFlexDirectionRow);
yDiv.addChild(Label.createLabel("Y: "));
yDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
LightManager lightManager = Globals.renderingEngine.getLightManager();
DirectionalLight directionalLight = lightManager.getDirectionalLight();
Vector3f direction = directionalLight.getDirection();
direction.y = event.getAsFloat() * 2 - 1;
directionalLight.setDirection(direction);
}}));
scrollable.addChild(yDiv);
Div zDiv = new Div();
zDiv.setMaxHeight(50);
zDiv.setFlexDirection(Yoga.YGFlexDirectionRow);
zDiv.addChild(Label.createLabel("Z: "));
zDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
LightManager lightManager = Globals.renderingEngine.getLightManager();
DirectionalLight directionalLight = lightManager.getDirectionalLight();
Vector3f direction = directionalLight.getDirection();
direction.z = event.getAsFloat() * 2 - 1;
directionalLight.setDirection(direction);
}}));
scrollable.addChild(zDiv);
mainSidePanel.applyYoga();
}
}

View File

@ -14,7 +14,9 @@ import electrosphere.renderer.ui.elements.Slider;
import electrosphere.renderer.ui.elements.VirtualScrollable;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
/**
* Menu generators for creating test visualizations for ui elements
@ -29,19 +31,11 @@ public class MenuGeneratorsUITesting {
FormElement rVal = new FormElement();
//button (back)
Button backButton = new Button();
Label backLabel = new Label(1.0f);
backLabel.setText("Back");
backButton.addChild(backLabel);
rVal.addChild(backButton);
backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
return false;
}});
//slider test
Slider slider = new Slider(0, 0, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0));
rVal.addChild(slider);
rVal.addChild(backButton);
ActorPanel actorPanel = new ActorPanel(500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx"));
if(Globals.playerCamera == null){
@ -60,6 +54,13 @@ public class MenuGeneratorsUITesting {
testButton.addChild(testLabel);
virtualScrollable.addChild(testButton);
}
// slider test
Slider slider = Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
}});
virtualScrollable.addChild(slider);
rVal.addChild(virtualScrollable);
return rVal;

View File

@ -3,14 +3,18 @@ package electrosphere.renderer.light;
import org.joml.Vector3f;
/**
*
* @author amaterasu
* A directional light source (global)
*/
public class DirectionalLight {
//the direction of the light as a uniform vector
Vector3f direction;
//the ambient color
Vector3f ambient;
//the diffuse color
Vector3f diffuse;
//the specular color
Vector3f specular;
public void setDirection(Vector3f direction) {

View File

@ -14,8 +14,7 @@ import electrosphere.engine.Globals;
import electrosphere.entity.types.camera.CameraEntityUtils;
/**
*
* @author amaterasu
* Manages the light sources in the engine
*/
public class LightManager {
@ -107,6 +106,48 @@ public class LightManager {
//glBufferData(GL_UNIFORM_BUFFER, <my_data>, GL_STATIC_DRAW);
}
//
//
// HIGHER ORDER OBJECT MANIPULATION
//
//
public void setPointLight(PointLight light, int index){
pointLights[index] = light;
}
/**
* Gets the directional light for this light manager
* @return the directional light
*/
public DirectionalLight getDirectionalLight(){
return this.directionalLight;
}
//
//
// BUFFER MANAGEMENT
//
//
/**
* Call in each mesh / per each shader
* @param shaderIndex
@ -121,10 +162,6 @@ public class LightManager {
//alternatively if want to use range, do glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
}
public void setPointLight(PointLight light, int index){
pointLights[index] = light;
}
/**
* Call once per render loop to set buffer values
*/

View File

@ -23,7 +23,7 @@ public class UIPipeline implements RenderPipeline {
//Black background
//
if(Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND){
GL40.glUseProgram(RenderingEngine.screenTextureShaders.getShaderId());
openGLState.setActiveShader(renderPipelineState, RenderingEngine.screenTextureShaders);
openGLState.glDepthTest(false);
GL40.glBindVertexArray(RenderingEngine.screenTextureVAO);
Texture blackTexture = Globals.assetManager.fetchTexture(Globals.blackTexture);
@ -39,7 +39,7 @@ public class UIPipeline implements RenderPipeline {
//White background
//
if(Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND){
GL40.glUseProgram(RenderingEngine.screenTextureShaders.getShaderId());
openGLState.setActiveShader(renderPipelineState, RenderingEngine.screenTextureShaders);
openGLState.glDepthTest(false);
GL40.glBindVertexArray(RenderingEngine.screenTextureVAO);
Texture blackTexture = Globals.assetManager.fetchTexture(Globals.offWhiteTexture);

View File

@ -8,6 +8,8 @@ import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Vector2i;
import electrosphere.renderer.ui.elements.Window;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
import electrosphere.renderer.ui.elementtypes.DraggableElement;
@ -177,6 +179,12 @@ public class ElementManager {
Element currentElement = null;
while(elementStack.size() > 0 && propagate == true){
currentElement = elementStack.pop();
if(event instanceof ClickEvent){
ClickEvent clickEvent = (ClickEvent)event;
Vector2i absPos = getAbsolutePosition(currentElement);
clickEvent.setRelativeX(clickEvent.getCurrentX() - absPos.x);
clickEvent.setRelativeY(clickEvent.getCurrentY() - absPos.y);
}
propagate = currentElement.handleEvent(event);
}
if(!propagate){
@ -329,16 +337,23 @@ public class ElementManager {
y <= el.getInternalY() + offsetY + el.getInternalHeight();
}
// public void click(MouseEvent event){
// if(currentFocusedElement instanceof ClickableElement){
// ((ClickableElement)currentFocusedElement).onClick();
// }
// }
/**
* Fires an event where the mouse presses a button and clicks
* @param event The event to fire
*/
public void click(ClickEvent event){
fireEvent(event,event.getCurrentX(),event.getCurrentY());
}
/**
* Fires an event where the mouse presses down a button and begins to drag an element
* @param x
* @param y
* @param lastX
* @param lastY
* @param deltaX
* @param deltaY
*/
public void dragStart(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
DragEvent event = new DragEvent(x, y, lastX, lastY, deltaX, deltaY, DragEventType.START, null);
currentDragElement = (DraggableElement)resolveFirstDraggable(event);
@ -346,21 +361,64 @@ public class ElementManager {
fireEvent(event,x,y);
}
/**
* Fires an event where the mouse is dragging an element
* @param x
* @param y
* @param lastX
* @param lastY
* @param deltaX
* @param deltaY
*/
public void drag(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
DragEvent event = new DragEvent(x, y, lastX, lastY, deltaX, deltaY, DragEventType.DRAG, currentDragElement);
if(currentDragElement != null){
//need to calculate offset based on parent positions
//the positions for x, y, lastX, and lastY are all in absolute-to-screen coordinates
//the logic for things like slider depend on the
Vector2i absPos = getAbsolutePosition(currentDragElement);
DragEvent event = new DragEvent(x - absPos.x, y - absPos.y, lastX - absPos.x, lastY - absPos.y, deltaX, deltaY, DragEventType.DRAG, currentDragElement);
currentDragElement.handleEvent(event);
}
// fireEvent(event,event.getCurrentX(),event.getCurrentY());
}
/**
* Fires an event where the mouse is dragging an element and releases the mouse button
* @param x
* @param y
* @param lastX
* @param lastY
* @param deltaX
* @param deltaY
*/
public void dragRelease(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
DragEvent event = new DragEvent(x, y, lastX, lastY, deltaX, deltaY, DragEventType.RELEASE, currentDragElement);
if(currentDragElement != null){
//need to calculate offset based on parent positions
//the positions for x, y, lastX, and lastY are all in absolute-to-screen coordinates
//the logic for things like slider depend on the
Vector2i absPos = getAbsolutePosition(currentDragElement);
DragEvent event = new DragEvent(x - absPos.x, y - absPos.y, lastX - absPos.x, lastY - absPos.y, deltaX, deltaY, DragEventType.RELEASE, currentDragElement);
currentDragElement.handleEvent(event);
currentDragElement = null;
}
fireEvent(event,event.getCurrentX(),event.getCurrentY());
// fireEvent(event,event.getCurrentX(),event.getCurrentY());
}
/**
* Gets the absolute position of an element
* @param target the element
* @return The absolute position
*/
private Vector2i getAbsolutePosition(Element target){
List<Element> ancestryList = constructNonPositionalAncestryList(target);
ancestryList.remove(target);
int relX = 0;
int relY = 0;
for(Element el : ancestryList){
relX = relX + el.getInternalX();
relY = relY + el.getInternalY();
}
return new Vector2i(relX,relY);
}
/**

View File

@ -30,6 +30,21 @@ public class Label extends StandardContainerElement implements DrawableElement {
Font font;
/**
* Creates a label element
* @param text the text for the label
* @return the label element
*/
public static Label createLabel(String text){
Label rVal = new Label(1.0f);
rVal.setText(text);
return rVal;
}
/**
* Simplified constructor
* @param fontSize the size of the font (default is 1.0f)
*/
public Label(float fontSize){
super();
this.font = Globals.fontManager.getFont("default");
@ -38,6 +53,12 @@ public class Label extends StandardContainerElement implements DrawableElement {
Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow);
}
/**
* Creates a label with absolute positioning
* @param x the x position
* @param y the y position
* @param fontSize the font size (default is 1.0f)
*/
public Label(int x, int y, float fontSize){
super();
this.setPositionX(x);

View File

@ -22,6 +22,9 @@ import electrosphere.renderer.ui.events.FocusEvent;
import electrosphere.renderer.ui.events.MenuEvent;
import electrosphere.renderer.ui.events.ValueChangeEvent;
/**
* A ui element that is a slider that lets you pick between a range of values
*/
public class Slider extends StandardElement implements ClickableElement, DraggableElement, FocusableElement, DrawableElement, MenuEventElement, ValueElement {
public boolean visible = false;
@ -49,6 +52,29 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f);
static final int DEFAULT_HEIGHT = 20;
static final int DEFAULT_WIDTH = 100;
/**
* Creates a slider element
* @param callback the Logic to fire when the slider changes value
* @return the slider element
*/
public static Slider createSlider(ValueChangeEventCallback callback){
Slider slider = new Slider();
slider.setOnValueChangeCallback(callback);
return slider;
}
/**
* Private constructor
*/
private Slider(){
super();
setWidth(DEFAULT_WIDTH);
setHeight(DEFAULT_HEIGHT);
}
public Slider(int positionX, int positionY, int width, int height, Vector3f colorBackground, Vector3f colorForeground){
@ -91,15 +117,15 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
}
float ndcX = (float)positionX/parentWidth;
float ndcY = (float)positionY/parentHeight;
float ndcWidth = (float)width/parentWidth;
float ndcHeight = (float)height/parentHeight;
float ndcWidth = (float)getInternalWidth()/parentWidth;
float ndcHeight = (float)getInternalHeight()/parentHeight;
float ndcX = (float)(getInternalX() + parentPosX)/parentWidth;
float ndcY = (float)(getInternalY() + parentPosY)/parentHeight;
Vector3f boxPosition = new Vector3f(ndcX,ndcY,0);
Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
Model planeModel = Globals.assetManager.fetchModel(Globals.solidPlaneModelID);
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
if(planeModel != null){
//bounding box/margin
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
@ -108,10 +134,10 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
planeModel.drawUI();
//actual slider
ndcX = (float)(positionX + marginX)/parentWidth;
ndcY = (float)(positionY + marginY)/parentHeight;
ndcWidth = (float)((width - marginX * 2) * getValueAsPercentage())/parentWidth;
ndcHeight = (float)(height - marginY * 2)/parentHeight;
ndcX = (float)(getInternalX() + marginX + parentPosX)/parentWidth;
ndcY = (float)(getInternalY() + marginY + parentPosY)/parentHeight;
ndcWidth = (float)((getInternalWidth() - marginX * 2) * getValueAsPercentage())/parentWidth;
ndcHeight = (float)(getInternalHeight() - marginY * 2)/parentHeight;
boxPosition = new Vector3f(ndcX,ndcY,0);
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
@ -270,6 +296,12 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
propagate = onDrag.execute(dragEvent);
} else {
//default behavior
int percentage = dragEvent.getCurrentX() - getInternalX();
int max = width;
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
if(onValueChange != null){
onValueChange.execute(new ValueChangeEvent(value));
}
propagate = false;
}
} else if(dragEvent.getType() == DragEventType.RELEASE){
@ -277,6 +309,12 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
propagate = onDragRelease.execute(dragEvent);
} else {
//default behavior
int percentage = dragEvent.getCurrentX() - getInternalX();
int max = width;
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
if(onValueChange != null){
onValueChange.execute(new ValueChangeEvent(value));
}
propagate = true;
}
}
@ -287,7 +325,7 @@ public class Slider extends StandardElement implements ClickableElement, Draggab
propagate = this.onClick.execute((ClickEvent)event);
} else {
//default behavior
int percentage = clickEvent.getCurrentX() - positionX;
int percentage = clickEvent.getRelativeX() - getInternalX();
int max = width;
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
if(onValueChange != null){

View File

@ -131,15 +131,15 @@ public class StandardContainerElement extends StandardElement implements Contain
}
}
@Override
public void setWidth(int width) {
this.width = width;
}
// @Override
// public void setWidth(int width) {
// this.width = width;
// }
@Override
public void setHeight(int height) {
this.height = height;
}
// @Override
// public void setHeight(int height) {
// this.height = height;
// }
@Override
public void setPositionX(int posX) {

View File

@ -1,9 +1,16 @@
package electrosphere.renderer.ui.events;
/**
* A UI Event where the mouse clicks a button
*/
public class ClickEvent implements Event {
//absolute positions
int currentX;
int currentY;
//relative positions
int relativeX;
int relativeY;
boolean button1;
boolean button2;
@ -30,4 +37,20 @@ public class ClickEvent implements Event {
return button2;
}
public int getRelativeX(){
return relativeX;
}
public int getRelativeY(){
return relativeY;
}
public void setRelativeX(int relX){
this.relativeX = relX;
}
public void setRelativeY(int relY){
this.relativeY = relY;
}
}