character creation menu work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
86fbaa8aa4
commit
9c672af15f
@ -1179,6 +1179,10 @@ Nearest biome sampling for content generation
|
||||
Fix recursive delete not actually recursing
|
||||
Add floor voxel type
|
||||
Singleplayer menu layout work
|
||||
Remove explicit garbage collection call
|
||||
Actor panel additional functionality
|
||||
Better style for character creation menu
|
||||
Fix AABB calculation from assimp-loaded models
|
||||
|
||||
|
||||
# TODO
|
||||
@ -1215,6 +1219,7 @@ Bug Fixes
|
||||
- Fix virtual scrollables not working
|
||||
- Fix foliage flickering on edit
|
||||
- Fix single blades of grass generating in bad locations
|
||||
- Fix falling tree not stopping when hitting static collidables
|
||||
|
||||
Startup Performance
|
||||
- Allow texture map to bind multiple model paths to a single set of mesh->textures
|
||||
|
||||
@ -216,6 +216,11 @@ public class CameraEntityUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the camera view matrix for a given camera entity
|
||||
* @param camera The camera
|
||||
* @return The view matrix for the camera
|
||||
*/
|
||||
public static Matrix4f getCameraViewMatrix(Entity camera){
|
||||
Vector3f cameraCenter = new Vector3f(0,0,0);//getViewMatrixCenterOffset(camera);
|
||||
Vector3f cameraEye = new Vector3f(cameraCenter).add(getCameraEye(camera));
|
||||
|
||||
@ -4,6 +4,7 @@ import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
@ -15,6 +16,7 @@ import electrosphere.net.parser.net.message.CharacterMessage;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorStaticMorph;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.renderer.light.DirectionalLight;
|
||||
import electrosphere.renderer.ui.elements.ActorPanel;
|
||||
import electrosphere.renderer.ui.elements.Button;
|
||||
import electrosphere.renderer.ui.elements.Div;
|
||||
@ -40,6 +42,16 @@ public class CharacterCustomizer {
|
||||
* Minimum height of the component
|
||||
*/
|
||||
public static final int MIN_HEIGHT = 500;
|
||||
|
||||
/**
|
||||
* The direction of the light in the actor panel
|
||||
*/
|
||||
static final Vector3f LIGHT_DIRECTION = new Vector3f(-0.2f,-0.8f,-0.2f).normalize();
|
||||
|
||||
/**
|
||||
* Margin around each control container
|
||||
*/
|
||||
static final int CONTROL_CONTAINER_MARGIN = 15;
|
||||
|
||||
/**
|
||||
* Creates a character customizer panel
|
||||
@ -58,8 +70,13 @@ public class CharacterCustomizer {
|
||||
Actor characterActor = ActorUtils.createActorFromModelPath(selectedRaceType.getGraphicsTemplate().getModel().getPath());
|
||||
ActorPanel actorPanel = ActorPanel.create(characterActor);
|
||||
actorPanel.setAnimation(selectedRaceType.getGraphicsTemplate().getModel().getIdleData().getAnimation().getNameThirdPerson());
|
||||
actorPanel.setPosition(new Vector3f(0,-0.5f,-0.6f));
|
||||
actorPanel.setPosition(new Vector3f(0));
|
||||
actorPanel.setScale(new Vector3f(1.0f));
|
||||
actorPanel.setClearColor(new Vector4d(0));
|
||||
|
||||
//Set lighting
|
||||
DirectionalLight directionalLight = Globals.renderingEngine.getLightManager().getDirectionalLight();
|
||||
directionalLight.setDirection(LIGHT_DIRECTION);
|
||||
|
||||
//have to build static morph while looping through attributes
|
||||
ActorStaticMorph staticMorph = new ActorStaticMorph();
|
||||
@ -105,7 +122,12 @@ public class CharacterCustomizer {
|
||||
//add attribute to creature template
|
||||
template.putAttributeValue(attribute.getAttributeId(), defaultValue);
|
||||
|
||||
scrollable.addChild(Div.createRow(sliderName,boneSlider));
|
||||
Div controlContainer = Div.createRow(sliderName,boneSlider);
|
||||
controlContainer.setMarginTop(CONTROL_CONTAINER_MARGIN);
|
||||
controlContainer.setMarginBottom(CONTROL_CONTAINER_MARGIN);
|
||||
controlContainer.setMarginLeft(CONTROL_CONTAINER_MARGIN);
|
||||
controlContainer.setMarginRight(CONTROL_CONTAINER_MARGIN);
|
||||
scrollable.addChild(controlContainer);
|
||||
} else if(attribute.getType().equals(VisualAttribute.TYPE_REMESH)){
|
||||
//add label for carousel
|
||||
Label scrollableName = Label.createLabel(attribute.getAttributeId());
|
||||
@ -136,22 +158,35 @@ public class CharacterCustomizer {
|
||||
//set the current attrib for the template
|
||||
template.putAttributeValue(attribute.getAttributeId(), attribute.getVariants().get(0).getId());
|
||||
|
||||
scrollable.addChild(Div.createRow(scrollableName,variantCarousel));
|
||||
Div controlContainer = Div.createRow(scrollableName,variantCarousel);
|
||||
controlContainer.setMarginTop(CONTROL_CONTAINER_MARGIN);
|
||||
controlContainer.setMarginBottom(CONTROL_CONTAINER_MARGIN);
|
||||
controlContainer.setMarginLeft(CONTROL_CONTAINER_MARGIN);
|
||||
controlContainer.setMarginRight(CONTROL_CONTAINER_MARGIN);
|
||||
scrollable.addChild(controlContainer);
|
||||
}
|
||||
}
|
||||
//finally set static morph
|
||||
characterActor.setActorStaticMorph(staticMorph);
|
||||
|
||||
//character create button
|
||||
Div createButtonContainer = Div.createDiv();
|
||||
createButtonContainer.setMarginTop(CONTROL_CONTAINER_MARGIN);
|
||||
createButtonContainer.setMarginBottom(CONTROL_CONTAINER_MARGIN);
|
||||
createButtonContainer.setMarginLeft(CONTROL_CONTAINER_MARGIN);
|
||||
createButtonContainer.setMarginRight(CONTROL_CONTAINER_MARGIN);
|
||||
createButtonContainer.addChild(Button.createButton("Create", () -> {
|
||||
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestCreateCharacterMessage(Utilities.stringify(template)));
|
||||
onConfirm.accept(template);
|
||||
}));
|
||||
|
||||
//create layout
|
||||
Div rVal = Div.createCol(
|
||||
Div.createRow(
|
||||
scrollable,
|
||||
actorPanel
|
||||
),
|
||||
Button.createButton("Create", () -> {
|
||||
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestCreateCharacterMessage(Utilities.stringify(template)));
|
||||
onConfirm.accept(template);
|
||||
})
|
||||
createButtonContainer
|
||||
);
|
||||
|
||||
return rVal;
|
||||
|
||||
@ -62,7 +62,7 @@ public class CameraHandler {
|
||||
}
|
||||
}
|
||||
|
||||
updateGlobalCamera();
|
||||
this.updateGlobalCamera();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +160,7 @@ public class CameraHandler {
|
||||
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
||||
|
||||
//update the cursor on client side
|
||||
updatePlayerCursor();
|
||||
this.updatePlayerCursor();
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
@ -196,6 +196,14 @@ public class CameraHandler {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the yaw of the camera handler
|
||||
* @param yaw The yaw
|
||||
*/
|
||||
public void setYaw(double yaw){
|
||||
this.yaw = (float)yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pitch of the camera handler
|
||||
* @return the pitch
|
||||
@ -204,6 +212,14 @@ public class CameraHandler {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pitch of the camera handler
|
||||
* @param pitch The pitch
|
||||
*/
|
||||
public void setPitch(double pitch){
|
||||
this.pitch = (float)pitch;
|
||||
}
|
||||
|
||||
//set player tracking
|
||||
public void setTrackPlayerEntity(boolean track){
|
||||
trackPlayerEntity = track;
|
||||
|
||||
@ -105,7 +105,7 @@ public class ControlCategoryMenuNav {
|
||||
//scrolling the mouse
|
||||
menuNavigationControlList.add(controlMap.get(MENU_SCROLL));
|
||||
controlMap.get(MENU_SCROLL).setOnScroll(new Control.ScrollCallback() {public void execute(MouseState mouseState, ScrollEvent scrollEvent){
|
||||
Globals.elementService.fireEvent(scrollEvent, GLFW.GLFW_KEY_X, GLFW.GLFW_KEY_Z);
|
||||
Globals.elementService.fireEvent(scrollEvent, (int)scrollEvent.getMouseX(), (int)scrollEvent.getMouseY());
|
||||
}});
|
||||
|
||||
//dragging the cursor
|
||||
|
||||
@ -95,8 +95,8 @@ public class AssetManager {
|
||||
modelsInQueue.remove(currentPath);
|
||||
AIScene aiScene = ModelLoader.loadAIScene(currentPath);
|
||||
TextureMap textureMap = null;
|
||||
if(getLocalTextureMapPath(currentPath) != null){
|
||||
textureMap = TextureMap.construct(getLocalTextureMapPath(currentPath));
|
||||
if(this.getLocalTextureMapPath(currentPath) != null){
|
||||
textureMap = TextureMap.construct(this.getLocalTextureMapPath(currentPath));
|
||||
}
|
||||
if(aiScene != null){
|
||||
modelsLoadedIntoMemory.put(currentPath, ModelLoader.createModelFromAiScene(aiScene,textureMap,currentPath));
|
||||
@ -105,7 +105,7 @@ public class AssetManager {
|
||||
//create physics
|
||||
physicsMeshesToLoad.remove(physicsMeshQueueItem);
|
||||
physicsMeshesLoadedIntoMemory.put(
|
||||
getCollisionMeshMapKey(physicsMeshQueueItem.collisionEngine,currentPath),
|
||||
this.getCollisionMeshMapKey(physicsMeshQueueItem.collisionEngine,currentPath),
|
||||
CollisionBodyCreation.generateRigidBodyFromAIScene(physicsMeshQueueItem.collisionEngine,aiScene,Collidable.TYPE_STATIC_BIT)
|
||||
);
|
||||
}
|
||||
|
||||
@ -427,39 +427,24 @@ public class Actor {
|
||||
*/
|
||||
public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState){
|
||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||
boolean hasDrawn = false;
|
||||
if(model != null && isWithinFrustumBox(renderPipelineState,model,frustumCull)){
|
||||
applyAnimationMasks(model);
|
||||
this.applyAnimationMasks(model);
|
||||
meshMask.processMeshMaskQueue();
|
||||
model.setMeshMask(meshMask);
|
||||
model.setTextureMask(textureMap);
|
||||
// if(!meshMask.isEmpty()){
|
||||
// }
|
||||
// if(animation != null){
|
||||
// model.playAnimation(animation);
|
||||
// model.incrementTime(0.001);
|
||||
// model.incrementTime(animationTime);
|
||||
// if(model.currentAnimation == null){
|
||||
// playingAnimation = false;
|
||||
// }
|
||||
// }
|
||||
for(ActorShaderMask shaderMask : shaderMasks){
|
||||
if(shaderMask.getModelName().equals(modelPath)){
|
||||
model.getShaderMask().put(shaderMask.getMeshName(),shaderMask);
|
||||
}
|
||||
}
|
||||
calculateNodeTransforms(model);
|
||||
this.calculateNodeTransforms(model);
|
||||
if(textureOverride != null){
|
||||
Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride);
|
||||
if(overrideTextureObject != null){
|
||||
overrideTextureObject.bind(openGLState);
|
||||
hasDrawn = true;
|
||||
model.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
}
|
||||
if(!hasDrawn){
|
||||
model.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
model.draw(renderPipelineState,openGLState);
|
||||
model.getShaderMask().clear();
|
||||
model.setTextureMask(null);
|
||||
}
|
||||
|
||||
@ -32,7 +32,8 @@ public class ModelLoader {
|
||||
Assimp.aiProcess_Triangulate |
|
||||
Assimp.aiProcess_FixInfacingNormals |
|
||||
Assimp.aiProcess_LimitBoneWeights |
|
||||
Assimp.aiProcess_GlobalScale
|
||||
Assimp.aiProcess_GlobalScale |
|
||||
Assimp.aiProcess_GenBoundingBoxes
|
||||
);
|
||||
if(rVal == null){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException(Assimp.aiGetErrorString()));
|
||||
@ -40,11 +41,18 @@ public class ModelLoader {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a model object from an ai scene
|
||||
* @param scene The ai scene
|
||||
* @param localTextureMap The local texture map stored next to the model file
|
||||
* @param path The path to the model
|
||||
* @return The model object
|
||||
*/
|
||||
public static Model createModelFromAiScene(AIScene scene, TextureMap localTextureMap, String path){
|
||||
Model rVal = null;
|
||||
if(scene != null){
|
||||
rVal = Model.createModelFromAiscene(path, scene);
|
||||
attemptAddTexturesFromPathname(path, localTextureMap, rVal);
|
||||
ModelLoader.attemptAddTexturesFromPathname(path, localTextureMap, rVal);
|
||||
LoggerInterface.loggerRenderer.DEBUG("Finished loading model " + path);
|
||||
}
|
||||
return rVal;
|
||||
|
||||
@ -6,8 +6,10 @@ import java.util.Iterator;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Vector4d;
|
||||
import org.joml.Vector3d;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIAABB;
|
||||
import org.lwjgl.assimp.AIBone;
|
||||
import org.lwjgl.assimp.AIFace;
|
||||
import org.lwjgl.assimp.AIMesh;
|
||||
@ -109,11 +111,6 @@ public class MeshLoader {
|
||||
minY = maxY = y;
|
||||
minZ = maxZ = z;
|
||||
}
|
||||
//update bounding sphere
|
||||
double dist = Math.sqrt(x*x+y*y+z*z);
|
||||
if(dist > rVal.getBoundingSphere().r){
|
||||
rVal.getBoundingSphere().r = dist;
|
||||
}
|
||||
//store vertex data
|
||||
Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0));
|
||||
transformedVertex.w = 1.0;
|
||||
@ -324,7 +321,14 @@ public class MeshLoader {
|
||||
|
||||
|
||||
|
||||
|
||||
//bounding sphere work
|
||||
{
|
||||
AIAABB aabbData = mesh.mAABB();
|
||||
AIVector3D max = aabbData.mMax();
|
||||
AIVector3D min = aabbData.mMin();
|
||||
double dist = new Vector3d(max.x(),max.y(),max.z()).distance(new Vector3d(min.x(),min.y(),min.z()));
|
||||
rVal.getBoundingSphere().r = dist / 2.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -344,7 +344,7 @@ public class Mesh {
|
||||
public void complexDraw(RenderPipelineState renderPipelineState, OpenGLState openGLState){
|
||||
|
||||
//bind vao off the rip
|
||||
glBindVertexArray(vertexArrayObject);
|
||||
GL40.glBindVertexArray(vertexArrayObject);
|
||||
Globals.renderingEngine.checkError();
|
||||
|
||||
if(renderPipelineState.getUseMeshShader()){
|
||||
@ -489,7 +489,7 @@ public class Mesh {
|
||||
}
|
||||
|
||||
if(renderPipelineState.getBufferNonStandardUniforms()){
|
||||
bufferAllUniforms(openGLState);
|
||||
this.bufferAllUniforms(openGLState);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
@ -519,7 +519,7 @@ public class Mesh {
|
||||
}
|
||||
}
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
GL40.glBindVertexArray(0);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ import org.lwjgl.assimp.AIScene;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joml.Sphered;
|
||||
import org.joml.Vector3d;
|
||||
import org.lwjgl.assimp.AIAnimation;
|
||||
@ -89,10 +90,10 @@ public class Model {
|
||||
/**
|
||||
* Loads a model from an ai scene object
|
||||
* @param path The path of the model
|
||||
* @param s the ai scene
|
||||
* @param scene the ai scene
|
||||
* @return The model object
|
||||
*/
|
||||
public static Model createModelFromAiscene(String path, AIScene s){
|
||||
public static Model createModelFromAiscene(String path, AIScene scene){
|
||||
Model rVal = new Model();
|
||||
|
||||
ModelPretransforms.ModelMetadata modelMetadata = Globals.modelPretransforms.getModel(path);
|
||||
@ -104,7 +105,7 @@ public class Model {
|
||||
//
|
||||
//load meshes
|
||||
//
|
||||
PointerBuffer meshesBuffer = s.mMeshes();
|
||||
PointerBuffer meshesBuffer = scene.mMeshes();
|
||||
rVal.meshes = new ArrayList<Mesh>();
|
||||
while(meshesBuffer.hasRemaining()){
|
||||
AIMesh aiMesh = AIMesh.create(meshesBuffer.get());
|
||||
@ -120,6 +121,7 @@ public class Model {
|
||||
rVal.boundingSphere.r = currentMesh.getBoundingSphere().r;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//register bones
|
||||
//
|
||||
@ -165,10 +167,11 @@ public class Model {
|
||||
currentMesh.getBones().add(boneIterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//parse animation nodes and form hierarchy
|
||||
//
|
||||
AINode rootNode = s.mRootNode();
|
||||
AINode rootNode = scene.mRootNode();
|
||||
//The mOffsetMatrix, inverted, is the bind pose matrix that we want to apply at the top of all anims: https://github.com/assimp/assimp/issues/4364
|
||||
//This version of assimp doesn't support it, unfortunately
|
||||
rVal.rootTransform = electrosphere.util.Utilities.convertAIMatrixd(rootNode.mTransformation());
|
||||
@ -178,12 +181,13 @@ public class Model {
|
||||
}
|
||||
LoggerInterface.loggerRenderer.DEBUG("Global Inverse Transform");
|
||||
LoggerInterface.loggerRenderer.DEBUG(rVal.rootTransform + "");
|
||||
rVal.rootAnimNode = rVal.buildAnimNodeMap(s.mRootNode(),null);
|
||||
rVal.rootAnimNode = rVal.buildAnimNodeMap(scene.mRootNode(),null);
|
||||
|
||||
//
|
||||
//load animations
|
||||
//
|
||||
int animCount = s.mNumAnimations();
|
||||
PointerBuffer animBuffer = s.mAnimations();
|
||||
int animCount = scene.mNumAnimations();
|
||||
PointerBuffer animBuffer = scene.mAnimations();
|
||||
rVal.animations = new ArrayList<Animation>();
|
||||
rVal.animMap = new HashMap<String,Animation>();
|
||||
for(int i = 0; i < animCount; i++){
|
||||
@ -191,18 +195,18 @@ public class Model {
|
||||
rVal.animations.add(newAnim);
|
||||
rVal.animMap.put(newAnim.name,newAnim);
|
||||
}
|
||||
|
||||
//
|
||||
//Load materials
|
||||
//
|
||||
if(s.mNumMaterials() > 0){
|
||||
if(scene.mNumMaterials() > 0){
|
||||
rVal.materials = new ArrayList<Material>();
|
||||
PointerBuffer material_buffer = s.mMaterials();
|
||||
PointerBuffer material_buffer = scene.mMaterials();
|
||||
while(material_buffer.hasRemaining()){
|
||||
rVal.materials.add(Material.load_material_from_aimaterial(AIMaterial.create(material_buffer.get())));
|
||||
}
|
||||
}
|
||||
//garbage collect
|
||||
System.gc();
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ import electrosphere.renderer.ui.events.Event;
|
||||
import electrosphere.renderer.ui.events.FocusEvent;
|
||||
import electrosphere.renderer.ui.events.HoverEvent;
|
||||
import electrosphere.renderer.ui.events.NavigationEvent;
|
||||
import electrosphere.renderer.ui.events.ScrollEvent;
|
||||
import electrosphere.renderer.ui.events.DragEvent.DragEventType;
|
||||
import electrosphere.renderer.ui.events.NavigationEvent.NavigationEventType;
|
||||
|
||||
@ -246,6 +247,11 @@ public class ElementService extends SignalServiceImpl {
|
||||
Vector2i absPos = getAbsolutePosition(currentElement);
|
||||
dragEvent.setRelativeX(dragEvent.getCurrentX() - absPos.x);
|
||||
dragEvent.setRelativeY(dragEvent.getCurrentY() - absPos.y);
|
||||
} else if(event instanceof ScrollEvent){
|
||||
ScrollEvent scrollEvent = (ScrollEvent)event;
|
||||
Vector2i absPos = getAbsolutePosition(currentElement);
|
||||
scrollEvent.setRelativeX((int)(scrollEvent.getMouseX() - absPos.x));
|
||||
scrollEvent.setRelativeY((int)(scrollEvent.getMouseY() - absPos.y));
|
||||
}
|
||||
propagate = currentElement.handleEvent(event);
|
||||
}
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
package electrosphere.renderer.ui.elements;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_LESS;
|
||||
import static org.lwjgl.opengl.GL11.glClear;
|
||||
import static org.lwjgl.opengl.GL11.glClearColor;
|
||||
import static org.lwjgl.opengl.GL11.glDepthMask;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.lwjgl.opengl.GL40;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.debug.DebugRendering;
|
||||
import electrosphere.renderer.framebuffer.Framebuffer;
|
||||
import electrosphere.renderer.model.Model;
|
||||
import electrosphere.renderer.ui.elementtypes.DraggableElement;
|
||||
import electrosphere.renderer.ui.elementtypes.ScrollableElement;
|
||||
import electrosphere.renderer.ui.events.DragEvent;
|
||||
import electrosphere.renderer.ui.events.DragEvent.DragEventType;
|
||||
import electrosphere.renderer.ui.events.Event;
|
||||
import electrosphere.renderer.ui.events.ScrollEvent;
|
||||
|
||||
public class ActorPanel extends BufferedStandardDrawableContainerElement implements DraggableElement {
|
||||
/**
|
||||
* Draws a 3d scene inside a panel
|
||||
*/
|
||||
public class ActorPanel extends BufferedStandardDrawableContainerElement implements DraggableElement, ScrollableElement {
|
||||
|
||||
/**
|
||||
* The default width of an actor panel
|
||||
@ -38,37 +38,138 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
*/
|
||||
public static final int DEFAULT_HEIGHT = 500;
|
||||
|
||||
/**
|
||||
* Default distance to move the camera back from the actor
|
||||
*/
|
||||
static final double DEFAULT_STANDOFF_DIST = 1.0;
|
||||
|
||||
/**
|
||||
* Default amount to increment the yaw by
|
||||
*/
|
||||
static final double DEFAULT_YAW_INCREMENT = 0.03;
|
||||
|
||||
/**
|
||||
* Multiplier applied to drag events to scale how fast the camera rotates
|
||||
*/
|
||||
static final double DRAG_MULTIPLIER = 0.5;
|
||||
|
||||
/**
|
||||
* The minimum zoom
|
||||
*/
|
||||
static final double MIN_ZOOM = 0.1;
|
||||
|
||||
/**
|
||||
* The maximum zoom
|
||||
*/
|
||||
static final double MAX_ZOOM = 10.0;
|
||||
|
||||
/**
|
||||
* Multiplier applied to scroll events to scale how fast the camera zooms
|
||||
*/
|
||||
static final double SCROLL_MULTIPLIER = 0.1;
|
||||
|
||||
/**
|
||||
* Color to clear the background with
|
||||
*/
|
||||
static Vector3f color = new Vector3f(1.0f);
|
||||
|
||||
/**
|
||||
* Color to clear the panel with
|
||||
*/
|
||||
Vector4d clearColor = new Vector4d(1.0);
|
||||
|
||||
/**
|
||||
* The actor to draw
|
||||
*/
|
||||
Actor actor;
|
||||
|
||||
/**
|
||||
* The model matrix for the actor panel
|
||||
*/
|
||||
Matrix4d modelMatrix = new Matrix4d();
|
||||
|
||||
/**
|
||||
* The current animation to play
|
||||
*/
|
||||
String currentAnim;
|
||||
|
||||
/**
|
||||
* The position of the actor
|
||||
*/
|
||||
Vector3f actorPosition = new Vector3f(0,0,0);
|
||||
|
||||
/**
|
||||
* The rotation of the actor
|
||||
*/
|
||||
Quaterniond actorRotation = new Quaterniond();
|
||||
|
||||
/**
|
||||
* The scale of the actor
|
||||
*/
|
||||
Vector3f actorScale = new Vector3f(1,1,1);
|
||||
|
||||
/**
|
||||
* The FOV of the panel
|
||||
*/
|
||||
float FOV = 50.0f;
|
||||
|
||||
/**
|
||||
* The aspec ratio of the panel
|
||||
*/
|
||||
float aspectRatio = 1.9f;
|
||||
|
||||
|
||||
/**
|
||||
* Used for calculating drawing the panel
|
||||
*/
|
||||
Vector3f texPosition = new Vector3f(0,0,0);
|
||||
|
||||
/**
|
||||
* Used for calculating drawing the panel
|
||||
*/
|
||||
Vector3f texScale = new Vector3f(1,1,0);
|
||||
|
||||
/**
|
||||
* Tracks whether this actor panel has pulled the camera back based on the bounding sphere of the model or not
|
||||
* <p>
|
||||
* This must be done during draw-phase instead of creation-phase because the model may not exist when creating
|
||||
* </p>
|
||||
*/
|
||||
boolean hasOffsetFromBoundingSphere = false;
|
||||
|
||||
/**
|
||||
* The yaw of the camera
|
||||
*/
|
||||
double yaw = 0;
|
||||
|
||||
/**
|
||||
* The pitch of the camera
|
||||
*/
|
||||
double pitch = 0;
|
||||
|
||||
/**
|
||||
* The radius of the camera
|
||||
*/
|
||||
double cameraRadius = 1.0;
|
||||
|
||||
/**
|
||||
* Fires on starting dragging the panel
|
||||
*/
|
||||
DragEventCallback onDragStart;
|
||||
|
||||
/**
|
||||
* Fires on dragging the panel
|
||||
*/
|
||||
DragEventCallback onDrag;
|
||||
|
||||
/**
|
||||
* Fires on releasing dragging thep anel
|
||||
*/
|
||||
DragEventCallback onDragRelease;
|
||||
|
||||
static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.0f,1.0f);
|
||||
|
||||
@Deprecated
|
||||
public ActorPanel(OpenGLState openGLState, int x, int y, int width, int height, Actor actor){
|
||||
super();
|
||||
|
||||
this.actor = actor;
|
||||
this.setWidth(width);
|
||||
this.setHeight(height);
|
||||
this.aspectRatio = (float)width / (float)height;
|
||||
recalculateModelMatrix();
|
||||
}
|
||||
/**
|
||||
* Fires when a scrollable event occurs
|
||||
*/
|
||||
ScrollEventCallback onScroll;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -113,14 +214,14 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
RenderingEngine.setAspectRatio(aspectRatio);
|
||||
|
||||
openGLState.glDepthTest(true);
|
||||
openGLState.glDepthFunc(GL_LESS);
|
||||
glDepthMask(true);
|
||||
openGLState.glDepthFunc(GL40.GL_LESS);
|
||||
GL40.glDepthMask(true);
|
||||
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
GL40.glClearColor((float)clearColor.x, (float)clearColor.y, (float)clearColor.z, (float)clearColor.w);
|
||||
GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
Model actorModel = Globals.assetManager.fetchModel(actor.getModelPath());
|
||||
|
||||
if(currentAnim != null){
|
||||
if((!actor.isPlayingAnimation() || !actor.isPlayingAnimation(currentAnim)) &&
|
||||
actorModel != null &&
|
||||
@ -130,6 +231,24 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
actor.incrementAnimationTime(0.0001);
|
||||
}
|
||||
}
|
||||
if(!hasOffsetFromBoundingSphere && actorModel != null){
|
||||
Globals.cameraHandler.updateRadialOffset(actorPosition);
|
||||
double radius = actorModel.getBoundingSphere().r;
|
||||
this.cameraRadius = radius + DEFAULT_STANDOFF_DIST;
|
||||
CameraEntityUtils.setOrbitalCameraDistance(Globals.playerCamera, (float)(this.cameraRadius));
|
||||
CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f(0,(float)(this.cameraRadius - DEFAULT_STANDOFF_DIST),0));
|
||||
hasOffsetFromBoundingSphere = true;
|
||||
}
|
||||
|
||||
//
|
||||
//Setup camera
|
||||
//
|
||||
yaw = yaw + DEFAULT_YAW_INCREMENT;
|
||||
this.clampYaw();
|
||||
Globals.cameraHandler.setYaw(yaw);
|
||||
Globals.cameraHandler.setPitch(pitch);
|
||||
Globals.cameraHandler.updateGlobalCamera();
|
||||
this.recalculateModelMatrix();
|
||||
|
||||
//
|
||||
// Set rendering engine state
|
||||
@ -138,7 +257,7 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
renderPipelineState.setBufferStandardUniforms(true);
|
||||
renderPipelineState.setBufferNonStandardUniforms(true);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
renderPipelineState.setUseShadowMap(true);
|
||||
renderPipelineState.setUseShadowMap(false);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(true);
|
||||
|
||||
@ -146,7 +265,6 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
actor.applySpatialData(modelMatrix,new Vector3d(actorPosition));
|
||||
actor.draw(renderPipelineState,openGLState);
|
||||
@ -201,58 +319,141 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
} else {
|
||||
LoggerInterface.loggerRenderer.ERROR("Actor Panel unable to find plane model!!", new Exception());
|
||||
}
|
||||
|
||||
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_ACTOR_PANEL){
|
||||
DebugRendering.drawUIBounds(framebuffer, boxPosition, boxDimensions, windowDrawDebugColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the animation of the actor panel's actor
|
||||
* @param animation The animation
|
||||
*/
|
||||
public void setAnimation(String animation){
|
||||
currentAnim = animation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the actor panel's actor
|
||||
* @param position The position
|
||||
*/
|
||||
public void setPosition(Vector3f position){
|
||||
this.actorPosition.set(position);
|
||||
recalculateModelMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rotation of the actor panel's actor
|
||||
* @param rotation The rotation
|
||||
*/
|
||||
public void setRotation(Quaterniond rotation){
|
||||
this.actorRotation.set(rotation);
|
||||
recalculateModelMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scale of the actor panel's actor
|
||||
* @param scale The scale
|
||||
*/
|
||||
public void setScale(Vector3f scale){
|
||||
this.actorScale.set(scale);
|
||||
recalculateModelMatrix();
|
||||
}
|
||||
|
||||
void recalculateModelMatrix(){
|
||||
/**
|
||||
* Recalculates the model matrix
|
||||
*/
|
||||
private void recalculateModelMatrix(){
|
||||
modelMatrix.identity();
|
||||
modelMatrix.translate(actorPosition);
|
||||
modelMatrix.translate(new Vector3d(actorPosition).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)));
|
||||
modelMatrix.rotate(actorRotation);
|
||||
modelMatrix.scale(new Vector3d(actorScale));
|
||||
actor.applySpatialData(modelMatrix,new Vector3d(actorPosition));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clear color of this panel
|
||||
* @param color The clear color
|
||||
*/
|
||||
public void setClearColor(Vector4d color){
|
||||
this.clearColor.set(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps the yaw value
|
||||
*/
|
||||
private void clampYaw(){
|
||||
while(yaw > 360){
|
||||
yaw = yaw - 360;
|
||||
}
|
||||
while(yaw < 0){
|
||||
yaw = yaw + 360;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps the pitch value
|
||||
*/
|
||||
private void clampPitch(){
|
||||
if(pitch >= 90){
|
||||
pitch = 89.99;
|
||||
}
|
||||
if(pitch <= -90){
|
||||
pitch = -89.99;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles any events applied to this actor panel
|
||||
*/
|
||||
public boolean handleEvent(Event event){
|
||||
boolean propagate = true;
|
||||
if(event instanceof DragEvent){
|
||||
if(onDragStart != null && ((DragEvent)event).getType() == DragEventType.START){
|
||||
if(!onDragStart.execute((DragEvent)event)){
|
||||
DragEvent dragEvent = (DragEvent)event;
|
||||
if(dragEvent.getType() == DragEventType.START){
|
||||
if(onDragStart != null){
|
||||
if(!onDragStart.execute(dragEvent)){
|
||||
propagate = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
if(dragEvent.getType() == DragEventType.DRAG){
|
||||
if(onDrag != null){
|
||||
if(!onDrag.execute(dragEvent)){
|
||||
propagate = false;
|
||||
}
|
||||
} else {
|
||||
yaw = yaw + dragEvent.getDeltaX() * DRAG_MULTIPLIER;
|
||||
this.clampYaw();
|
||||
pitch = pitch + dragEvent.getDeltaY() * DRAG_MULTIPLIER;
|
||||
this.clampPitch();
|
||||
propagate = false;
|
||||
}
|
||||
}
|
||||
if(onDrag != null && ((DragEvent)event).getType() == DragEventType.DRAG){
|
||||
if(!onDrag.execute((DragEvent)event)){
|
||||
propagate = false;
|
||||
if(dragEvent.getType() == DragEventType.RELEASE){
|
||||
if(onDragRelease != null){
|
||||
if(!onDragRelease.execute(dragEvent)){
|
||||
propagate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(onDragRelease != null && ((DragEvent)event).getType() == DragEventType.RELEASE){
|
||||
if(!onDragRelease.execute((DragEvent)event)){
|
||||
}
|
||||
if(event instanceof ScrollEvent){
|
||||
ScrollEvent scrollEvent = (ScrollEvent)event;
|
||||
if(onScroll != null){
|
||||
if(!onScroll.execute(scrollEvent)){
|
||||
propagate = false;
|
||||
}
|
||||
} else {
|
||||
this.cameraRadius = this.cameraRadius - scrollEvent.getScrollAmount() * SCROLL_MULTIPLIER;
|
||||
if(this.cameraRadius > MAX_ZOOM){
|
||||
this.cameraRadius = MAX_ZOOM;
|
||||
}
|
||||
if(this.cameraRadius < MIN_ZOOM){
|
||||
this.cameraRadius = MIN_ZOOM;
|
||||
}
|
||||
CameraEntityUtils.setOrbitalCameraDistance(Globals.playerCamera, (float)cameraRadius);
|
||||
propagate = false;
|
||||
}
|
||||
}
|
||||
return propagate;
|
||||
@ -272,6 +473,11 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme
|
||||
public void setOnDragRelease(DragEventCallback callback) {
|
||||
onDragRelease = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnScrollCallback(ScrollEventCallback callback) {
|
||||
onScroll = callback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,9 @@ public class ScrollEvent implements Event {
|
||||
double mouseX;
|
||||
double mouseY;
|
||||
|
||||
int relativeX;
|
||||
int relativeY;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param scrollAmount
|
||||
@ -19,6 +22,8 @@ public class ScrollEvent implements Event {
|
||||
this.scrollAmount = scrollAmount;
|
||||
this.mouseX = mouseX;
|
||||
this.mouseY = mouseY;
|
||||
this.relativeX = (int)mouseX;
|
||||
this.relativeY = (int)mouseY;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,5 +50,21 @@ public class ScrollEvent implements Event {
|
||||
return mouseY;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user