fluid work
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit
This commit is contained in:
parent
080cdeca33
commit
dfc59e0ea6
@ -92,6 +92,36 @@
|
||||
"offsetZ" : 0
|
||||
},
|
||||
"iconPath" : "Textures/icons/itemIconItemGeneric.png"
|
||||
},
|
||||
{
|
||||
"id" : "waterSpawner",
|
||||
"tokens" : [
|
||||
"GRAVITY",
|
||||
"TARGETABLE"
|
||||
],
|
||||
"equipData": {
|
||||
"equipClass" : "tool"
|
||||
},
|
||||
"graphicsTemplate": {
|
||||
"model": {
|
||||
"path" : "Models/basic/geometry/unitvector.glb"
|
||||
}
|
||||
},
|
||||
"clientSideSecondary": "SPAWN_WATER",
|
||||
"collidable": {
|
||||
"type" : "CUBE",
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
},
|
||||
"iconPath" : "Textures/icons/itemIconItemGeneric.png"
|
||||
}
|
||||
],
|
||||
"files" : [
|
||||
|
||||
@ -34,5 +34,11 @@ export const clientHooks: Hook[] = [
|
||||
callback: (engine: Engine) => {
|
||||
engine.classes.levelEditorUtils.static.inspectEntity()
|
||||
}
|
||||
},
|
||||
{
|
||||
signal: "SPAWN_WATER",
|
||||
callback: (engine: Engine) => {
|
||||
engine.classes.voxelUtils.static.spawnWater()
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -8,4 +8,9 @@ export interface ClientVoxelUtils {
|
||||
*/
|
||||
readonly applyEdit: () => void
|
||||
|
||||
/**
|
||||
* Spawns water at the player's cursor
|
||||
*/
|
||||
readonly spawnWater: () => void
|
||||
|
||||
}
|
||||
@ -1,36 +1,8 @@
|
||||
#version 330 core
|
||||
|
||||
#define NR_POINT_LIGHTS 10
|
||||
|
||||
out vec4 FragColor;
|
||||
#version 450 core
|
||||
#extension GL_ARB_shading_language_include : require
|
||||
#include "../../lib/lights.fs"
|
||||
|
||||
|
||||
layout (std140) uniform Lights {
|
||||
// this is how many because we have to align
|
||||
// bytes it SHOULD in multiples of 16, this
|
||||
// take it where it ACTUALLY is
|
||||
//
|
||||
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
|
||||
//
|
||||
// base alignment aligned offset
|
||||
//direct light
|
||||
vec3 dLDirection; // 16 0
|
||||
vec3 dLAmbient; // 16 16
|
||||
vec3 dLDiffuse; // 16 32
|
||||
vec3 dLSpecular; // 16 48
|
||||
|
||||
//point light
|
||||
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
|
||||
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
|
||||
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
|
||||
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
|
||||
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
|
||||
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
|
||||
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
|
||||
|
||||
//for a total size of 1184
|
||||
|
||||
};
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
@ -47,26 +19,12 @@ in vec4 FragPosLightSpace;
|
||||
|
||||
|
||||
uniform vec3 viewPos;
|
||||
// uniform DirLight dirLight;
|
||||
// uniform PointLight pointLights[NR_POINT_LIGHTS];
|
||||
// uniform SpotLight spotLight;
|
||||
uniform Material material;
|
||||
|
||||
//texture stuff
|
||||
// uniform sampler2D ourTexture;
|
||||
uniform int hasTransparency;
|
||||
// uniform sampler2D specularTexture;
|
||||
|
||||
//light depth map
|
||||
uniform sampler2D shadowMap;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
// function prototypes
|
||||
// vec3 CalcDirLight(vec3 normal, vec3 viewDir);
|
||||
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||
float calcLightIntensityTotal(vec3 normal);
|
||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
||||
vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Material material);
|
||||
|
||||
void main(){
|
||||
@ -80,14 +38,10 @@ void main(){
|
||||
vec3 textureColor = vec3(0.6, 0.92, 0.92);//getColor(texPlane1, texPlane2, texPlane3, norm, material);
|
||||
|
||||
//shadow
|
||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
|
||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
|
||||
|
||||
//calculate final color
|
||||
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4);
|
||||
// vec3 lightAmount = CalcDirLight(norm, viewDir);
|
||||
// for(int i = 0; i < NR_POINT_LIGHTS; i++){
|
||||
// lightAmount += CalcPointLight(i, norm, FragPos, viewDir);
|
||||
// }
|
||||
|
||||
//this final calculation is for transparency
|
||||
FragColor = vec4(finalColor, 0.2);
|
||||
@ -104,105 +58,4 @@ vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Mater
|
||||
|
||||
|
||||
return (albedoX * weights.x + albedoY * weights.y + albedoZ * weights.z);
|
||||
}
|
||||
|
||||
//
|
||||
float calcLightIntensityAmbient(){
|
||||
//calculate average of ambient light
|
||||
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
|
||||
return avg;
|
||||
}
|
||||
|
||||
//
|
||||
float calcLightIntensityDir(vec3 normal){
|
||||
vec3 lightDir = normalize(-dLDirection);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
//
|
||||
float calcLightIntensityTotal(vec3 normal){
|
||||
//ambient intensity
|
||||
float ambientLightIntensity = calcLightIntensityAmbient();
|
||||
|
||||
//get direct intensity
|
||||
float directLightIntensity = calcLightIntensityDir(normal);
|
||||
|
||||
//sum
|
||||
float total = ambientLightIntensity + directLightIntensity;
|
||||
return total;
|
||||
}
|
||||
|
||||
//
|
||||
vec3 getTotalLightColor(vec3 normal){
|
||||
//get the direct light color adjusted for intensity
|
||||
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
|
||||
|
||||
//sum light colors
|
||||
vec3 totalLightColor = diffuseLightColor;
|
||||
return totalLightColor;
|
||||
}
|
||||
|
||||
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||
vec3 lightDir = normalize(pLposition[i] - fragPos);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// attenuation
|
||||
float distance = length(pLposition[i] - fragPos);
|
||||
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
||||
// combine results
|
||||
vec3 ambient = pLambient[i];
|
||||
vec3 diffuse = pLdiffuse[i] * diff;
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
// specular *= attenuation;
|
||||
vec3 specular = vec3(0,0,0);
|
||||
|
||||
vec3 finalValue = (ambient + diffuse + specular);
|
||||
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
||||
|
||||
return finalValue;
|
||||
}
|
||||
|
||||
|
||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
||||
|
||||
// perform perspective divide
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
|
||||
//transform to NDC
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
//get closest depth from light's POV
|
||||
float closestDepth = texture(shadowMap, projCoords.xy).r;
|
||||
|
||||
//get depth of current fragment
|
||||
float currentDepth = projCoords.z;
|
||||
|
||||
//calculate bias
|
||||
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
|
||||
|
||||
//calculate shadow value
|
||||
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
if(projCoords.z > 1.0){
|
||||
shadow = 0.0;
|
||||
}
|
||||
|
||||
//calculate dot product, if it is >0 we know they're parallel-ish therefore should disregard the shadow mapping
|
||||
//ie the fragment is already facing away from the light source
|
||||
float dotprod = dot(normalize(lightDir),normalize(normal));
|
||||
|
||||
if(dotprod > 0.0){
|
||||
shadow = 0.0;
|
||||
}
|
||||
|
||||
// shadow = currentDepth;
|
||||
|
||||
return shadow;
|
||||
}
|
||||
@ -1186,6 +1186,9 @@ Fix AABB calculation from assimp-loaded models
|
||||
Fix singleplayer launching at all
|
||||
Store characters in database
|
||||
Spawn characters from database
|
||||
Fluid spawning item
|
||||
Fix fluid shader
|
||||
Re-enable fluid simulation
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
@ -2,12 +2,14 @@ package electrosphere.client.script;
|
||||
|
||||
import org.graalvm.polyglot.HostAccess.Export;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.terrain.editing.TerrainEditing;
|
||||
import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
* Utilities for interacting with voxels from the client
|
||||
@ -39,4 +41,36 @@ public class ScriptClientVoxelUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the current voxel palette where the player's cursor is looking
|
||||
*/
|
||||
@Export
|
||||
public static void spawnWater(){
|
||||
CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine();
|
||||
Entity camera = Globals.playerCamera;
|
||||
if(
|
||||
collisionEngine != null &&
|
||||
camera != null &&
|
||||
Globals.realmManager != null &&
|
||||
Globals.realmManager.first() != null &&
|
||||
Globals.realmManager.first().getServerWorldData() != null &&
|
||||
Globals.realmManager.first().getServerWorldData().getServerFluidManager() != null
|
||||
){
|
||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||
Vector3d cursorPos = collisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||
Vector3i worldPos = new Vector3i(
|
||||
(int)(cursorPos.x / ServerTerrainChunk.CHUNK_DIMENSION),
|
||||
(int)(cursorPos.y / ServerTerrainChunk.CHUNK_DIMENSION),
|
||||
(int)(cursorPos.z / ServerTerrainChunk.CHUNK_DIMENSION)
|
||||
);
|
||||
Vector3i voxelPos = new Vector3i(
|
||||
(int)(cursorPos.x % ServerTerrainChunk.CHUNK_DIMENSION),
|
||||
(int)(cursorPos.y % ServerTerrainChunk.CHUNK_DIMENSION),
|
||||
(int)(cursorPos.z % ServerTerrainChunk.CHUNK_DIMENSION)
|
||||
);
|
||||
Globals.realmManager.first().getServerWorldData().getServerFluidManager().deformFluidAtLocationToValue(worldPos, voxelPos, 1.0f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -166,6 +166,7 @@ public class LoadingUtils {
|
||||
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
|
||||
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
|
||||
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
|
||||
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
|
||||
//set player character template
|
||||
serverPlayerConnection.setCreatureTemplate(template);
|
||||
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage(CharacterProtocol.SPAWN_EXISTING_TEMPLATE + ""));
|
||||
|
||||
@ -166,6 +166,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
|
||||
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
|
||||
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
|
||||
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
|
||||
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
|
||||
//set player character template
|
||||
connectionHandler.setCreatureTemplate(template);
|
||||
} else {
|
||||
@ -186,6 +187,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
|
||||
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
|
||||
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
|
||||
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
|
||||
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
|
||||
//set player character template
|
||||
connectionHandler.setCreatureTemplate(template);
|
||||
}
|
||||
|
||||
@ -542,7 +542,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
Vector3i cellPos = this.getCellWorldPosition(cell);
|
||||
boolean update = this.serverFluidManager.simulate(cellPos.x,cellPos.y,cellPos.z);
|
||||
if(update){
|
||||
rebroadcastFluidChunk(cellPos);
|
||||
this.rebroadcastFluidChunk(cellPos);
|
||||
}
|
||||
}
|
||||
loadedCellsLock.release();
|
||||
|
||||
@ -14,13 +14,6 @@ public class DefaultFluidGenerator implements FluidGenerator {
|
||||
float[][][] velocityZ = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
|
||||
ServerFluidChunk chunk = new ServerFluidChunk(worldX, worldY, worldZ, weights, velocityX, velocityY, velocityZ);
|
||||
|
||||
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
|
||||
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
|
||||
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
|
||||
weights[x][y][z] = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
|
||||
@ -79,6 +79,17 @@ public class ServerFluidChunk {
|
||||
return weights[x][y][z];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a weight
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param z The z coordinate
|
||||
* @param weight The weight
|
||||
*/
|
||||
public void setWeight(int x, int y, int z, float weight){
|
||||
weights[x][y][z] = weight;
|
||||
}
|
||||
|
||||
//get velocity x
|
||||
public float[][][] getVelocityX() {
|
||||
return velocityX;
|
||||
|
||||
@ -7,6 +7,7 @@ import electrosphere.server.fluid.diskmap.FluidDiskMap;
|
||||
import electrosphere.server.fluid.generation.FluidGenerator;
|
||||
import electrosphere.server.fluid.models.FluidModel;
|
||||
import electrosphere.server.fluid.simulator.ServerFluidSimulator;
|
||||
import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutomataSimulator;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainManager;
|
||||
import electrosphere.util.FileUtils;
|
||||
@ -52,7 +53,7 @@ public class ServerFluidManager {
|
||||
ServerTerrainManager serverTerrainManager;
|
||||
|
||||
//controls whether fluid simulation should actually happen or not
|
||||
boolean simulate = true;
|
||||
boolean simulate = false;
|
||||
|
||||
/**
|
||||
* The parent world data
|
||||
@ -75,6 +76,7 @@ public class ServerFluidManager {
|
||||
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
|
||||
this.seed = seed;
|
||||
this.chunkGenerator = chunkGenerator;
|
||||
this.serverFluidSimulator = new FluidCellularAutomataSimulator();
|
||||
}
|
||||
|
||||
ServerFluidManager(){
|
||||
@ -85,14 +87,6 @@ public class ServerFluidManager {
|
||||
* Generates a fluid model for the manager
|
||||
*/
|
||||
public void generate(){
|
||||
// FluidGenerator terrainGen = new FluidGenerator();
|
||||
// terrainGen.setInterpolationRatio(worldSizeDiscrete/200);
|
||||
// terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio);
|
||||
// terrainGen.setRandomSeed(seed);
|
||||
// model = terrainGen.generateModel();
|
||||
// this.chunkGenerator.setModel(model);
|
||||
// model.setInterpolationRandomDampener(interpolationRandomDampener);
|
||||
// this.chunkDiskMap = new ChunkDiskMap();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,6 +259,8 @@ public class ServerFluidManager {
|
||||
// ServerFluidChunk chunk = chunkCache.get(key);
|
||||
// chunk.addModification(modification);
|
||||
// }
|
||||
ServerFluidChunk fluidChunk = this.getChunk(worldPos.x, worldPos.y, worldPos.z);
|
||||
fluidChunk.setWeight(voxelPos.x, voxelPos.y, voxelPos.z, weight);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,13 +269,13 @@ public class ServerFluidManager {
|
||||
public boolean simulate(int worldX, int worldY, int worldZ){
|
||||
boolean rVal = false;
|
||||
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
|
||||
// if(simulate){
|
||||
// ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
|
||||
// ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
|
||||
// if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
|
||||
// rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
|
||||
// }
|
||||
// }
|
||||
if(simulate){
|
||||
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
|
||||
ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
|
||||
if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
|
||||
rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user