Compare commits
2 Commits
2b715ab325
...
8dcff7efe0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dcff7efe0 | ||
|
|
7a2bdf7745 |
@ -1,3 +1,3 @@
|
|||||||
#maven.buildNumber.plugin properties file
|
#maven.buildNumber.plugin properties file
|
||||||
#Fri Jun 14 13:45:11 EDT 2024
|
#Wed Jun 19 19:19:09 EDT 2024
|
||||||
buildNumber=137
|
buildNumber=138
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
- @subpage archimprovementtargets
|
- @subpage archimprovementtargets
|
||||||
- @subpage savesindex
|
- @subpage savesindex
|
||||||
- @subpage hitboxesindex
|
- @subpage hitboxesindex
|
||||||
|
- @subpage drawcell
|
||||||
|
|
||||||
|
|
||||||
# What is this section
|
# What is this section
|
||||||
|
|||||||
6
docs/src/architecture/drawcell/drawcell.md
Normal file
6
docs/src/architecture/drawcell/drawcell.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@page drawcell Draw Cells
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
- @subpage transvoxelalgorithm
|
||||||
|
|
||||||
|

|
||||||
49
docs/src/architecture/drawcell/transvoxelalgorithm.md
Normal file
49
docs/src/architecture/drawcell/transvoxelalgorithm.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
@page transvoxelalgorithm Transvoxel Chunk Generation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# High Level
|
||||||
|
|
||||||
|
|
||||||
|
The goal of the transvoxel algorithm is to bridge the divide between a chunk of a higher resolution and a chunk of a lower resolution
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
For the voxels on the border between a low resolution chunk and a high resolution chunk, we split the voxels in half
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
On the low-resolution half, we perform marching cubes
|
||||||
|
|
||||||
|
On the high resolution half, we generate a mesh that adapts the high resolution chunk to the low resolution voxel
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Major files
|
||||||
|
[TransvoxelModelGeneration.java](@ref #electrosphere.renderer.meshgen.TransvoxelModelGeneration) - The main class that turns voxel data into mesh data
|
||||||
|
|
||||||
|
[TerrainChunk.java](@ref #electrosphere.entity.types.terrain.TerrainChunk) - The class that the DrawCellManager calls to generate chunk meshes
|
||||||
|
|
||||||
|
[ClientTerrainManager.java](@ref #electrosphere.client.terrain.manager.ClientTerrainManager) - Handles queueing the mesh data to the gpu
|
||||||
|
|
||||||
|
[TerrainChunkGenQueueItem.java](@ref #electrosphere.client.terrain.manager.TerrainChunkGenQueueItem) - A terrain mesh that has been queued to be added to the gpu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Implementation Notes
|
||||||
|
|
||||||
|
The description of the algorithm always refers to the transition cells in terms of y pointing upwards and x pointing to the right.
|
||||||
|
This can be confusing to think about how it would apply to other orientations (ie what if we're working along the y axis or something and x is "up").
|
||||||
|
All these transforms are done implicitly in the `generateTerrainChunkData` function. When iterating across each axis, I've manually calculated what point should be where.
|
||||||
|
The inner polygonize functions always treat it as y-up, but that works because this transform has already been done before the data is passed in.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Notes about table format
|
||||||
|
- `transitionCellClass` is indexed into by the case index value generated from the high resolution face data
|
||||||
|
- `transitionCellData` is indexed into by the class value from the `transitionCellClass`
|
||||||
|
- `transitionVertexData` is ALSO indexed into by the CASE INDEX VALUE, NOT THE CLASS VALUE. You can figure this out because the `transitionVertexData` has 512 entries
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
@page narrativearcdesign Narrative Arc Design
|
||||||
|
|
||||||
|
Use the idea of conspiracy to create mystery eventually leading to a big series of confrontations and narrative payoff
|
||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
- @subpage whatmakesaquestgood
|
- @subpage whatmakesaquestgood
|
||||||
|
- @subpage narrativearcdesign
|
||||||
|
|
||||||
|
|
||||||
TODO: describe
|
TODO: describe
|
||||||
|
|||||||
BIN
docs/src/images/architecture/drawcell/ClientMacroArch.png
Normal file
BIN
docs/src/images/architecture/drawcell/ClientMacroArch.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/src/images/architecture/drawcell/adaptedvoxel.png
Normal file
BIN
docs/src/images/architecture/drawcell/adaptedvoxel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
BIN
docs/src/images/architecture/drawcell/bisectedvoxel.png
Normal file
BIN
docs/src/images/architecture/drawcell/bisectedvoxel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
BIN
docs/src/images/architecture/drawcell/completevoxel.png
Normal file
BIN
docs/src/images/architecture/drawcell/completevoxel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
@ -1,6 +1,11 @@
|
|||||||
@page bigthings Big Things I want to build
|
@page bigthings Big Things I want to build
|
||||||
# and may or may not have the sanity to build
|
# and may or may not have the sanity to build
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
|
||||||
|
|
||||||
|
TODO(?):
|
||||||
|
|
||||||
- CFD
|
- CFD
|
||||||
- Internal Boundaries
|
- Internal Boundaries
|
||||||
- Multigrid optimization
|
- Multigrid optimization
|
||||||
@ -8,6 +13,8 @@
|
|||||||
|
|
||||||
- Transvoxel Algorithm
|
- Transvoxel Algorithm
|
||||||
|
|
||||||
|
- Building cube voxels w/ LOD
|
||||||
|
|
||||||
- Deferred Shading Pipeline
|
- Deferred Shading Pipeline
|
||||||
|
|
||||||
- Audio Ray Tracing
|
- Audio Ray Tracing
|
||||||
@ -17,3 +24,7 @@
|
|||||||
- Massive scale creature groups
|
- Massive scale creature groups
|
||||||
(ie 10k armies)
|
(ie 10k armies)
|
||||||
|
|
||||||
|
- Use HTML to define ui windows
|
||||||
|
- Some css support
|
||||||
|
- Language file for translation
|
||||||
|
|
||||||
|
|||||||
@ -371,9 +371,25 @@ Highlevel netcode gen updates
|
|||||||
- Furthermore, keep tracking of the existing ids for trees and fields and only generate ids for new trees and fields
|
- Furthermore, keep tracking of the existing ids for trees and fields and only generate ids for new trees and fields
|
||||||
Fix client gravity tree name
|
Fix client gravity tree name
|
||||||
|
|
||||||
|
(06/19/2024)
|
||||||
|
Transvoxel implementation
|
||||||
|
- Begin work on transvoxel algo
|
||||||
|
|
||||||
|
(06/21/2024)
|
||||||
|
Transvoxel implementation
|
||||||
|
- First working implementation of mesh generation for transvoxel chunks (architecture of adding it to drawcellmanager still todo)
|
||||||
|
|
||||||
|
(06/22/2024)
|
||||||
|
Transvoxel implementation
|
||||||
|
- Scaling LODed chunks by lod level
|
||||||
|
|
||||||
|
Fix items falling below the ground
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Demo requirements:
|
Demo requirements:
|
||||||
= Assets =
|
= Assets =
|
||||||
Block animation in first person
|
Block animation in first person
|
||||||
@ -385,7 +401,6 @@ Audio FX for everything
|
|||||||
|
|
||||||
= Coding =
|
= Coding =
|
||||||
Sour spot, sweet spot for damage hitboxes and hurtboxes
|
Sour spot, sweet spot for damage hitboxes and hurtboxes
|
||||||
Fix items falling below the ground
|
|
||||||
Sub menu on title screen that allows changing control mappings
|
Sub menu on title screen that allows changing control mappings
|
||||||
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
- Introduce block hitbox (blockbox) type
|
- Introduce block hitbox (blockbox) type
|
||||||
@ -400,6 +415,26 @@ Ability for private realms to have time start/stop based on the player's feedbac
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Goof off today requirements:
|
||||||
|
Transvoxel implementation
|
||||||
|
- Fix draw cell manager requesting far-out chunks
|
||||||
|
- Properly update to higher LOD meshes as you get closer
|
||||||
|
Client Terrain Entity Management (specifically creation/teardown for client)
|
||||||
|
- Also queries for far out chunks to load far away terrain
|
||||||
|
Server Terrain Management (specifically for collision)
|
||||||
|
- Handles communicating far out LOD chunks to client as well
|
||||||
|
Terrain Interface Positional Access Interface
|
||||||
|
- Ability to get terrain at point for interactions with game world eg placing grass/water collision
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIG BIG BIG BIG IMMEDIATE TO DO:
|
BIG BIG BIG BIG IMMEDIATE TO DO:
|
||||||
always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible
|
always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible
|
||||||
|
|
||||||
@ -456,22 +491,6 @@ Shader library system
|
|||||||
- Abiltiy to include the shader library in individual files (ie implement #include)
|
- Abiltiy to include the shader library in individual files (ie implement #include)
|
||||||
|
|
||||||
Break control handlers into separate files with new logic to transition between control handler states
|
Break control handlers into separate files with new logic to transition between control handler states
|
||||||
|
|
||||||
|
|
||||||
Transvoxel Algorithm
|
|
||||||
Client Terrain Entity Management (specifically creation/teardown for client)
|
|
||||||
- Also queries for far out chunks to load far away terrain
|
|
||||||
Server Terrain Management (specifically for collision)
|
|
||||||
- Handles communicating far out LOD chunks to client as well
|
|
||||||
Terrain Interface Positional Access Interface
|
|
||||||
- Ability to get terrain at point for interactions with game world eg placing grass/water collision
|
|
||||||
Actually implement transvoxel algo
|
|
||||||
Marching Cubes Texture Overhaul
|
|
||||||
- Detect opengl max image size
|
|
||||||
- Construct texture atlas of max size
|
|
||||||
- (target 256x256 resolution initially, should give ~1000 types for 8192x8192)
|
|
||||||
- Prebake all textures into atlas
|
|
||||||
- Rewrite marching cubes shader to leverage this atlas
|
|
||||||
|
|
||||||
Another pass at grass
|
Another pass at grass
|
||||||
- Multiple foliage models in same cell
|
- Multiple foliage models in same cell
|
||||||
@ -580,9 +599,6 @@ Generic collision engine to support different instances of engine (eg hitboxes v
|
|||||||
- Major refactoring to happen here
|
- Major refactoring to happen here
|
||||||
Procedural Cliff Texture
|
Procedural Cliff Texture
|
||||||
- Uses noise or fractals or something to generate infinite textures in shader
|
- Uses noise or fractals or something to generate infinite textures in shader
|
||||||
Terrain Chunks:
|
|
||||||
- Scale textures to be 1 texture per unit of terrain
|
|
||||||
- Texture atlasing (512x512)
|
|
||||||
Loot Generator
|
Loot Generator
|
||||||
- System that can generate items that would be appropriate reward given some variables
|
- System that can generate items that would be appropriate reward given some variables
|
||||||
- ie you tell it 'this is this character's stats, this is the relative level of loot I want to provide'
|
- ie you tell it 'this is this character's stats, this is the relative level of loot I want to provide'
|
||||||
|
|||||||
17
docs/src/testing/testing.md
Normal file
17
docs/src/testing/testing.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
@page testing Testing
|
||||||
|
|
||||||
|
Eventual goal is to have unit tests for parts of the engine that it makes sense for. Some ideas:
|
||||||
|
- Loading assets
|
||||||
|
- UI functionality
|
||||||
|
- Basic behavior trees
|
||||||
|
- Script Engine
|
||||||
|
- AI
|
||||||
|
- Networking
|
||||||
|
|
||||||
|
|
||||||
|
Current CI is Jenkins, which has a plugin
|
||||||
|
https://plugins.jenkins.io/xvfb/
|
||||||
|
that allows for graphical sessions while building
|
||||||
|
|
||||||
|
I need to figure out hooking this up to my container in order to do most of the above testing
|
||||||
|
|
||||||
@ -90,6 +90,11 @@
|
|||||||
"type" : "BYTE_ARRAY"
|
"type" : "BYTE_ARRAY"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name" : "chunkResolution",
|
||||||
|
"type" : "FIXED_INT"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name" : "terrainWeight",
|
"name" : "terrainWeight",
|
||||||
"type" : "FIXED_FLOAT"
|
"type" : "FIXED_FLOAT"
|
||||||
@ -186,6 +191,27 @@
|
|||||||
"chunkData"
|
"chunkData"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"messageName" : "RequestReducedChunkData",
|
||||||
|
"description" : "Requests reduced resolution chunk data from the server",
|
||||||
|
"data" : [
|
||||||
|
"worldX",
|
||||||
|
"worldY",
|
||||||
|
"worldZ",
|
||||||
|
"chunkResolution"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"messageName" : "SendReducedChunkData",
|
||||||
|
"description" : "Sends chunk data to the client",
|
||||||
|
"data" : [
|
||||||
|
"worldX",
|
||||||
|
"worldY",
|
||||||
|
"worldZ",
|
||||||
|
"chunkResolution",
|
||||||
|
"chunkData"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "RequestFluidData",
|
"messageName" : "RequestFluidData",
|
||||||
"description" : "Requests a fluid data from the server",
|
"description" : "Requests a fluid data from the server",
|
||||||
|
|||||||
@ -11,39 +11,47 @@ import electrosphere.entity.ClientEntityUtils;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.types.terrain.TerrainChunk;
|
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||||
import electrosphere.renderer.texture.Texture;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
import electrosphere.server.datacell.Realm;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A single drawcell - contains an entity that has a physics mesh and potentially graphics
|
||||||
* @author satellite
|
|
||||||
*/
|
*/
|
||||||
public class DrawCell {
|
public class DrawCell {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for the different faces of a draw cell -- used when filling in data for higher LOD faces
|
||||||
|
*/
|
||||||
|
public enum DrawCellFace {
|
||||||
|
X_POSITIVE,
|
||||||
|
X_NEGATIVE,
|
||||||
|
Y_POSITIVE,
|
||||||
|
Y_NEGATIVE,
|
||||||
|
Z_POSITIVE,
|
||||||
|
Z_NEGATIVE,
|
||||||
|
}
|
||||||
|
|
||||||
//the position of the draw cell in world coordinates
|
//the position of the draw cell in world coordinates
|
||||||
Vector3i worldPos;
|
Vector3i worldPos;
|
||||||
|
|
||||||
|
//the main entity for the cell
|
||||||
Entity modelEntity;
|
Entity modelEntity;
|
||||||
|
|
||||||
|
//the physics mesh
|
||||||
DBody physicsObject;
|
DBody physicsObject;
|
||||||
|
|
||||||
//Allocated once instead of continuously, used to generate the visual/physics models
|
//Allocated once instead of continuously, used to generate the visual/physics models
|
||||||
float[][][] weights = new float[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
|
float[][][] weights = new float[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
|
||||||
int[][][] types = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
|
int[][][] types = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
//the maximum detail LOD level
|
||||||
|
public static final int FULL_DETAIL_LOD = 0;
|
||||||
|
|
||||||
|
|
||||||
static Texture groundTextureOne = new Texture("/Textures/Ground/Dirt1.png");
|
/**
|
||||||
static Texture groundTextureTwo = new Texture("/Textures/Ground/Dirt1.png");
|
* Private constructor
|
||||||
static Texture groundTextureThree = new Texture("/Textures/Ground/Dirt1.png");
|
*/
|
||||||
static Texture groundTextureFour = new Texture("/Textures/Ground/Dirt1.png");
|
|
||||||
|
|
||||||
static {
|
|
||||||
// groundTextureOne = new Texture("/Textures/Ground/GrassTileable.png");
|
|
||||||
// groundTextureTwo = new Texture("/Textures/Ground/Dirt1.png");
|
|
||||||
// groundTextureThree = new Texture("/Textures/Ground/Dirt1.png");
|
|
||||||
// groundTextureFour = new Texture("/Textures/Ground/Dirt1.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DrawCell(){
|
DrawCell(){
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -63,18 +71,23 @@ public class DrawCell {
|
|||||||
/**
|
/**
|
||||||
* Generates a drawable entity based on this chunk
|
* Generates a drawable entity based on this chunk
|
||||||
*/
|
*/
|
||||||
public void generateDrawableEntity(VoxelTextureAtlas atlas){
|
public void generateDrawableEntity(VoxelTextureAtlas atlas, int lod, DrawCellFace higherLODFace){
|
||||||
if(modelEntity != null){
|
if(modelEntity != null){
|
||||||
Globals.clientScene.deregisterEntity(modelEntity);
|
Globals.clientScene.deregisterEntity(modelEntity);
|
||||||
}
|
}
|
||||||
|
this.fillInData();
|
||||||
|
TransvoxelChunkData chunkData = new TransvoxelChunkData(weights, types, lod);
|
||||||
|
if(lod > FULL_DETAIL_LOD){
|
||||||
|
|
||||||
fillInData();
|
}
|
||||||
|
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(chunkData, lod, atlas);
|
||||||
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(weights, types, 0, atlas);
|
|
||||||
|
|
||||||
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos());
|
ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the real-space position of the draw cell
|
||||||
|
* @return the real-space position
|
||||||
|
*/
|
||||||
protected Vector3d getRealPos(){
|
protected Vector3d getRealPos(){
|
||||||
return new Vector3d(
|
return new Vector3d(
|
||||||
worldPos.x * ChunkData.CHUNK_SIZE,
|
worldPos.x * ChunkData.CHUNK_SIZE,
|
||||||
@ -224,5 +237,49 @@ public class DrawCell {
|
|||||||
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
types[ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE][ChunkData.CHUNK_SIZE] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills in the internal arrays of data for generate terrain models
|
||||||
|
*/
|
||||||
|
private void fillInData(TransvoxelChunkData chunkData, int lod, DrawCellFace face){
|
||||||
|
float[][] faceData = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
|
||||||
|
int[][] atlasData = new int[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
|
||||||
|
switch(face){
|
||||||
|
case X_POSITIVE: {
|
||||||
|
} break;
|
||||||
|
case X_NEGATIVE: {
|
||||||
|
} break;
|
||||||
|
case Y_POSITIVE: {
|
||||||
|
} break;
|
||||||
|
case Y_NEGATIVE: {
|
||||||
|
} break;
|
||||||
|
case Z_POSITIVE: {
|
||||||
|
} break;
|
||||||
|
case Z_NEGATIVE: {
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//fill in data
|
||||||
|
//
|
||||||
|
//main chunk
|
||||||
|
//face X
|
||||||
|
// if(worldPos.x + 1 < Globals.clientWorldData.getWorldDiscreteSize()){
|
||||||
|
// currentChunk = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos.x + 1, worldPos.y, worldPos.z);
|
||||||
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
||||||
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
||||||
|
// weights[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getWeight(0, i, j);
|
||||||
|
// types[ChunkData.CHUNK_SIZE][i][j] = currentChunk.getType(0, i, j);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// for(int i = 0; i < ChunkData.CHUNK_SIZE; i++){
|
||||||
|
// for(int j = 0; j < ChunkData.CHUNK_SIZE; j++){
|
||||||
|
// weights[ChunkData.CHUNK_SIZE][i][j] = -1;
|
||||||
|
// types[ChunkData.CHUNK_SIZE][i][j] = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,15 +9,40 @@ import org.joml.Vector3d;
|
|||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
import electrosphere.client.terrain.cache.ChunkData;
|
import electrosphere.client.terrain.cache.ChunkData;
|
||||||
|
import electrosphere.client.terrain.cells.DrawCell.DrawCellFace;
|
||||||
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;
|
||||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
import electrosphere.renderer.shader.ShaderProgram;
|
||||||
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Manages the graphical entities for the terrain chunks
|
||||||
* @author satellite
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
Notes for integrating with transvoxel algo:
|
||||||
|
Different problems to tackle
|
||||||
|
|
||||||
|
For all chunks within minimum radius, check if they can be updated and update accordingly <--- we do this currently
|
||||||
|
|
||||||
|
|
||||||
|
For all chunks between minimum radius and first LOD radius, check if we can make a LOD chunk
|
||||||
|
If we can, make a lod chunk or see if it can be updated
|
||||||
|
This check will be:
|
||||||
|
For every position, check if all four positions required for LOD chunk are within lod radius
|
||||||
|
if yes, make lod chunk
|
||||||
|
|
||||||
|
If we cannot, create a fullres chunk
|
||||||
|
This check will be:
|
||||||
|
For every position, check if all four positions required for LOD chunk are within lod radius
|
||||||
|
if yes, make lod chunk
|
||||||
|
if they are outside the far bound, create lod chunk
|
||||||
|
if they are within the near bound, create a fullres chunk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public class DrawCellManager {
|
public class DrawCellManager {
|
||||||
|
|
||||||
@ -27,45 +52,46 @@ public class DrawCellManager {
|
|||||||
int cellY;
|
int cellY;
|
||||||
int cellZ;
|
int cellZ;
|
||||||
|
|
||||||
|
|
||||||
//the dimensions of the world that this cell manager can handles
|
|
||||||
int cellWidth;
|
|
||||||
|
|
||||||
//the width of a minicell in this manager
|
|
||||||
int miniCellWidth;
|
|
||||||
|
|
||||||
//all currently displaying mini cells
|
//all currently displaying mini cells
|
||||||
Set<DrawCell> cells;
|
Set<DrawCell> cells = new HashSet<DrawCell>();
|
||||||
Map<String,DrawCell> keyCellMap = new HashMap<String,DrawCell>();
|
Map<String,DrawCell> keyCellMap = new HashMap<String,DrawCell>();
|
||||||
Set<String> hasNotRequested;
|
|
||||||
Set<String> hasRequested;
|
//status of all position keys
|
||||||
Set<String> drawable;
|
Set<String> hasNotRequested = new HashSet<String>();
|
||||||
Set<String> undrawable;
|
Set<String> requested = new HashSet<String>();
|
||||||
Set<String> updateable;
|
Set<String> drawable = new HashSet<String>();
|
||||||
|
Set<String> undrawable = new HashSet<String>();
|
||||||
|
Set<String> updateable = new HashSet<String>();
|
||||||
|
|
||||||
|
//LOD level of all position keys
|
||||||
|
Map<String,Integer> positionLODLevel = new HashMap<String,Integer>();
|
||||||
|
|
||||||
//voxel atlas
|
//voxel atlas
|
||||||
VoxelTextureAtlas atlas;
|
VoxelTextureAtlas atlas;
|
||||||
|
|
||||||
|
//shader program for drawable cells
|
||||||
ShaderProgram program;
|
ShaderProgram program;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// int drawRadius = 5;
|
//the real-space radius for which we will construct draw cells inside of
|
||||||
int drawStepdownInterval = 3;
|
//ie, we check if the draw cell's entity would be inside this radius. If it would, create the draw cell, otherwise don't
|
||||||
int drawStepdownValue = 25;
|
double drawFullModelRadius = 50;
|
||||||
|
|
||||||
double drawRadius = 50;
|
//the radius we'll draw LODed chunks for
|
||||||
|
double drawLODRadius = drawFullModelRadius + ServerTerrainChunk.CHUNK_DIMENSION * (2*2 + 4*4 + 8*8 + 16*16);
|
||||||
|
|
||||||
|
|
||||||
|
//the number of possible LOD levels
|
||||||
|
//1,2,4,8,16
|
||||||
|
static final int NUMBER_OF_LOD_LEVELS = 5;
|
||||||
|
|
||||||
|
//the table of lod leve -> radius at which we will look for chunks within this log
|
||||||
|
double[] lodLevelRadiusTable = new double[5];
|
||||||
|
|
||||||
|
//the radius for which physics meshes are created when draw cells are created
|
||||||
int physicsRadius = 3;
|
int physicsRadius = 3;
|
||||||
|
|
||||||
int worldBoundDiscreteMin = 0;
|
|
||||||
int worldBoundDiscreteMax = 0;
|
|
||||||
|
|
||||||
//client terrain manager
|
|
||||||
// ClientTerrainManager clientTerrainManager;
|
|
||||||
|
|
||||||
|
|
||||||
//ready to start updating?
|
//ready to start updating?
|
||||||
boolean update = false;
|
boolean update = false;
|
||||||
|
|
||||||
@ -82,22 +108,22 @@ public class DrawCellManager {
|
|||||||
* @param discreteY The initial discrete position Y coordinate
|
* @param discreteY The initial discrete position Y coordinate
|
||||||
*/
|
*/
|
||||||
public DrawCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){
|
public DrawCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){
|
||||||
worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f);
|
|
||||||
cells = new HashSet<DrawCell>();
|
|
||||||
hasNotRequested = new HashSet<String>();
|
|
||||||
drawable = new HashSet<String>();
|
|
||||||
undrawable = new HashSet<String>();
|
|
||||||
updateable = new HashSet<String>();
|
|
||||||
hasRequested = new HashSet<String>();
|
|
||||||
|
|
||||||
cellX = discreteX;
|
cellX = discreteX;
|
||||||
cellY = discreteY;
|
cellY = discreteY;
|
||||||
cellZ = discreteZ;
|
cellZ = discreteZ;
|
||||||
|
|
||||||
program = Globals.terrainShaderProgram;
|
program = Globals.terrainShaderProgram;
|
||||||
|
|
||||||
|
//the first lod level is set by user
|
||||||
|
lodLevelRadiusTable[0] = drawFullModelRadius;
|
||||||
|
//generate LOD radius table
|
||||||
|
for(int i = 1; i < NUMBER_OF_LOD_LEVELS; i++){
|
||||||
|
double sizeOfSingleModel = Math.pow(2,i) * ServerTerrainChunk.CHUNK_DIMENSION;
|
||||||
|
//size of the radius for this lod level should be three times the size of a model + the previous radius
|
||||||
|
//this guarantees we get at least one adapter chunk, one proper chunk, and also that the radius accounts for the previous lod level chunks
|
||||||
|
lodLevelRadiusTable[i] = lodLevelRadiusTable[i-1] + sizeOfSingleModel * 3;
|
||||||
|
}
|
||||||
|
|
||||||
// drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius();
|
|
||||||
drawStepdownInterval = Globals.userSettings.getGameplayPhysicsCellRadius();
|
|
||||||
physicsRadius = Globals.userSettings.getGameplayPhysicsCellRadius();
|
physicsRadius = Globals.userSettings.getGameplayPhysicsCellRadius();
|
||||||
|
|
||||||
invalidateAllCells();
|
invalidateAllCells();
|
||||||
@ -105,29 +131,41 @@ public class DrawCellManager {
|
|||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor
|
||||||
|
*/
|
||||||
DrawCellManager(){
|
DrawCellManager(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCell(Vector3i cellPos){
|
/**
|
||||||
|
* Sets the player's current position in cell-space
|
||||||
|
* @param cellPos The cell's position
|
||||||
|
*/
|
||||||
|
public void setPlayerCell(Vector3i cellPos){
|
||||||
cellX = cellPos.x;
|
cellX = cellPos.x;
|
||||||
cellY = cellPos.y;
|
cellY = cellPos.y;
|
||||||
cellZ = cellPos.z;
|
cellZ = cellPos.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update function that is called if a cell has not been requested
|
||||||
|
*/
|
||||||
void updateUnrequestedCell(){
|
void updateUnrequestedCell(){
|
||||||
if(hasNotRequested.size() > 0){
|
if(hasNotRequested.size() > 0){
|
||||||
String targetKey = hasNotRequested.iterator().next();
|
String targetKey = hasNotRequested.iterator().next();
|
||||||
hasNotRequested.remove(targetKey);
|
hasNotRequested.remove(targetKey);
|
||||||
Vector3i worldPos = getVectorFromKey(targetKey);
|
Vector3i worldPos = getVectorFromKey(targetKey);
|
||||||
// Vector3i vector = getVectorFromKey(targetKey);
|
|
||||||
// int currentCellX = cellX - drawRadius + vector.x;
|
//
|
||||||
// int currentCellY = cellY - drawRadius + vector.y;
|
//Because of the way marching cubes works, we need to request the adjacent chunks so we know how to properly blend between one chunk and the next
|
||||||
// int currentCellZ = cellZ - drawRadius + vector.z;
|
//The following loop-hell does this
|
||||||
|
//
|
||||||
for(int i = 0; i < 2; i++){
|
for(int i = 0; i < 2; i++){
|
||||||
for(int j = 0; j < 2; j++){
|
for(int j = 0; j < 2; j++){
|
||||||
for(int k = 0; k < 2; k++){
|
for(int k = 0; k < 2; k++){
|
||||||
Vector3i posToCheck = new Vector3i(worldPos).add(i,j,k);
|
Vector3i posToCheck = new Vector3i(worldPos).add(i,j,k);
|
||||||
|
String requestKey = getCellKey(posToCheck.x,posToCheck.y,posToCheck.z);
|
||||||
if(
|
if(
|
||||||
posToCheck.x >= 0 &&
|
posToCheck.x >= 0 &&
|
||||||
posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||||
@ -137,20 +175,20 @@ public class DrawCellManager {
|
|||||||
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() &&
|
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||||
!Globals.clientTerrainManager.containsChunkDataAtWorldPoint(posToCheck.x, posToCheck.y, posToCheck.z)
|
!Globals.clientTerrainManager.containsChunkDataAtWorldPoint(posToCheck.x, posToCheck.y, posToCheck.z)
|
||||||
){
|
){
|
||||||
// if(!hasRequested.contains(targetKey)){
|
if(!requested.contains(requestKey)){
|
||||||
//client should request chunk data from server for each chunk necessary to create the model
|
//client should request chunk data from server for each chunk necessary to create the model
|
||||||
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkDataMessage(
|
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkDataMessage(
|
||||||
posToCheck.x,
|
posToCheck.x,
|
||||||
posToCheck.y,
|
posToCheck.y,
|
||||||
posToCheck.z
|
posToCheck.z
|
||||||
));
|
));
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
undrawable.add(targetKey);
|
|
||||||
hasRequested.add(targetKey);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
undrawable.add(targetKey);
|
||||||
|
requested.add(targetKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,10 +196,12 @@ public class DrawCellManager {
|
|||||||
* Makes one of the undrawable cells drawable
|
* Makes one of the undrawable cells drawable
|
||||||
*/
|
*/
|
||||||
void makeCellDrawable(){
|
void makeCellDrawable(){
|
||||||
|
|
||||||
if(undrawable.size() > 0){
|
if(undrawable.size() > 0){
|
||||||
String targetKey = undrawable.iterator().next();
|
String targetKey = undrawable.iterator().next();
|
||||||
Vector3i worldPos = getVectorFromKey(targetKey);
|
Vector3i worldPos = getVectorFromKey(targetKey);
|
||||||
|
|
||||||
|
//
|
||||||
|
//Checks if all chunk data necessary to generate a mesh is present
|
||||||
boolean containsNecessaryChunks = true;
|
boolean containsNecessaryChunks = true;
|
||||||
for(int i = 0; i < 2; i++){
|
for(int i = 0; i < 2; i++){
|
||||||
for(int j = 0; j < 2; j++){
|
for(int j = 0; j < 2; j++){
|
||||||
@ -175,25 +215,28 @@ public class DrawCellManager {
|
|||||||
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() &&
|
posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||||
!containsChunkDataAtWorldPoint(posToCheck.x,posToCheck.y,posToCheck.z)
|
!containsChunkDataAtWorldPoint(posToCheck.x,posToCheck.y,posToCheck.z)
|
||||||
){
|
){
|
||||||
containsChunkDataAtWorldPoint(posToCheck.x,posToCheck.y,posToCheck.z);
|
|
||||||
containsNecessaryChunks = false;
|
containsNecessaryChunks = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if contains all chunks necessary to generate visuals
|
//
|
||||||
|
//if contains data for all chunks necessary to generate visuals
|
||||||
if(containsNecessaryChunks){
|
if(containsNecessaryChunks){
|
||||||
//build float array
|
|
||||||
|
//update the status of the terrain key
|
||||||
|
undrawable.remove(targetKey);
|
||||||
|
drawable.add(targetKey);
|
||||||
|
|
||||||
|
//build the cell
|
||||||
DrawCell cell = DrawCell.generateTerrainCell(
|
DrawCell cell = DrawCell.generateTerrainCell(
|
||||||
worldPos
|
worldPos
|
||||||
);
|
);
|
||||||
cells.add(cell);
|
cells.add(cell);
|
||||||
keyCellMap.put(targetKey,cell);
|
keyCellMap.put(targetKey,cell);
|
||||||
// undrawable.add(targetKey);
|
DrawCellFace higherLODFace = null;
|
||||||
undrawable.remove(targetKey);
|
keyCellMap.get(targetKey).generateDrawableEntity(atlas,0,higherLODFace);
|
||||||
drawable.add(targetKey);
|
|
||||||
//make drawable entity
|
|
||||||
keyCellMap.get(targetKey).generateDrawableEntity(atlas);
|
|
||||||
//evaluate for foliage
|
//evaluate for foliage
|
||||||
Globals.clientFoliageManager.evaluateChunk(worldPos);
|
Globals.clientFoliageManager.evaluateChunk(worldPos);
|
||||||
}
|
}
|
||||||
@ -216,37 +259,49 @@ public class DrawCellManager {
|
|||||||
worldPos.z >= 0 &&
|
worldPos.z >= 0 &&
|
||||||
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize()
|
worldPos.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||||
){
|
){
|
||||||
// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){
|
|
||||||
// needsPhysics[targetX][targetY] = true;
|
|
||||||
// }
|
|
||||||
// int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
|
|
||||||
// int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
|
|
||||||
// while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){
|
|
||||||
// stride = stride + 1;
|
|
||||||
// }
|
|
||||||
keyCellMap.get(targetKey).destroy();
|
keyCellMap.get(targetKey).destroy();
|
||||||
keyCellMap.get(targetKey).generateDrawableEntity(atlas);
|
DrawCellFace higherLODFace = null;
|
||||||
|
keyCellMap.get(targetKey).generateDrawableEntity(atlas,0,higherLODFace);
|
||||||
}
|
}
|
||||||
drawable.add(targetKey);
|
drawable.add(targetKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the manager contains a cell position that hasn't had its chunk data requested from the server yet
|
||||||
|
* @return true if there is an unrequested cell, false otherwise
|
||||||
|
*/
|
||||||
public boolean containsUnrequestedCell(){
|
public boolean containsUnrequestedCell(){
|
||||||
return hasNotRequested.size() > 0;
|
return hasNotRequested.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the manager contains a cell who hasn't been made drawable yet
|
||||||
|
* @return true if there is an undrawable cell, false otherwise
|
||||||
|
*/
|
||||||
public boolean containsUndrawableCell(){
|
public boolean containsUndrawableCell(){
|
||||||
return undrawable.size() > 0;
|
return undrawable.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the manager contains a cell who needs to be updated
|
||||||
|
* @return true if there is an updateable cell, false otherwise
|
||||||
|
*/
|
||||||
public boolean containsUpdateableCell(){
|
public boolean containsUpdateableCell(){
|
||||||
return updateable.size() > 0;
|
return updateable.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a real coordinate into a cell-space coordinate
|
||||||
|
* @param input the real coordinate
|
||||||
|
* @return the cell coordinate
|
||||||
|
*/
|
||||||
public int transformRealSpaceToCellSpace(double input){
|
public int transformRealSpaceToCellSpace(double input){
|
||||||
return (int)(input / Globals.clientWorldData.getDynamicInterpolationRatio());
|
return (int)(input / Globals.clientWorldData.getDynamicInterpolationRatio());
|
||||||
}
|
}
|
||||||
@ -278,7 +333,7 @@ public class DrawCellManager {
|
|||||||
Set<DrawCell> cellsToRemove = new HashSet<DrawCell>();
|
Set<DrawCell> cellsToRemove = new HashSet<DrawCell>();
|
||||||
for(DrawCell cell : cells){
|
for(DrawCell cell : cells){
|
||||||
Vector3d realPos = cell.getRealPos();
|
Vector3d realPos = cell.getRealPos();
|
||||||
if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawRadius){
|
if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawFullModelRadius){
|
||||||
cellsToRemove.add(cell);
|
cellsToRemove.add(cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,7 +345,7 @@ public class DrawCellManager {
|
|||||||
undrawable.remove(key);
|
undrawable.remove(key);
|
||||||
updateable.remove(key);
|
updateable.remove(key);
|
||||||
keyCellMap.remove(key);
|
keyCellMap.remove(key);
|
||||||
hasRequested.remove(key);
|
requested.remove(key);
|
||||||
cell.destroy();
|
cell.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,9 +356,9 @@ public class DrawCellManager {
|
|||||||
private void queueNewCells(){
|
private void queueNewCells(){
|
||||||
if(Globals.playerEntity != null && Globals.clientWorldData != null){
|
if(Globals.playerEntity != null && Globals.clientWorldData != null){
|
||||||
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
|
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
|
||||||
for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_SIZE){
|
for(int x = -(int)drawFullModelRadius; x < drawFullModelRadius; x = x + ChunkData.CHUNK_SIZE){
|
||||||
for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_SIZE){
|
for(int y = -(int)drawFullModelRadius; y < drawFullModelRadius; y = y + ChunkData.CHUNK_SIZE){
|
||||||
for(int z = -(int)drawRadius; z < drawRadius; z = z + ChunkData.CHUNK_SIZE){
|
for(int z = -(int)drawFullModelRadius; z < drawFullModelRadius; z = z + ChunkData.CHUNK_SIZE){
|
||||||
Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z);
|
Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z);
|
||||||
Vector3i worldPos = new Vector3i(
|
Vector3i worldPos = new Vector3i(
|
||||||
Globals.clientWorldData.convertRealToChunkSpace(newPos.x),
|
Globals.clientWorldData.convertRealToChunkSpace(newPos.x),
|
||||||
@ -316,7 +371,7 @@ public class DrawCellManager {
|
|||||||
Globals.clientWorldData.convertChunkToRealSpace(worldPos.z)
|
Globals.clientWorldData.convertChunkToRealSpace(worldPos.z)
|
||||||
);
|
);
|
||||||
if(
|
if(
|
||||||
playerPos.distance(chunkRealSpace) < drawRadius &&
|
playerPos.distance(chunkRealSpace) < drawFullModelRadius &&
|
||||||
worldPos.x >= 0 &&
|
worldPos.x >= 0 &&
|
||||||
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||||
worldPos.y >= 0 &&
|
worldPos.y >= 0 &&
|
||||||
@ -330,7 +385,7 @@ public class DrawCellManager {
|
|||||||
Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.z)
|
Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.z)
|
||||||
);
|
);
|
||||||
if(!keyCellMap.containsKey(key) && !hasNotRequested.contains(key) && !undrawable.contains(key) && !drawable.contains(key) &&
|
if(!keyCellMap.containsKey(key) && !hasNotRequested.contains(key) && !undrawable.contains(key) && !drawable.contains(key) &&
|
||||||
!hasRequested.contains(key)){
|
!requested.contains(key)){
|
||||||
hasNotRequested.add(key);
|
hasNotRequested.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,27 +410,20 @@ public class DrawCellManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits a cell key into its constituent coordinates in array format.
|
* Controls whether the client generates drawable chunks or just physics chunks (ie if running a headless client)
|
||||||
* @param cellKey The cell key to split
|
* @param generate true to generate graphics, false otherwise
|
||||||
* @return The coordinates in array format
|
|
||||||
*/
|
*/
|
||||||
// private int[] splitKeyToCoordinates(String cellKey){
|
|
||||||
// int[] rVal = new int[3];
|
|
||||||
// String[] components = cellKey.split("_");
|
|
||||||
// for(int i = 0; i < 3; i++){
|
|
||||||
// rVal[i] = Integer.parseInt(components[i]);
|
|
||||||
// }
|
|
||||||
// return rVal;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public boolean coordsInPhysicsSpace(int worldX, int worldY){
|
|
||||||
return worldX <= cellX + physicsRadius && worldX >= cellX - physicsRadius && worldY <= cellY + physicsRadius && worldY >= cellY - physicsRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGenerateDrawables(boolean generate){
|
public void setGenerateDrawables(boolean generate){
|
||||||
this.generateDrawables = generate;
|
this.generateDrawables = generate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the terrain cache has a chunk at a given world point
|
||||||
|
* @param worldX the x coordinate
|
||||||
|
* @param worldY the y coordinate
|
||||||
|
* @param worldZ the z coordinate
|
||||||
|
* @return true if the chunk data exists, false otherwise
|
||||||
|
*/
|
||||||
boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
||||||
if(Globals.clientTerrainManager != null){
|
if(Globals.clientTerrainManager != null){
|
||||||
return Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldX,worldY,worldZ);
|
return Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldX,worldY,worldZ);
|
||||||
@ -428,11 +476,11 @@ public class DrawCellManager {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the draw radius
|
* Gets the radius within which full-detail models are drawn
|
||||||
* @return the draw radius
|
* @return the radius
|
||||||
*/
|
*/
|
||||||
public double getDrawRadius(){
|
public double getDrawFullModelRadius(){
|
||||||
return drawRadius;
|
return drawFullModelRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -444,6 +492,5 @@ public class DrawCellManager {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// public
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ public class VoxelTextureAtlas {
|
|||||||
* @return the index in the atlas of the texture of the provided voxel type
|
* @return the index in the atlas of the texture of the provided voxel type
|
||||||
*/
|
*/
|
||||||
public int getVoxelTypeOffset(int voxelTypeId){
|
public int getVoxelTypeOffset(int voxelTypeId){
|
||||||
return typeCoordMap.get(voxelTypeId);
|
return typeCoordMap.containsKey(voxelTypeId) ? typeCoordMap.get(voxelTypeId) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
package electrosphere.client.terrain.editing;
|
package electrosphere.client.terrain.editing;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3i;
|
|
||||||
|
|
||||||
import electrosphere.client.terrain.cache.ChunkData;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import java.nio.IntBuffer;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ public class ClientTerrainManager {
|
|||||||
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||||
|
|
||||||
//caches chunks from server
|
//caches chunks from server
|
||||||
static final int CACHE_SIZE = 50;
|
static final int CACHE_SIZE = 500;
|
||||||
|
|
||||||
//used for caching the macro values
|
//used for caching the macro values
|
||||||
ClientTerrainCache terrainCache;
|
ClientTerrainCache terrainCache;
|
||||||
@ -55,6 +54,9 @@ public class ClientTerrainManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles messages that have been received from the server
|
||||||
|
*/
|
||||||
public void handleMessages(){
|
public void handleMessages(){
|
||||||
List<TerrainMessage> bouncedMessages = new LinkedList<TerrainMessage>();
|
List<TerrainMessage> bouncedMessages = new LinkedList<TerrainMessage>();
|
||||||
for(TerrainMessage message : messageQueue){
|
for(TerrainMessage message : messageQueue){
|
||||||
@ -99,14 +101,32 @@ public class ClientTerrainManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a terrain message to the queue of messages that this manager needs to process
|
||||||
|
* @param message The message
|
||||||
|
*/
|
||||||
public void attachTerrainMessage(TerrainMessage message){
|
public void attachTerrainMessage(TerrainMessage message){
|
||||||
messageQueue.add(message);
|
messageQueue.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the terrain cache contains chunk data at a given world position
|
||||||
|
* @param worldX the x position
|
||||||
|
* @param worldY the y position
|
||||||
|
* @param worldZ the z position
|
||||||
|
* @return true if the data exists, false otherwise
|
||||||
|
*/
|
||||||
public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){
|
||||||
return terrainCache.containsChunkDataAtWorldPoint(worldX, worldY, worldZ);
|
return terrainCache.containsChunkDataAtWorldPoint(worldX, worldY, worldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the cache contains chunk data at a real-space coordinate
|
||||||
|
* @param x the x coordinate
|
||||||
|
* @param y the y coordinate
|
||||||
|
* @param z the z coordinate
|
||||||
|
* @return true if the cache contains the chunk data at the coordinate, false otherwise
|
||||||
|
*/
|
||||||
public boolean containsChunkDataAtRealPoint(double x, double y, double z){
|
public boolean containsChunkDataAtRealPoint(double x, double y, double z){
|
||||||
assert clientWorldData != null;
|
assert clientWorldData != null;
|
||||||
return terrainCache.containsChunkDataAtWorldPoint(
|
return terrainCache.containsChunkDataAtWorldPoint(
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
import electrosphere.audio.AudioUtils;
|
import electrosphere.audio.AudioUtils;
|
||||||
import electrosphere.audio.VirtualAudioSource;
|
import electrosphere.audio.VirtualAudioSource;
|
||||||
@ -15,7 +16,9 @@ import electrosphere.client.fluid.cells.FluidCellManager;
|
|||||||
import electrosphere.client.foliagemanager.ClientFoliageManager;
|
import electrosphere.client.foliagemanager.ClientFoliageManager;
|
||||||
import electrosphere.client.sim.ClientSimulation;
|
import electrosphere.client.sim.ClientSimulation;
|
||||||
import electrosphere.client.targeting.crosshair.Crosshair;
|
import electrosphere.client.targeting.crosshair.Crosshair;
|
||||||
|
import electrosphere.client.terrain.cells.DrawCell;
|
||||||
import electrosphere.client.terrain.cells.DrawCellManager;
|
import electrosphere.client.terrain.cells.DrawCellManager;
|
||||||
|
import electrosphere.client.terrain.cells.DrawCell.DrawCellFace;
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
import electrosphere.controls.ControlHandler;
|
import electrosphere.controls.ControlHandler;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
@ -28,6 +31,7 @@ import electrosphere.entity.EntityUtils;
|
|||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.state.movement.ApplyRotationTree;
|
import electrosphere.entity.state.movement.ApplyRotationTree;
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||||
import electrosphere.entity.types.tree.ProceduralTree;
|
import electrosphere.entity.types.tree.ProceduralTree;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.menu.MenuGenerators;
|
import electrosphere.menu.MenuGenerators;
|
||||||
@ -36,8 +40,10 @@ import electrosphere.menu.WindowUtils;
|
|||||||
import electrosphere.menu.mainmenu.MenuGeneratorsMultiplayer;
|
import electrosphere.menu.mainmenu.MenuGeneratorsMultiplayer;
|
||||||
import electrosphere.net.NetUtils;
|
import electrosphere.net.NetUtils;
|
||||||
import electrosphere.net.client.ClientNetworking;
|
import electrosphere.net.client.ClientNetworking;
|
||||||
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||||
import electrosphere.renderer.ui.elements.Window;
|
import electrosphere.renderer.ui.elements.Window;
|
||||||
import electrosphere.server.datacell.EntityDataCellMapper;
|
import electrosphere.server.datacell.EntityDataCellMapper;
|
||||||
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
import electrosphere.util.MathUtils;
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
public class ClientLoading {
|
public class ClientLoading {
|
||||||
@ -180,7 +186,6 @@ public class ClientLoading {
|
|||||||
} else {
|
} else {
|
||||||
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), MathUtils.getOriginVectorf());
|
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), MathUtils.getOriginVectorf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package electrosphere.entity.types.terrain;
|
|||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
import electrosphere.client.terrain.cells.DrawCell;
|
||||||
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
||||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
@ -11,6 +12,8 @@ import electrosphere.entity.EntityCreationUtils;
|
|||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
||||||
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration;
|
||||||
|
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,19 +24,23 @@ public class TerrainChunk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a client terrain chunk based on weights and values provided
|
* Creates a client terrain chunk based on weights and values provided
|
||||||
* @param weights The terrain weights
|
* @param chunkData the chunk data to generate with
|
||||||
* @param values The values (block types)
|
|
||||||
* @param levelOfDetail Increasing value that increments level of detail. 0 would be full resolution, 1 would be half resolution and so on. Only generates physics if levelOfDetail is 0
|
* @param levelOfDetail Increasing value that increments level of detail. 0 would be full resolution, 1 would be half resolution and so on. Only generates physics if levelOfDetail is 0
|
||||||
* @return The terrain chunk entity
|
* @return The terrain chunk entity
|
||||||
*/
|
*/
|
||||||
public static Entity clientCreateTerrainChunkEntity(float[][][] weights, int[][][] values, int levelOfDetail, VoxelTextureAtlas atlas){
|
public static Entity clientCreateTerrainChunkEntity(TransvoxelChunkData chunkData, int levelOfDetail, VoxelTextureAtlas atlas){
|
||||||
|
|
||||||
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values);
|
TerrainChunkData data;
|
||||||
|
if(levelOfDetail == DrawCell.FULL_DETAIL_LOD){
|
||||||
|
data = TerrainChunkModelGeneration.generateTerrainChunkData(chunkData.terrainGrid, chunkData.textureGrid, levelOfDetail);
|
||||||
|
} else {
|
||||||
|
data = TransvoxelModelGeneration.generateTerrainChunkData(chunkData);
|
||||||
|
}
|
||||||
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas);
|
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas);
|
||||||
|
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
|
||||||
if(data.vertices.size() > 0 && levelOfDetail < 1){
|
if(data.vertices.size() > 0 && levelOfDetail == DrawCell.FULL_DETAIL_LOD){
|
||||||
PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data);
|
PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +60,7 @@ public class TerrainChunk {
|
|||||||
*/
|
*/
|
||||||
public static Entity serverCreateTerrainChunkEntity(Realm realm, Vector3d position, float[][][] weights, int[][][] values){
|
public static Entity serverCreateTerrainChunkEntity(Realm realm, Vector3d position, float[][][] weights, int[][][] values){
|
||||||
|
|
||||||
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values);
|
TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values, DrawCell.FULL_DETAIL_LOD);
|
||||||
|
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
||||||
if(data.vertices.size() > 0){
|
if(data.vertices.size() > 0){
|
||||||
|
|||||||
@ -52,6 +52,9 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
//is the voxel selection window open
|
//is the voxel selection window open
|
||||||
static boolean voxelWindowOpen = false;
|
static boolean voxelWindowOpen = false;
|
||||||
|
|
||||||
|
//vertical offset from cursor position to spawn things at
|
||||||
|
static final Vector3d cursorVerticalOffset = new Vector3d(0,0.05,0);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the level editor side panel top view
|
* Creates the level editor side panel top view
|
||||||
@ -172,7 +175,7 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||||
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||||
CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, data.getCreatureId(), null);
|
CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, data.getCreatureId(), null);
|
||||||
return false;
|
return false;
|
||||||
}}));
|
}}));
|
||||||
@ -202,7 +205,7 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||||
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||||
FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, data.getName(), new Random().nextLong());
|
FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, data.getName(), new Random().nextLong());
|
||||||
return false;
|
return false;
|
||||||
}}));
|
}}));
|
||||||
@ -232,7 +235,7 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||||
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||||
ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId());
|
ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId());
|
||||||
return false;
|
return false;
|
||||||
}}));
|
}}));
|
||||||
@ -263,7 +266,7 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||||
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||||
ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId());
|
ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId());
|
||||||
return false;
|
return false;
|
||||||
}}));
|
}}));
|
||||||
|
|||||||
@ -176,6 +176,16 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer);
|
rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA:
|
||||||
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
|
rVal = TerrainMessage.parseRequestReducedChunkDataMessage(byteBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA:
|
||||||
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
|
rVal = TerrainMessage.parseSendReducedChunkDataMessage(byteBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestFluidDataMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestFluidDataMessage(byteBuffer);
|
||||||
|
|||||||
@ -16,6 +16,8 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
SPAWNPOSITION,
|
SPAWNPOSITION,
|
||||||
REQUESTCHUNKDATA,
|
REQUESTCHUNKDATA,
|
||||||
SENDCHUNKDATA,
|
SENDCHUNKDATA,
|
||||||
|
REQUESTREDUCEDCHUNKDATA,
|
||||||
|
SENDREDUCEDCHUNKDATA,
|
||||||
REQUESTFLUIDDATA,
|
REQUESTFLUIDDATA,
|
||||||
SENDFLUIDDATA,
|
SENDFLUIDDATA,
|
||||||
UPDATEFLUIDDATA,
|
UPDATEFLUIDDATA,
|
||||||
@ -40,6 +42,7 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
double realLocationY;
|
double realLocationY;
|
||||||
double realLocationZ;
|
double realLocationZ;
|
||||||
byte[] chunkData;
|
byte[] chunkData;
|
||||||
|
int chunkResolution;
|
||||||
float terrainWeight;
|
float terrainWeight;
|
||||||
int terrainValue;
|
int terrainValue;
|
||||||
|
|
||||||
@ -196,6 +199,14 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
this.chunkData = chunkData;
|
this.chunkData = chunkData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getchunkResolution() {
|
||||||
|
return chunkResolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setchunkResolution(int chunkResolution) {
|
||||||
|
this.chunkResolution = chunkResolution;
|
||||||
|
}
|
||||||
|
|
||||||
public float getterrainWeight() {
|
public float getterrainWeight() {
|
||||||
return terrainWeight;
|
return terrainWeight;
|
||||||
}
|
}
|
||||||
@ -262,6 +273,14 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
}
|
}
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA:
|
||||||
return TerrainMessage.canParsesendChunkDataMessage(byteBuffer);
|
return TerrainMessage.canParsesendChunkDataMessage(byteBuffer);
|
||||||
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA:
|
||||||
|
if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA_SIZE){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA:
|
||||||
|
return TerrainMessage.canParseSendReducedChunkDataMessage(byteBuffer);
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE){
|
if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE){
|
||||||
return true;
|
return true;
|
||||||
@ -478,6 +497,79 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TerrainMessage parseRequestReducedChunkDataMessage(CircularByteBuffer byteBuffer){
|
||||||
|
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTREDUCEDCHUNKDATA);
|
||||||
|
stripPacketHeader(byteBuffer);
|
||||||
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setchunkResolution(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TerrainMessage constructRequestReducedChunkDataMessage(int worldX,int worldY,int worldZ,int chunkResolution){
|
||||||
|
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTREDUCEDCHUNKDATA);
|
||||||
|
rVal.setworldX(worldX);
|
||||||
|
rVal.setworldY(worldY);
|
||||||
|
rVal.setworldZ(worldZ);
|
||||||
|
rVal.setchunkResolution(chunkResolution);
|
||||||
|
rVal.serialize();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canParseSendReducedChunkDataMessage(CircularByteBuffer byteBuffer){
|
||||||
|
int currentStreamLength = byteBuffer.getRemaining();
|
||||||
|
List<Byte> temporaryByteQueue = new LinkedList();
|
||||||
|
if(currentStreamLength < 6){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 10){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 14){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 18){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int chunkDataSize = 0;
|
||||||
|
if(currentStreamLength < 22){
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(18 + 0));
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(18 + 1));
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(18 + 2));
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(18 + 3));
|
||||||
|
chunkDataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 22 + chunkDataSize){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TerrainMessage parseSendReducedChunkDataMessage(CircularByteBuffer byteBuffer){
|
||||||
|
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDREDUCEDCHUNKDATA);
|
||||||
|
stripPacketHeader(byteBuffer);
|
||||||
|
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setchunkResolution(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setchunkData(ByteStreamUtils.popByteArrayFromByteQueue(byteBuffer));
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TerrainMessage constructSendReducedChunkDataMessage(int worldX,int worldY,int worldZ,int chunkResolution,byte[] chunkData){
|
||||||
|
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.SENDREDUCEDCHUNKDATA);
|
||||||
|
rVal.setworldX(worldX);
|
||||||
|
rVal.setworldY(worldY);
|
||||||
|
rVal.setworldZ(worldZ);
|
||||||
|
rVal.setchunkResolution(chunkResolution);
|
||||||
|
rVal.setchunkData(chunkData);
|
||||||
|
rVal.serialize();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
public static TerrainMessage parseRequestFluidDataMessage(CircularByteBuffer byteBuffer){
|
public static TerrainMessage parseRequestFluidDataMessage(CircularByteBuffer byteBuffer){
|
||||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTFLUIDDATA);
|
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTFLUIDDATA);
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
@ -807,6 +899,59 @@ public class TerrainMessage extends NetworkMessage {
|
|||||||
rawBytes[18+i] = chunkData[i];
|
rawBytes[18+i] = chunkData[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case REQUESTREDUCEDCHUNKDATA:
|
||||||
|
rawBytes = new byte[2+4+4+4+4];
|
||||||
|
//message header
|
||||||
|
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
|
||||||
|
//entity messaage header
|
||||||
|
rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA;
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(worldX);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[2+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(worldY);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[6+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(worldZ);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[10+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(chunkResolution);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[14+i] = intValues[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SENDREDUCEDCHUNKDATA:
|
||||||
|
rawBytes = new byte[2+4+4+4+4+4+chunkData.length];
|
||||||
|
//message header
|
||||||
|
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
|
||||||
|
//entity messaage header
|
||||||
|
rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA;
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(worldX);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[2+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(worldY);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[6+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(worldZ);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[10+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(chunkResolution);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[14+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(chunkData.length);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[18+i] = intValues[i];
|
||||||
|
}
|
||||||
|
for(int i = 0; i < chunkData.length; i++){
|
||||||
|
rawBytes[22+i] = chunkData[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
case REQUESTFLUIDDATA:
|
case REQUESTFLUIDDATA:
|
||||||
rawBytes = new byte[2+4+4+4];
|
rawBytes = new byte[2+4+4+4];
|
||||||
//message header
|
//message header
|
||||||
|
|||||||
@ -69,9 +69,11 @@ Message categories
|
|||||||
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 5;
|
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 5;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 6;
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 6;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 7;
|
public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 7;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 8;
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA = 8;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 9;
|
public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA = 9;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 10;
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 10;
|
||||||
|
public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 11;
|
||||||
|
public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 12;
|
||||||
/*
|
/*
|
||||||
Terrain packet sizes
|
Terrain packet sizes
|
||||||
*/
|
*/
|
||||||
@ -82,6 +84,7 @@ Message categories
|
|||||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTUSETERRAINPALETTE_SIZE = 38;
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTUSETERRAINPALETTE_SIZE = 38;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 26;
|
public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 26;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE = 14;
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE = 14;
|
||||||
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA_SIZE = 18;
|
||||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE = 14;
|
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE = 14;
|
||||||
/*
|
/*
|
||||||
Server subcategories
|
Server subcategories
|
||||||
|
|||||||
@ -1,23 +1,18 @@
|
|||||||
package electrosphere.renderer.meshgen;
|
package electrosphere.renderer.meshgen;
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
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 org.joml.Matrix4f;
|
|
||||||
import org.joml.Vector2f;
|
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
|
||||||
|
|
||||||
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
@ -25,14 +20,13 @@ import electrosphere.entity.types.terrain.TerrainChunkData;
|
|||||||
import electrosphere.renderer.model.Material;
|
import electrosphere.renderer.model.Material;
|
||||||
import electrosphere.renderer.model.Mesh;
|
import electrosphere.renderer.model.Mesh;
|
||||||
import electrosphere.renderer.model.Model;
|
import electrosphere.renderer.model.Model;
|
||||||
import electrosphere.renderer.shader.ShaderProgram;
|
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
public class TerrainChunkModelGeneration {
|
public class TerrainChunkModelGeneration {
|
||||||
|
|
||||||
//http://paulbourke.net/geometry/polygonise/
|
//http://paulbourke.net/geometry/polygonise/
|
||||||
|
|
||||||
static int edgeTable[]={
|
public static int edgeTable[]={
|
||||||
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
||||||
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||||
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
||||||
@ -68,7 +62,7 @@ public class TerrainChunkModelGeneration {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//256 by 16
|
//256 by 16
|
||||||
static int triTable[][] = {
|
public static int triTable[][] = {
|
||||||
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||||
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
{0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||||
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
{0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
|
||||||
@ -625,7 +619,7 @@ public class TerrainChunkModelGeneration {
|
|||||||
return new Vector3f(x,y,z);
|
return new Vector3f(x,y,z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TerrainChunkData generateTerrainChunkData(float[][][] terrainGrid, int[][][] textureGrid){
|
public static TerrainChunkData generateTerrainChunkData(float[][][] terrainGrid, int[][][] textureGrid, int lod){
|
||||||
|
|
||||||
// 5 6
|
// 5 6
|
||||||
// +-------------+ +-----5-------+ ^ Y
|
// +-------------+ +-----5-------+ ^ Y
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -24,13 +24,13 @@ public class RenderScreenPipeline implements RenderPipeline {
|
|||||||
//the leftover texture gets used to draw the screen framebuffer quad
|
//the leftover texture gets used to draw the screen framebuffer quad
|
||||||
//which doesnt work
|
//which doesnt work
|
||||||
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
||||||
GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
||||||
openGLState.glActiveTexture(GL40.GL_TEXTURE1);
|
openGLState.glActiveTexture(GL40.GL_TEXTURE1);
|
||||||
GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
||||||
openGLState.glActiveTexture(GL40.GL_TEXTURE2);
|
openGLState.glActiveTexture(GL40.GL_TEXTURE2);
|
||||||
GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
||||||
openGLState.glActiveTexture(GL40.GL_TEXTURE3);
|
openGLState.glActiveTexture(GL40.GL_TEXTURE3);
|
||||||
GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
|
||||||
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
||||||
|
|
||||||
openGLState.glDepthTest(false);
|
openGLState.glDepthTest(false);
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class VolumeBufferPipeline implements RenderPipeline {
|
|||||||
|
|
||||||
RenderingEngine.volumeDepthBackfaceFramebuffer.bind();
|
RenderingEngine.volumeDepthBackfaceFramebuffer.bind();
|
||||||
GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT);
|
GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT);
|
||||||
GL40.glActiveTexture(GL40.GL_TEXTURE0);
|
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
||||||
// glBindTexture(GL_TEXTURE_2D, woodTexture);
|
// glBindTexture(GL_TEXTURE_2D, woodTexture);
|
||||||
// renderScene(simpleDepthShader);
|
// renderScene(simpleDepthShader);
|
||||||
|
|
||||||
|
|||||||
@ -7,14 +7,12 @@ import org.joml.Vector3i;
|
|||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
import electrosphere.server.content.serialization.ContentSerialization;
|
import electrosphere.server.content.serialization.ContentSerialization;
|
||||||
import electrosphere.server.content.serialization.EntitySerialization;
|
import electrosphere.server.content.serialization.EntitySerialization;
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.pathfinding.NavMeshUtils;
|
|
||||||
import electrosphere.server.saves.SaveUtils;
|
import electrosphere.server.saves.SaveUtils;
|
||||||
import electrosphere.util.FileUtils;
|
import electrosphere.util.FileUtils;
|
||||||
|
|
||||||
@ -54,7 +52,8 @@ public class ServerContentManager {
|
|||||||
hydrateRawContent(realm,cell,contentRaw);
|
hydrateRawContent(realm,cell,contentRaw);
|
||||||
} else {
|
} else {
|
||||||
//else create from scratch
|
//else create from scratch
|
||||||
EnvironmentGenerator.generateForest(realm, cell, worldPos, 0);
|
//UNCOMMENT THIS WHEN YOU WANT CONTENT GENERATED FOR WORLDS AGAIN
|
||||||
|
// EnvironmentGenerator.generateForest(realm, cell, worldPos, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//just because content wasn't generated doesn't mean there isn't data saved under that key
|
//just because content wasn't generated doesn't mean there isn't data saved under that key
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user