Proper frustum culling
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
1883ffddf3
commit
5356b3e325
@ -1,3 +1,3 @@
|
|||||||
#maven.buildNumber.plugin properties file
|
#maven.buildNumber.plugin properties file
|
||||||
#Thu Feb 29 11:18:06 EST 2024
|
#Thu Feb 29 18:57:13 EST 2024
|
||||||
buildNumber=29
|
buildNumber=30
|
||||||
|
|||||||
9
docs/src/rendering/actors/actorsindex.md
Normal file
9
docs/src/rendering/actors/actorsindex.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
@page actorsindex Actors
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
- @subpage texturemask
|
||||||
|
- @subpage bonerotators
|
||||||
|
- @subpage staticmorph
|
||||||
|
- @subpage shadermask
|
||||||
|
- @subpage animationmask
|
||||||
|
- @subpage meshmask
|
||||||
5
docs/src/rendering/actors/animationmask.md
Normal file
5
docs/src/rendering/actors/animationmask.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@page animationmask Animation Mask
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
use example: play running animation for whole actor, but then mask crafting animation on top of bones from torso up
|
||||||
5
docs/src/rendering/actors/bonerotators.md
Normal file
5
docs/src/rendering/actors/bonerotators.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@page bonerotators Actor Bone Rotators
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
use example: rotate torso to tilt based on whatever the player is locked on to, so that they swing at goblins below them and harpies above them
|
||||||
5
docs/src/rendering/actors/meshmask.md
Normal file
5
docs/src/rendering/actors/meshmask.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@page meshmask Mesh Mask
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
use example: overwriting a mesh without clothing to one with clothing
|
||||||
5
docs/src/rendering/actors/shadermask.md
Normal file
5
docs/src/rendering/actors/shadermask.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@page shadermask Shader Mask
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
use example: override default cube shader to use a shader that does raymarching
|
||||||
5
docs/src/rendering/actors/staticmorph.md
Normal file
5
docs/src/rendering/actors/staticmorph.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@page staticmorph Actor Static Morph
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
use example: scale something that was exported from blender waayyyyyy too large
|
||||||
3
docs/src/rendering/actors/texturemask.md
Normal file
3
docs/src/rendering/actors/texturemask.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@page texturemask Actor Texture Mask
|
||||||
|
|
||||||
|
TODO
|
||||||
@ -90,7 +90,7 @@ public class FoliageCell {
|
|||||||
instancedActor.setPriority((int)grassPosition.distance(playerPosition));
|
instancedActor.setPriority((int)grassPosition.distance(playerPosition));
|
||||||
|
|
||||||
//draw
|
//draw
|
||||||
instancedActor.draw(Globals.renderingEngine.getRenderPipelineState());
|
instancedActor.draw(Globals.renderingEngine.getRenderPipelineState(), new Vector3d(cameraModifiedPosition));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package electrosphere.client.instancing;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityTags;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.renderer.actor.instance.InstancedActor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for updating instance priority
|
||||||
|
*/
|
||||||
|
public class InstanceUpdater {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all instanced actors to have priority based on distance from camera
|
||||||
|
*/
|
||||||
|
public static void updateInstancedActorPriority(){
|
||||||
|
Vector3d eyePosition = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||||
|
for(Entity entity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){
|
||||||
|
//set priority equal to distance
|
||||||
|
Vector3d entityPosition = EntityUtils.getPosition(entity);
|
||||||
|
InstancedActor.getInstancedActor(entity).setPriority((int)entityPosition.distance(eyePosition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package electrosphere.client.sim;
|
package electrosphere.client.sim;
|
||||||
|
|
||||||
|
import electrosphere.client.instancing.InstanceUpdater;
|
||||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
@ -28,6 +29,7 @@ public class ClientFunctions {
|
|||||||
ClientTerrainManager.generateTerrainChunkGeometry();
|
ClientTerrainManager.generateTerrainChunkGeometry();
|
||||||
updateSkyboxPos();
|
updateSkyboxPos();
|
||||||
Globals.clientSceneWrapper.destroyEntitiesOutsideSimRange();
|
Globals.clientSceneWrapper.destroyEntitiesOutsideSimRange();
|
||||||
|
InstanceUpdater.updateInstancedActorPriority();
|
||||||
// updateCellManager();
|
// updateCellManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,10 +74,6 @@ public class ClientSimulation {
|
|||||||
}
|
}
|
||||||
//clear collidable impulse lists
|
//clear collidable impulse lists
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
||||||
//delete all client side entities that aren't in visible chunks
|
|
||||||
if(Globals.clientEntityCullingManager != null){
|
|
||||||
Globals.clientEntityCullingManager.clearOutOfBoundsEntities();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import electrosphere.entity.types.terrain.TerrainChunkData;
|
|||||||
public class CollisionBodyCreation {
|
public class CollisionBodyCreation {
|
||||||
|
|
||||||
//Matrix for correcting initial axis of eg cylinders or capsules
|
//Matrix for correcting initial axis of eg cylinders or capsules
|
||||||
static final DMatrix3 AXIS_CORRECTION_MATRIX = new DMatrix3(
|
public static final DMatrix3 AXIS_CORRECTION_MATRIX = new DMatrix3(
|
||||||
1.0000000, 0.0000000, 0.0000000,
|
1.0000000, 0.0000000, 0.0000000,
|
||||||
0.0000000, 0.0000000, -1.0000000,
|
0.0000000, 0.0000000, -1.0000000,
|
||||||
0.0000000, 1.0000000, 0.0000000
|
0.0000000, 1.0000000, 0.0000000
|
||||||
@ -65,7 +65,7 @@ public class CollisionBodyCreation {
|
|||||||
public static DBody createCylinderBody(CollisionEngine collisionEngine, double radius, double length){
|
public static DBody createCylinderBody(CollisionEngine collisionEngine, double radius, double length){
|
||||||
DCylinder geom = collisionEngine.createCylinderGeom(radius,length);
|
DCylinder geom = collisionEngine.createCylinderGeom(radius,length);
|
||||||
DBody returnBody = collisionEngine.createDBody(geom);
|
DBody returnBody = collisionEngine.createDBody(geom);
|
||||||
geom.setOffsetRotation(AXIS_CORRECTION_MATRIX); //ode4j required geom to already be on body before rotating for some reason
|
collisionEngine.setOffsetRotation(geom); //ode4j required geom to already be on body before rotating for some reason
|
||||||
return returnBody;
|
return returnBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -671,6 +671,16 @@ public class CollisionEngine {
|
|||||||
spaceLock.release();
|
spaceLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corrects the initial axis of eg cylinders or capsules
|
||||||
|
* @param geom the geometry to correct
|
||||||
|
*/
|
||||||
|
protected void setOffsetRotation(DGeom geom){
|
||||||
|
spaceLock.acquireUninterruptibly();
|
||||||
|
geom.setOffsetRotation(CollisionBodyCreation.AXIS_CORRECTION_MATRIX);
|
||||||
|
spaceLock.release();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the position of the body in a thread-safe way
|
* Gets the position of the body in a thread-safe way
|
||||||
* @param body The body to get the position of
|
* @param body The body to get the position of
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Sphered;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4d;
|
import org.joml.Vector4d;
|
||||||
@ -114,6 +115,9 @@ public class Mesh {
|
|||||||
|
|
||||||
Material material;
|
Material material;
|
||||||
|
|
||||||
|
//the bounding sphere for this mesh
|
||||||
|
Sphered boundingSphere;
|
||||||
|
|
||||||
public static Mesh create_mesh_from_aimesh(AIMesh mesh, ModelPretransforms.MeshMetadata metadata){
|
public static Mesh create_mesh_from_aimesh(AIMesh mesh, ModelPretransforms.MeshMetadata metadata){
|
||||||
boolean has_bones = false;
|
boolean has_bones = false;
|
||||||
boolean apply_lighting = true;
|
boolean apply_lighting = true;
|
||||||
@ -184,6 +188,7 @@ public class Mesh {
|
|||||||
float x = vertex.x();
|
float x = vertex.x();
|
||||||
float y = vertex.y();
|
float y = vertex.y();
|
||||||
float z = vertex.z();
|
float z = vertex.z();
|
||||||
|
//store dimensions of the model
|
||||||
if(definedDimensions){
|
if(definedDimensions){
|
||||||
if(x < minX){ minX = x; }
|
if(x < minX){ minX = x; }
|
||||||
if(x > maxX){ maxX = x; }
|
if(x > maxX){ maxX = x; }
|
||||||
@ -197,6 +202,12 @@ public class Mesh {
|
|||||||
minY = maxY = y;
|
minY = maxY = y;
|
||||||
minZ = maxZ = z;
|
minZ = maxZ = z;
|
||||||
}
|
}
|
||||||
|
//update bounding sphere
|
||||||
|
double dist = Math.sqrt(x*x+y*y+z*z);
|
||||||
|
if(dist > rVal.boundingSphere.r){
|
||||||
|
rVal.boundingSphere.r = dist;
|
||||||
|
}
|
||||||
|
//store vertex data
|
||||||
Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0));
|
Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0));
|
||||||
transformedVertex.w = 1.0;
|
transformedVertex.w = 1.0;
|
||||||
temp[0] = (float)transformedVertex.x;
|
temp[0] = (float)transformedVertex.x;
|
||||||
@ -456,7 +467,7 @@ public class Mesh {
|
|||||||
|
|
||||||
|
|
||||||
public Mesh(){
|
public Mesh(){
|
||||||
|
this.boundingSphere = new Sphered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -745,4 +756,26 @@ public class Mesh {
|
|||||||
}
|
}
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the bounding sphere of the mesh
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param z
|
||||||
|
* @param r
|
||||||
|
*/
|
||||||
|
public void updateBoundingSphere(float x, float y, float z, float r){
|
||||||
|
this.boundingSphere.x = x;
|
||||||
|
this.boundingSphere.y = y;
|
||||||
|
this.boundingSphere.z = z;
|
||||||
|
this.boundingSphere.r = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bounding sphere of this mesh
|
||||||
|
* @return The bounding sphere
|
||||||
|
*/
|
||||||
|
public Sphered getBoundingSphere(){
|
||||||
|
return this.boundingSphere;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Sphered;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.lwjgl.assimp.AIAnimation;
|
import org.lwjgl.assimp.AIAnimation;
|
||||||
import org.lwjgl.assimp.AIBone;
|
import org.lwjgl.assimp.AIBone;
|
||||||
@ -72,6 +73,15 @@ public class Model {
|
|||||||
Map<String,ActorShaderMask> shaderMask = new HashMap<String,ActorShaderMask>();
|
Map<String,ActorShaderMask> shaderMask = new HashMap<String,ActorShaderMask>();
|
||||||
Map<String,ActorTextureMask> textureMap = null;
|
Map<String,ActorTextureMask> textureMap = null;
|
||||||
|
|
||||||
|
//The bounding sphere for this particular model
|
||||||
|
Sphered boundingSphere;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a model from an ai scene object
|
||||||
|
* @param path The path of the model
|
||||||
|
* @param s the ai scene
|
||||||
|
* @return The model object
|
||||||
|
*/
|
||||||
public static Model createModelFromAiscene(String path, AIScene s){
|
public static Model createModelFromAiscene(String path, AIScene s){
|
||||||
Model rVal = new Model();
|
Model rVal = new Model();
|
||||||
//
|
//
|
||||||
@ -100,6 +110,10 @@ public class Model {
|
|||||||
Mesh currentMesh = Mesh.create_mesh_from_aimesh(aiMesh, meshMetadata);
|
Mesh currentMesh = Mesh.create_mesh_from_aimesh(aiMesh, meshMetadata);
|
||||||
rVal.meshes.add(currentMesh);
|
rVal.meshes.add(currentMesh);
|
||||||
currentMesh.parent = rVal;
|
currentMesh.parent = rVal;
|
||||||
|
//update model bounding sphere
|
||||||
|
if(currentMesh.boundingSphere.r > rVal.boundingSphere.r){
|
||||||
|
rVal.boundingSphere.r = currentMesh.boundingSphere.r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
//register bones
|
//register bones
|
||||||
@ -211,6 +225,7 @@ public class Model {
|
|||||||
modelMatrix = new Matrix4d();
|
modelMatrix = new Matrix4d();
|
||||||
program = null;
|
program = null;
|
||||||
globalInverseTransform = null;
|
globalInverseTransform = null;
|
||||||
|
this.boundingSphere = new Sphered();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void free() {
|
public void free() {
|
||||||
@ -532,4 +547,20 @@ public class Model {
|
|||||||
mesh.setMaterial(material);
|
mesh.setMaterial(material);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bounding sphere for this model
|
||||||
|
* @return The bounding sphere
|
||||||
|
*/
|
||||||
|
public Sphered getBoundingSphere(){
|
||||||
|
return boundingSphere;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the bounding sphere
|
||||||
|
* @param boundingSphere The bounding sphere to be stored
|
||||||
|
*/
|
||||||
|
public void setBoundingSphere(Sphered boundingSphere){
|
||||||
|
this.boundingSphere = boundingSphere;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
package electrosphere.renderer;
|
package electrosphere.renderer;
|
||||||
|
|
||||||
|
import org.joml.FrustumIntersection;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
import electrosphere.renderer.actor.instance.InstanceData;
|
import electrosphere.renderer.actor.instance.InstanceData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,6 +56,9 @@ public class RenderPipelineState {
|
|||||||
//The pointer to the current shader program bound
|
//The pointer to the current shader program bound
|
||||||
int currentShaderPointer;
|
int currentShaderPointer;
|
||||||
|
|
||||||
|
//JOML-provided object to perform frustum culling
|
||||||
|
FrustumIntersection frustumInt = new FrustumIntersection();
|
||||||
|
|
||||||
public boolean getUseMeshShader(){
|
public boolean getUseMeshShader(){
|
||||||
return this.useMeshShader;
|
return this.useMeshShader;
|
||||||
}
|
}
|
||||||
@ -141,4 +147,24 @@ public class RenderPipelineState {
|
|||||||
this.currentShaderPointer = currentShaderPointer;
|
this.currentShaderPointer = currentShaderPointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the frustum intersection with the provided projection and view matrices
|
||||||
|
* @param projectionMatrix the projection matrix
|
||||||
|
* @param viewMatrix the view matrix
|
||||||
|
*/
|
||||||
|
public void updateFrustumIntersection(Matrix4f projectionMatrix, Matrix4f viewMatrix){
|
||||||
|
Matrix4f projectionViewMatrix = new Matrix4f();
|
||||||
|
projectionViewMatrix.set(projectionMatrix);
|
||||||
|
projectionViewMatrix.mul(viewMatrix);
|
||||||
|
this.frustumInt.set(projectionViewMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current render pipeline's frustum intersection object
|
||||||
|
* @return The frustum intersection object
|
||||||
|
*/
|
||||||
|
public FrustumIntersection getFrustumIntersection(){
|
||||||
|
return frustumInt;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,6 +65,7 @@ import org.joml.Matrix4d;
|
|||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Sphered;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
@ -182,8 +183,6 @@ public class RenderingEngine {
|
|||||||
|
|
||||||
LightManager lightManager;
|
LightManager lightManager;
|
||||||
|
|
||||||
static float currentViewPlanarAngle;
|
|
||||||
|
|
||||||
ShaderProgram activeProgram;
|
ShaderProgram activeProgram;
|
||||||
|
|
||||||
static int outputFramebuffer = 0;
|
static int outputFramebuffer = 0;
|
||||||
@ -192,6 +191,7 @@ public class RenderingEngine {
|
|||||||
static float aspectRatio = 1.0f;
|
static float aspectRatio = 1.0f;
|
||||||
static float verticalFOV = 90.0f;
|
static float verticalFOV = 90.0f;
|
||||||
|
|
||||||
|
//the current state of the rendering pipeline
|
||||||
static RenderPipelineState renderPipelineState = new RenderPipelineState();
|
static RenderPipelineState renderPipelineState = new RenderPipelineState();
|
||||||
|
|
||||||
|
|
||||||
@ -409,32 +409,22 @@ public class RenderingEngine {
|
|||||||
return origin.distance(target);
|
return origin.distance(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
static boolean drawPoint(Vector3f cameraPos, Vector3f position){
|
* Updates the frustum box of the render pipeline
|
||||||
boolean rVal = true;
|
*/
|
||||||
float phi = (float)Math.abs((calculateAngle(cameraPos,position) - currentViewPlanarAngle) % (Math.PI * 2.0f));
|
void updateFrustumBox(){
|
||||||
if(phi > Math.PI){
|
renderPipelineState.updateFrustumIntersection(Globals.projectionMatrix, Globals.viewMatrix);
|
||||||
phi = (float)(Math.PI * 2) - phi;
|
|
||||||
}
|
|
||||||
float rotationalDiff = phi;
|
|
||||||
float dist = calculateDist(new Vector3f(cameraPos.x,0,cameraPos.z), new Vector3f(position.x,0,position.z));
|
|
||||||
if(rotationalDiff > (Globals.verticalFOV / 180 * Math.PI) && dist > 300){
|
|
||||||
rVal = false;
|
|
||||||
}
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calculateRenderingAngle(){
|
|
||||||
currentViewPlanarAngle = calculateAngle(CameraEntityUtils.getCameraEye(Globals.playerCamera), new Vector3f(0,0,0));
|
|
||||||
// System.out.println(currentViewPlanarAngle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function to draw the screen
|
||||||
|
*/
|
||||||
public void drawScreen(){
|
public void drawScreen(){
|
||||||
|
|
||||||
//calculate render angle for frustum culling
|
//calculate render angle for frustum culling
|
||||||
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
|
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
|
||||||
calculateRenderingAngle();
|
updateFrustumBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -581,7 +571,6 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
|
|
||||||
currentEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW)
|
currentEntity.containsKey(EntityDataStrings.DRAW_CAST_SHADOW)
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
@ -658,8 +647,7 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null &&
|
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
|
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||||
@ -679,8 +667,7 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null &&
|
currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null &&
|
||||||
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null &&
|
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
|
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
|
InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
|
||||||
@ -696,15 +683,13 @@ public class RenderingEngine {
|
|||||||
new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w),
|
new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w),
|
||||||
new Vector3f(EntityUtils.getScale(currentEntity))
|
new Vector3f(EntityUtils.getScale(currentEntity))
|
||||||
);
|
);
|
||||||
// modelTransformMatrix.translate(cameraModifiedPosition);
|
|
||||||
// modelTransformMatrix.rotate(rotation);
|
|
||||||
// modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
|
|
||||||
//set actor value
|
//set actor value
|
||||||
currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix));
|
currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix));
|
||||||
// ((Matrix4f)currentActor.getAttributeValue(modelAttribute)).set(modelTransformMatrix);
|
//draw
|
||||||
|
currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition));
|
||||||
|
} else {
|
||||||
|
currentActor.draw(renderPipelineState);
|
||||||
}
|
}
|
||||||
//draw
|
|
||||||
currentActor.draw(renderPipelineState);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//draw all instanced models
|
//draw all instanced models
|
||||||
@ -747,8 +732,7 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null &&
|
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
|
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||||
@ -768,13 +752,27 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null &&
|
currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) != null &&
|
||||||
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null &&
|
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
|
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
|
InstancedActor currentActor = InstancedActor.getInstancedActor(currentEntity);
|
||||||
//draw
|
//if the shader attribute for model matrix exists, calculate the model matrix and apply
|
||||||
if(currentActor != null){
|
if(InstancedActor.getInstanceModelAttribute(currentEntity) != null){
|
||||||
|
ShaderAttribute modelAttribute = InstancedActor.getInstanceModelAttribute(currentEntity);
|
||||||
|
//calculate model matrix
|
||||||
|
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
|
Quaterniond rotation = EntityUtils.getRotation(currentEntity);
|
||||||
|
// modelTransformMatrix.identity();
|
||||||
|
modelTransformMatrix.identity().translationRotateScale(
|
||||||
|
cameraModifiedPosition,
|
||||||
|
new Quaternionf((float)rotation.x,(float)rotation.y,(float)rotation.z,(float)rotation.w),
|
||||||
|
new Vector3f(EntityUtils.getScale(currentEntity))
|
||||||
|
);
|
||||||
|
//set actor value
|
||||||
|
currentActor.setAttribute(modelAttribute, new Matrix4f(modelTransformMatrix));
|
||||||
|
//draw
|
||||||
|
currentActor.draw(renderPipelineState, new Vector3d(cameraModifiedPosition));
|
||||||
|
} else {
|
||||||
currentActor.draw(renderPipelineState);
|
currentActor.draw(renderPipelineState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -833,8 +831,7 @@ public class RenderingEngine {
|
|||||||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
|
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
|
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||||
@ -1080,8 +1077,7 @@ public class RenderingEngine {
|
|||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null &&
|
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null &&
|
||||||
currentEntity.getData(EntityDataStrings.DRAW_OUTLINE) != null &&
|
currentEntity.getData(EntityDataStrings.DRAW_OUTLINE) != null
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
|
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||||
@ -1334,7 +1330,6 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
|
|
||||||
currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC)
|
currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC)
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
@ -1372,7 +1367,6 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
|
|
||||||
!currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC)
|
!currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC)
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
@ -1421,7 +1415,6 @@ public class RenderingEngine {
|
|||||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||||
if(
|
if(
|
||||||
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
|
||||||
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) &&
|
|
||||||
currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC)
|
currentEntity.containsKey(EntityDataStrings.DRAW_VOLUMETRIC)
|
||||||
){
|
){
|
||||||
//fetch actor
|
//fetch actor
|
||||||
|
|||||||
@ -17,23 +17,50 @@ import org.joml.Matrix4d;
|
|||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
|
import org.joml.Sphered;
|
||||||
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4d;
|
import org.joml.Vector4d;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* An actor
|
||||||
* @author amaterasu
|
* Container for a model that keeps track of:
|
||||||
|
* - Animation state
|
||||||
|
* - Mesh overrides
|
||||||
|
* - Shader overrides
|
||||||
|
* - Texture overrides
|
||||||
|
* - Bone overrides
|
||||||
|
* - Static Morphs (think scaling something, but from creatures.json)
|
||||||
*/
|
*/
|
||||||
public class Actor {
|
public class Actor {
|
||||||
|
|
||||||
|
//the model path of the model backing the actor
|
||||||
String modelPath;
|
String modelPath;
|
||||||
|
|
||||||
|
//used for statically binding textures in pipelines that dont bind textures on a per-mesh level
|
||||||
|
//ie when in the ui, this can be set to bind a texture at the actor level
|
||||||
String textureOverride;
|
String textureOverride;
|
||||||
|
|
||||||
|
//scales the time that animations are played at
|
||||||
float animationScalar = 1.0f;
|
float animationScalar = 1.0f;
|
||||||
|
|
||||||
|
//The stack of animations being applied to a given actor
|
||||||
PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>();
|
PriorityQueue<ActorAnimationMask> animationQueue = new PriorityQueue<ActorAnimationMask>();
|
||||||
|
|
||||||
|
//Mask for overwriting meshes in a given actor
|
||||||
ActorMeshMask meshMask = new ActorMeshMask();
|
ActorMeshMask meshMask = new ActorMeshMask();
|
||||||
|
|
||||||
|
//optional overrides for specific shaders
|
||||||
List<ActorShaderMask> shaderMasks = new LinkedList<ActorShaderMask>();
|
List<ActorShaderMask> shaderMasks = new LinkedList<ActorShaderMask>();
|
||||||
|
|
||||||
|
//optional overrides for textures
|
||||||
Map<String,ActorTextureMask> textureMap = null;
|
Map<String,ActorTextureMask> textureMap = null;
|
||||||
|
|
||||||
|
//bone rotators
|
||||||
Map<String,ActorBoneRotator> boneRotators = new HashMap<String,ActorBoneRotator>();
|
Map<String,ActorBoneRotator> boneRotators = new HashMap<String,ActorBoneRotator>();
|
||||||
|
|
||||||
|
//static morph for this specific actor
|
||||||
ActorStaticMorph staticMorph;
|
ActorStaticMorph staticMorph;
|
||||||
|
|
||||||
public Actor(String modelPath){
|
public Actor(String modelPath){
|
||||||
@ -52,18 +79,6 @@ public class Actor {
|
|||||||
for(ActorAnimationMask mask : toRemoveMasks){
|
for(ActorAnimationMask mask : toRemoveMasks){
|
||||||
animationQueue.remove(mask);
|
animationQueue.remove(mask);
|
||||||
}
|
}
|
||||||
// if(playingAnimation){
|
|
||||||
// animationTime = animationTime + deltaTime * animationScalar;
|
|
||||||
// }
|
|
||||||
// if(model != null){
|
|
||||||
// if(animation != null){
|
|
||||||
// model.playAnimation(animation);
|
|
||||||
// model.incrementTime(animationTime);
|
|
||||||
// if(model.currentAnimation == null){
|
|
||||||
// playingAnimation = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getAnimationTime(String animationName){
|
public double getAnimationTime(String animationName){
|
||||||
@ -100,10 +115,6 @@ public class Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public String getCurrentAnimation(){
|
|
||||||
// return animation;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void playAnimation(String animationName, int priority){
|
public void playAnimation(String animationName, int priority){
|
||||||
// animationTime = 0;
|
// animationTime = 0;
|
||||||
// playingAnimation = true;
|
// playingAnimation = true;
|
||||||
@ -170,10 +181,6 @@ public class Actor {
|
|||||||
model.updateNodeTransform(boneRotators,staticMorph);
|
model.updateNodeTransform(boneRotators,staticMorph);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public boolean isPlayingAnimation(){
|
|
||||||
// return playingAnimation;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setAnimationScalar(float animationScalar) {
|
public void setAnimationScalar(float animationScalar) {
|
||||||
this.animationScalar = animationScalar;
|
this.animationScalar = animationScalar;
|
||||||
}
|
}
|
||||||
@ -185,10 +192,14 @@ public class Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws an actor
|
||||||
|
* @param renderPipelineState The render pipeline state to draw within
|
||||||
|
*/
|
||||||
public void draw(RenderPipelineState renderPipelineState){
|
public void draw(RenderPipelineState renderPipelineState){
|
||||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||||
boolean hasDrawn = false;
|
boolean hasDrawn = false;
|
||||||
if(model != null){
|
if(model != null && isWithinFrustumBox(renderPipelineState,model)){
|
||||||
applyAnimationMasks(model);
|
applyAnimationMasks(model);
|
||||||
meshMask.processMeshMaskQueue();
|
meshMask.processMeshMaskQueue();
|
||||||
model.setMeshMask(meshMask);
|
model.setMeshMask(meshMask);
|
||||||
@ -353,5 +364,17 @@ public class Actor {
|
|||||||
return this.staticMorph;
|
return this.staticMorph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a given model is within the render pipeline state's frustum box
|
||||||
|
* @param renderPipelineState The render pipeline state
|
||||||
|
* @param model The model
|
||||||
|
* @return true if it is within the box, false otherwise
|
||||||
|
*/
|
||||||
|
static boolean isWithinFrustumBox(RenderPipelineState renderPipelineState, Model model){
|
||||||
|
Sphered sphere = model.getBoundingSphere();
|
||||||
|
Vector3d modelPosition = model.modelMatrix.getTranslation(new Vector3d());
|
||||||
|
return renderPipelineState.getFrustumIntersection().testSphere((float)(sphere.x + modelPosition.x), (float)(sphere.y + modelPosition.y), (float)(sphere.z + modelPosition.z), (float)sphere.r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,10 @@ package electrosphere.renderer.actor;
|
|||||||
|
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional rotation to be applied to a bone that can be programmatically controlled and applied alongside another animation.
|
||||||
|
* For instance, having a character look at something, turn their torso mid animation, or hair rotating around.
|
||||||
|
*/
|
||||||
public class ActorBoneRotator {
|
public class ActorBoneRotator {
|
||||||
|
|
||||||
Quaternionf rotation = new Quaternionf().identity();
|
Quaternionf rotation = new Quaternionf().identity();
|
||||||
|
|||||||
@ -7,6 +7,10 @@ import org.joml.Matrix4f;
|
|||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A static morph that is applied to an actor if it is defined in a pipeline creating an actor.
|
||||||
|
* For instance, if you provide a static morph for the model in an item in creatures.json, this is the structure that will actually hold that data
|
||||||
|
*/
|
||||||
public class ActorStaticMorph {
|
public class ActorStaticMorph {
|
||||||
|
|
||||||
Map<String,StaticMorphTransforms> boneTransformMap = new HashMap<String,StaticMorphTransforms>();
|
Map<String,StaticMorphTransforms> boneTransformMap = new HashMap<String,StaticMorphTransforms>();
|
||||||
|
|||||||
@ -3,11 +3,15 @@ package electrosphere.renderer.actor.instance;
|
|||||||
import java.nio.DoubleBuffer;
|
import java.nio.DoubleBuffer;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NavigableSet;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.concurrent.ConcurrentSkipListSet;
|
||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
@ -37,8 +41,8 @@ public class InstanceData {
|
|||||||
//the number of draw calls since the last clear operation
|
//the number of draw calls since the last clear operation
|
||||||
int drawCalls = 0;
|
int drawCalls = 0;
|
||||||
|
|
||||||
//The priority queue of instanced actors to draw
|
//The set of instanced actors to draw
|
||||||
PriorityQueue<InstancedActor> actorQueue = null;
|
List<InstancedActor> actorQueue = null;
|
||||||
//Map of actor to index in the buffers that are emitted
|
//Map of actor to index in the buffers that are emitted
|
||||||
Map<InstancedActor,Integer> actorIndexMap = new HashMap<InstancedActor,Integer>();
|
Map<InstancedActor,Integer> actorIndexMap = new HashMap<InstancedActor,Integer>();
|
||||||
//Map of index -> actor used for buffer evictions
|
//Map of index -> actor used for buffer evictions
|
||||||
@ -60,7 +64,7 @@ public class InstanceData {
|
|||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
this.vertexShaderPath = vertexPath;
|
this.vertexShaderPath = vertexPath;
|
||||||
this.fragmentShaderPath = fragmentPath;
|
this.fragmentShaderPath = fragmentPath;
|
||||||
actorQueue = new PriorityQueue<InstancedActor>(this.capacity);
|
actorQueue = new LinkedList<InstancedActor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,6 +183,7 @@ public class InstanceData {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
actorQueue.sort(Comparator.naturalOrder());
|
||||||
//buffer data
|
//buffer data
|
||||||
for(InstancedActor actor : actorQueue){
|
for(InstancedActor actor : actorQueue){
|
||||||
//push values to attribute buffers
|
//push values to attribute buffers
|
||||||
|
|||||||
@ -6,11 +6,14 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Sphered;
|
||||||
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.Model;
|
import electrosphere.renderer.Model;
|
||||||
import electrosphere.renderer.RenderPipelineState;
|
import electrosphere.renderer.RenderPipelineState;
|
||||||
@ -41,6 +44,23 @@ public class InstancedActor implements Comparable<InstancedActor> {
|
|||||||
/**
|
/**
|
||||||
* Draws the instanced actor. Should be called normally in a loop as if this was a regular actor.
|
* Draws the instanced actor. Should be called normally in a loop as if this was a regular actor.
|
||||||
* @param renderPipelineState The pipeline state of the instanced actor
|
* @param renderPipelineState The pipeline state of the instanced actor
|
||||||
|
* @param position The position used for frustum checking
|
||||||
|
*/
|
||||||
|
public void draw(RenderPipelineState renderPipelineState, Vector3d position){
|
||||||
|
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||||
|
if(model != null){
|
||||||
|
Sphered boundingSphere = model.getBoundingSphere();
|
||||||
|
//frustum check if the model matrix exists (and we therefore can get position)
|
||||||
|
boolean frustumCheck = renderPipelineState.getFrustumIntersection().testSphere((float)(position.x + boundingSphere.x), (float)(position.y + boundingSphere.y), (float)(position.z + boundingSphere.z), (float)boundingSphere.r);
|
||||||
|
if(frustumCheck){
|
||||||
|
Globals.clientInstanceManager.addToQueue(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the instanced actor WITHOUT frustum checking. Otherwise identical to the call with frustum checking
|
||||||
|
* @param renderPipelineState
|
||||||
*/
|
*/
|
||||||
public void draw(RenderPipelineState renderPipelineState){
|
public void draw(RenderPipelineState renderPipelineState){
|
||||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import electrosphere.renderer.Material;
|
|||||||
import electrosphere.renderer.Mesh;
|
import electrosphere.renderer.Mesh;
|
||||||
import electrosphere.renderer.Model;
|
import electrosphere.renderer.Model;
|
||||||
import electrosphere.renderer.ShaderProgram;
|
import electrosphere.renderer.ShaderProgram;
|
||||||
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
public class TerrainChunkModelGeneration {
|
public class TerrainChunkModelGeneration {
|
||||||
|
|
||||||
@ -775,6 +776,13 @@ public class TerrainChunkModelGeneration {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float halfChunk = ServerTerrainChunk.CHUNK_DIMENSION / 2.0f;
|
||||||
|
mesh.updateBoundingSphere(
|
||||||
|
halfChunk,
|
||||||
|
halfChunk,
|
||||||
|
halfChunk,
|
||||||
|
(float)Math.sqrt(halfChunk * halfChunk + halfChunk * halfChunk + halfChunk * halfChunk)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -805,6 +813,7 @@ public class TerrainChunkModelGeneration {
|
|||||||
m.parent = rVal;
|
m.parent = rVal;
|
||||||
|
|
||||||
rVal.meshes.add(m);
|
rVal.meshes.add(m);
|
||||||
|
rVal.setBoundingSphere(m.getBoundingSphere());
|
||||||
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user