Compare commits
	
		
			No commits in common. "8dcff7efe00de17bcee633ccfe0ec5205b7b4885" and "2b715ab3254e2b7f907fdd5f3b08427bd9dbdbcd" have entirely different histories.
		
	
	
		
			8dcff7efe0
			...
			2b715ab325
		
	
		
| @ -1,3 +1,3 @@ | ||||
| #maven.buildNumber.plugin properties file | ||||
| #Wed Jun 19 19:19:09 EDT 2024 | ||||
| buildNumber=138 | ||||
| #Fri Jun 14 13:45:11 EDT 2024 | ||||
| buildNumber=137 | ||||
|  | ||||
| @ -10,7 +10,6 @@ | ||||
| - @subpage archimprovementtargets | ||||
| - @subpage savesindex | ||||
| - @subpage hitboxesindex | ||||
| - @subpage drawcell | ||||
| 
 | ||||
| 
 | ||||
| # What is this section | ||||
|  | ||||
| @ -1,6 +0,0 @@ | ||||
| @page drawcell Draw Cells | ||||
| 
 | ||||
| [TOC] | ||||
|  - @subpage transvoxelalgorithm | ||||
| 
 | ||||
|  | ||||
| @ -1,49 +0,0 @@ | ||||
| @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 | ||||
| 
 | ||||
| 
 | ||||
| @ -1,3 +0,0 @@ | ||||
| @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,7 +4,6 @@ | ||||
| 
 | ||||
| [TOC] | ||||
|  - @subpage whatmakesaquestgood | ||||
|  - @subpage narrativearcdesign | ||||
| 
 | ||||
| 
 | ||||
| TODO: describe | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 28 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 9.7 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 9.8 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 6.4 KiB | 
| @ -1,11 +1,6 @@ | ||||
| @page bigthings Big Things I want to build | ||||
| # and may or may not have the sanity to build | ||||
| 
 | ||||
| DONE: | ||||
| 
 | ||||
| 
 | ||||
| TODO(?): | ||||
| 
 | ||||
|  - CFD | ||||
|   - Internal Boundaries | ||||
|   - Multigrid optimization | ||||
| @ -13,8 +8,6 @@ TODO(?): | ||||
| 
 | ||||
|  - Transvoxel Algorithm | ||||
| 
 | ||||
|  - Building cube voxels w/ LOD | ||||
| 
 | ||||
|  - Deferred Shading Pipeline | ||||
| 
 | ||||
|  - Audio Ray Tracing | ||||
| @ -24,7 +17,3 @@ TODO(?): | ||||
|  - Massive scale creature groups | ||||
|    (ie 10k armies) | ||||
| 
 | ||||
|  - Use HTML to define ui windows | ||||
|   - Some css support | ||||
|   - Language file for translation | ||||
| 
 | ||||
|  | ||||
| @ -371,25 +371,9 @@ Highlevel netcode gen updates | ||||
|   - 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 | ||||
| 
 | ||||
| (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 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| Demo requirements: | ||||
|  = Assets =  | ||||
| Block animation in first person | ||||
| @ -401,6 +385,7 @@ Audio FX for everything | ||||
| 
 | ||||
|  = Coding =  | ||||
| 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 | ||||
| Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around) | ||||
|  - Introduce block hitbox (blockbox) type | ||||
| @ -415,26 +400,6 @@ 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: | ||||
| always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible | ||||
| 
 | ||||
| @ -492,6 +457,22 @@ Shader library system | ||||
| 
 | ||||
| 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 | ||||
|  - Multiple foliage models in same cell | ||||
| 
 | ||||
| @ -599,6 +580,9 @@ Generic collision engine to support different instances of engine (eg hitboxes v | ||||
|  - Major refactoring to happen here | ||||
| Procedural Cliff Texture | ||||
|  - 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 | ||||
|  - 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' | ||||
|  | ||||
| @ -1,17 +0,0 @@ | ||||
| @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,11 +90,6 @@ | ||||
|                     "type" : "BYTE_ARRAY" | ||||
|                 }, | ||||
| 
 | ||||
|                 { | ||||
|                     "name" : "chunkResolution", | ||||
|                     "type" : "FIXED_INT" | ||||
|                 }, | ||||
| 
 | ||||
|                 { | ||||
|                     "name" : "terrainWeight", | ||||
|                     "type" : "FIXED_FLOAT" | ||||
| @ -191,27 +186,6 @@ | ||||
|                         "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", | ||||
|                     "description" : "Requests a fluid data from the server", | ||||
|  | ||||
| @ -11,47 +11,39 @@ import electrosphere.entity.ClientEntityUtils; | ||||
| import electrosphere.entity.Entity; | ||||
| import electrosphere.entity.EntityUtils; | ||||
| import electrosphere.entity.types.terrain.TerrainChunk; | ||||
| import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData; | ||||
| import electrosphere.server.terrain.manager.ServerTerrainChunk; | ||||
| import electrosphere.renderer.shader.ShaderProgram; | ||||
| import electrosphere.renderer.texture.Texture; | ||||
| import electrosphere.server.datacell.Realm; | ||||
| 
 | ||||
| /** | ||||
|  * A single drawcell - contains an entity that has a physics mesh and potentially graphics | ||||
|  * | ||||
|  * @author satellite | ||||
|  */ | ||||
| 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 | ||||
|     Vector3i worldPos; | ||||
|      | ||||
|     //the main entity for the cell | ||||
|     Entity modelEntity; | ||||
|      | ||||
|     //the physics mesh | ||||
|     DBody physicsObject; | ||||
| 
 | ||||
|     //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]; | ||||
|     int[][][] types = new int[ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE][ChunkData.CHUNK_DATA_GENERATOR_SIZE]; | ||||
|      | ||||
|     static Texture groundTextureOne = new Texture("/Textures/Ground/Dirt1.png"); | ||||
|     static Texture groundTextureTwo = new Texture("/Textures/Ground/Dirt1.png"); | ||||
|     static Texture groundTextureThree = new Texture("/Textures/Ground/Dirt1.png"); | ||||
|     static Texture groundTextureFour = new Texture("/Textures/Ground/Dirt1.png"); | ||||
|      | ||||
|     //the maximum detail LOD level | ||||
|     public static final int FULL_DETAIL_LOD = 0; | ||||
|     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"); | ||||
|     } | ||||
|      | ||||
|      | ||||
|     /** | ||||
|      * Private constructor | ||||
|      */ | ||||
|     DrawCell(){ | ||||
|          | ||||
|     } | ||||
| @ -71,23 +63,18 @@ public class DrawCell { | ||||
|     /** | ||||
|      * Generates a drawable entity based on this chunk | ||||
|      */ | ||||
|     public void generateDrawableEntity(VoxelTextureAtlas atlas, int lod, DrawCellFace higherLODFace){ | ||||
|     public void generateDrawableEntity(VoxelTextureAtlas atlas){ | ||||
|         if(modelEntity != null){ | ||||
|             Globals.clientScene.deregisterEntity(modelEntity); | ||||
|         } | ||||
|         this.fillInData(); | ||||
|         TransvoxelChunkData chunkData = new TransvoxelChunkData(weights, types, lod); | ||||
|         if(lod > FULL_DETAIL_LOD){ | ||||
| 
 | ||||
|         } | ||||
|         modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(chunkData, lod, atlas); | ||||
|         fillInData(); | ||||
| 
 | ||||
|         modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(weights, types, 0, atlas); | ||||
| 
 | ||||
|         ClientEntityUtils.initiallyPositionEntity(modelEntity, getRealPos()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the real-space position of the draw cell | ||||
|      * @return the real-space position | ||||
|      */ | ||||
|     protected Vector3d getRealPos(){ | ||||
|         return new Vector3d( | ||||
|             worldPos.x * ChunkData.CHUNK_SIZE, | ||||
| @ -238,48 +225,4 @@ public class DrawCell { | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * 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,40 +9,15 @@ import org.joml.Vector3d; | ||||
| import org.joml.Vector3i; | ||||
| 
 | ||||
| import electrosphere.client.terrain.cache.ChunkData; | ||||
| import electrosphere.client.terrain.cells.DrawCell.DrawCellFace; | ||||
| import electrosphere.client.terrain.manager.ClientTerrainManager; | ||||
| import electrosphere.engine.Globals; | ||||
| import electrosphere.entity.EntityUtils; | ||||
| import electrosphere.net.parser.net.message.TerrainMessage; | ||||
| import electrosphere.renderer.shader.ShaderProgram; | ||||
| import electrosphere.server.terrain.manager.ServerTerrainChunk; | ||||
| 
 | ||||
| /** | ||||
|  * Manages the graphical entities for the terrain chunks | ||||
|  * | ||||
|  *  | ||||
|  *  | ||||
| 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 | ||||
|   | ||||
| 
 | ||||
| 
 | ||||
|  * @author satellite | ||||
|  */ | ||||
| public class DrawCellManager { | ||||
|      | ||||
| @ -52,46 +27,45 @@ public class DrawCellManager { | ||||
|     int cellY; | ||||
|     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 | ||||
|     Set<DrawCell> cells = new HashSet<DrawCell>(); | ||||
|     Set<DrawCell> cells; | ||||
|     Map<String,DrawCell> keyCellMap = new HashMap<String,DrawCell>(); | ||||
|      | ||||
|     //status of all position keys | ||||
|     Set<String> hasNotRequested = new HashSet<String>(); | ||||
|     Set<String> requested = new HashSet<String>(); | ||||
|     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>(); | ||||
|     Set<String> hasNotRequested; | ||||
|     Set<String> hasRequested; | ||||
|     Set<String> drawable; | ||||
|     Set<String> undrawable; | ||||
|     Set<String> updateable; | ||||
| 
 | ||||
|     //voxel atlas | ||||
|     VoxelTextureAtlas atlas; | ||||
|      | ||||
|     //shader program for drawable cells | ||||
|      | ||||
|     ShaderProgram program; | ||||
|      | ||||
|      | ||||
|      | ||||
|     //the real-space radius for which we will construct draw cells inside of | ||||
|     //ie, we check if the draw cell's entity would be inside this radius. If it would, create the draw cell, otherwise don't | ||||
|     double drawFullModelRadius = 50; | ||||
|     // int drawRadius = 5; | ||||
|     int drawStepdownInterval = 3; | ||||
|     int drawStepdownValue = 25; | ||||
| 
 | ||||
|     //the radius we'll draw LODed chunks for | ||||
|     double drawLODRadius = drawFullModelRadius + ServerTerrainChunk.CHUNK_DIMENSION * (2*2 + 4*4 + 8*8 + 16*16); | ||||
|     double drawRadius = 50; | ||||
|      | ||||
| 
 | ||||
|     //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 worldBoundDiscreteMin = 0; | ||||
|     int worldBoundDiscreteMax = 0; | ||||
|          | ||||
|     //client terrain manager | ||||
|     // ClientTerrainManager clientTerrainManager; | ||||
|      | ||||
|      | ||||
|     //ready to start updating? | ||||
|     boolean update = false; | ||||
| 
 | ||||
| @ -108,22 +82,22 @@ public class DrawCellManager { | ||||
|      * @param discreteY The initial discrete position Y coordinate | ||||
|      */ | ||||
|     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; | ||||
|         cellY = discreteY; | ||||
|         cellZ = discreteZ; | ||||
|          | ||||
|         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(); | ||||
|          | ||||
|         invalidateAllCells(); | ||||
| @ -131,41 +105,29 @@ public class DrawCellManager { | ||||
|         update = true; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Private constructor | ||||
|      */ | ||||
|     DrawCellManager(){ | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the player's current position in cell-space | ||||
|      * @param cellPos The cell's position | ||||
|      */ | ||||
|     public void setPlayerCell(Vector3i cellPos){ | ||||
|     public void setCell(Vector3i cellPos){ | ||||
|         cellX = cellPos.x; | ||||
|         cellY = cellPos.y; | ||||
|         cellZ = cellPos.z; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Update function that is called if a cell has not been requested | ||||
|      */ | ||||
|     void updateUnrequestedCell(){ | ||||
|         if(hasNotRequested.size() > 0){ | ||||
|             String targetKey = hasNotRequested.iterator().next(); | ||||
|             hasNotRequested.remove(targetKey); | ||||
|             Vector3i worldPos = getVectorFromKey(targetKey); | ||||
| 
 | ||||
|             // | ||||
|             //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 | ||||
|             //The following loop-hell does this | ||||
|             // | ||||
|             // Vector3i vector = getVectorFromKey(targetKey); | ||||
|             // int currentCellX = cellX - drawRadius + vector.x; | ||||
|             // int currentCellY = cellY - drawRadius + vector.y; | ||||
|             // int currentCellZ = cellZ - drawRadius + vector.z; | ||||
|             for(int i = 0; i < 2; i++){ | ||||
|                 for(int j = 0; j < 2; j++){ | ||||
|                     for(int k = 0; k < 2; k++){ | ||||
|                         Vector3i posToCheck = new Vector3i(worldPos).add(i,j,k); | ||||
|                         String requestKey = getCellKey(posToCheck.x,posToCheck.y,posToCheck.z); | ||||
|                         if( | ||||
|                             posToCheck.x >= 0 && | ||||
|                             posToCheck.x < Globals.clientWorldData.getWorldDiscreteSize() && | ||||
| @ -175,20 +137,20 @@ public class DrawCellManager { | ||||
|                             posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() && | ||||
|                             !Globals.clientTerrainManager.containsChunkDataAtWorldPoint(posToCheck.x, posToCheck.y, posToCheck.z) | ||||
|                             ){ | ||||
|                             if(!requested.contains(requestKey)){ | ||||
|                             // if(!hasRequested.contains(targetKey)){ | ||||
|                                 //client should request chunk data from server for each chunk necessary to create the model | ||||
|                                 Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestChunkDataMessage( | ||||
|                                     posToCheck.x, | ||||
|                                     posToCheck.y, | ||||
|                                     posToCheck.z | ||||
|                                 )); | ||||
|                             } | ||||
|                             // } | ||||
|                         } | ||||
|                         undrawable.add(targetKey); | ||||
|                         hasRequested.add(targetKey); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             undrawable.add(targetKey); | ||||
|             requested.add(targetKey); | ||||
|         } | ||||
|     } | ||||
|      | ||||
| @ -196,12 +158,10 @@ public class DrawCellManager { | ||||
|      * Makes one of the undrawable cells drawable | ||||
|      */ | ||||
|     void makeCellDrawable(){ | ||||
|          | ||||
|         if(undrawable.size() > 0){ | ||||
|             String targetKey = undrawable.iterator().next(); | ||||
|             Vector3i worldPos = getVectorFromKey(targetKey); | ||||
| 
 | ||||
|             // | ||||
|             //Checks if all chunk data necessary to generate a mesh is present | ||||
|             boolean containsNecessaryChunks = true; | ||||
|             for(int i = 0; i < 2; i++){ | ||||
|                 for(int j = 0; j < 2; j++){ | ||||
| @ -215,28 +175,25 @@ public class DrawCellManager { | ||||
|                         posToCheck.z < Globals.clientWorldData.getWorldDiscreteSize() && | ||||
|                         !containsChunkDataAtWorldPoint(posToCheck.x,posToCheck.y,posToCheck.z) | ||||
|                         ){ | ||||
|                             containsChunkDataAtWorldPoint(posToCheck.x,posToCheck.y,posToCheck.z); | ||||
|                             containsNecessaryChunks = false; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             // | ||||
|             //if contains data for all chunks necessary to generate visuals | ||||
|             //if contains all chunks necessary to generate visuals | ||||
|             if(containsNecessaryChunks){ | ||||
| 
 | ||||
|                 //update the status of the terrain key | ||||
|                 undrawable.remove(targetKey); | ||||
|                 drawable.add(targetKey); | ||||
| 
 | ||||
|                 //build the cell | ||||
|                 //build float array | ||||
|                 DrawCell cell = DrawCell.generateTerrainCell( | ||||
|                     worldPos | ||||
|                 ); | ||||
|                 cells.add(cell); | ||||
|                 keyCellMap.put(targetKey,cell); | ||||
|                 DrawCellFace higherLODFace = null; | ||||
|                 keyCellMap.get(targetKey).generateDrawableEntity(atlas,0,higherLODFace); | ||||
|                  | ||||
|                 // undrawable.add(targetKey); | ||||
|                 undrawable.remove(targetKey); | ||||
|                 drawable.add(targetKey); | ||||
|                 //make drawable entity | ||||
|                 keyCellMap.get(targetKey).generateDrawableEntity(atlas); | ||||
|                 //evaluate for foliage | ||||
|                 Globals.clientFoliageManager.evaluateChunk(worldPos); | ||||
|             } | ||||
| @ -259,49 +216,37 @@ public class DrawCellManager { | ||||
|                 worldPos.z >= 0 && | ||||
|                 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(); | ||||
|                 DrawCellFace higherLODFace = null; | ||||
|                 keyCellMap.get(targetKey).generateDrawableEntity(atlas,0,higherLODFace); | ||||
|                 keyCellMap.get(targetKey).generateDrawableEntity(atlas); | ||||
|             } | ||||
|             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(){ | ||||
|         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(){ | ||||
|         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(){ | ||||
|         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){ | ||||
|         return (int)(input / Globals.clientWorldData.getDynamicInterpolationRatio()); | ||||
|     } | ||||
| @ -333,7 +278,7 @@ public class DrawCellManager { | ||||
|         Set<DrawCell> cellsToRemove = new HashSet<DrawCell>(); | ||||
|         for(DrawCell cell : cells){ | ||||
|             Vector3d realPos = cell.getRealPos(); | ||||
|             if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawFullModelRadius){ | ||||
|             if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawRadius){ | ||||
|                 cellsToRemove.add(cell); | ||||
|             } | ||||
|         } | ||||
| @ -345,7 +290,7 @@ public class DrawCellManager { | ||||
|             undrawable.remove(key); | ||||
|             updateable.remove(key); | ||||
|             keyCellMap.remove(key); | ||||
|             requested.remove(key); | ||||
|             hasRequested.remove(key); | ||||
|             cell.destroy(); | ||||
|         } | ||||
|     } | ||||
| @ -356,9 +301,9 @@ public class DrawCellManager { | ||||
|     private void queueNewCells(){ | ||||
|         if(Globals.playerEntity != null && Globals.clientWorldData != null){ | ||||
|             Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); | ||||
|             for(int x = -(int)drawFullModelRadius; x < drawFullModelRadius; x = x + ChunkData.CHUNK_SIZE){ | ||||
|                 for(int y = -(int)drawFullModelRadius; y < drawFullModelRadius; y = y + ChunkData.CHUNK_SIZE){ | ||||
|                     for(int z = -(int)drawFullModelRadius; z < drawFullModelRadius; z = z + ChunkData.CHUNK_SIZE){ | ||||
|             for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_SIZE){ | ||||
|                 for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_SIZE){ | ||||
|                     for(int z = -(int)drawRadius; z < drawRadius; z = z + ChunkData.CHUNK_SIZE){ | ||||
|                         Vector3d newPos = new Vector3d(playerPos.x + x, playerPos.y + y, playerPos.z + z); | ||||
|                         Vector3i worldPos = new Vector3i( | ||||
|                             Globals.clientWorldData.convertRealToChunkSpace(newPos.x), | ||||
| @ -371,7 +316,7 @@ public class DrawCellManager { | ||||
|                             Globals.clientWorldData.convertChunkToRealSpace(worldPos.z) | ||||
|                         ); | ||||
|                         if( | ||||
|                             playerPos.distance(chunkRealSpace) < drawFullModelRadius && | ||||
|                             playerPos.distance(chunkRealSpace) < drawRadius && | ||||
|                             worldPos.x >= 0 && | ||||
|                             worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && | ||||
|                             worldPos.y >= 0 && | ||||
| @ -385,7 +330,7 @@ public class DrawCellManager { | ||||
|                                 Globals.clientWorldData.convertRealToChunkSpace(chunkRealSpace.z) | ||||
|                             ); | ||||
|                             if(!keyCellMap.containsKey(key) && !hasNotRequested.contains(key) && !undrawable.contains(key) && !drawable.contains(key) && | ||||
|                             !requested.contains(key)){ | ||||
|                             !hasRequested.contains(key)){ | ||||
|                                 hasNotRequested.add(key); | ||||
|                             } | ||||
|                         } | ||||
| @ -410,20 +355,27 @@ public class DrawCellManager { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Controls whether the client generates drawable chunks or just physics chunks (ie if running a headless client) | ||||
|      * @param generate true to generate graphics, false otherwise | ||||
|      * Splits a cell key into its constituent coordinates in array format. | ||||
|      * @param cellKey The cell key to split | ||||
|      * @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){ | ||||
|         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){ | ||||
|         if(Globals.clientTerrainManager != null){ | ||||
|             return Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldX,worldY,worldZ); | ||||
| @ -476,11 +428,11 @@ public class DrawCellManager { | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the radius within which full-detail models are drawn | ||||
|      * @return the radius | ||||
|      * Gets the draw radius | ||||
|      * @return the draw radius | ||||
|      */ | ||||
|     public double getDrawFullModelRadius(){ | ||||
|         return drawFullModelRadius; | ||||
|     public double getDrawRadius(){ | ||||
|         return drawRadius; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -492,5 +444,6 @@ 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 | ||||
|      */ | ||||
|     public int getVoxelTypeOffset(int voxelTypeId){ | ||||
|         return typeCoordMap.containsKey(voxelTypeId) ? typeCoordMap.get(voxelTypeId) : -1; | ||||
|         return typeCoordMap.get(voxelTypeId); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,9 @@ | ||||
| package electrosphere.client.terrain.editing; | ||||
| 
 | ||||
| import org.joml.Vector3d; | ||||
| import org.joml.Vector3i; | ||||
| 
 | ||||
| import electrosphere.client.terrain.cache.ChunkData; | ||||
| import electrosphere.engine.Globals; | ||||
| import electrosphere.net.parser.net.message.TerrainMessage; | ||||
| 
 | ||||
|  | ||||
| @ -6,6 +6,7 @@ import java.nio.IntBuffer; | ||||
| import java.util.Collection; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.UUID; | ||||
| import java.util.concurrent.CopyOnWriteArrayList; | ||||
| 
 | ||||
| @ -35,7 +36,7 @@ public class ClientTerrainManager { | ||||
|     public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO; | ||||
|      | ||||
|     //caches chunks from server | ||||
|     static final int CACHE_SIZE = 500; | ||||
|     static final int CACHE_SIZE = 50; | ||||
|      | ||||
|     //used for caching the macro values | ||||
|     ClientTerrainCache terrainCache; | ||||
| @ -54,9 +55,6 @@ public class ClientTerrainManager { | ||||
|     } | ||||
|      | ||||
|      | ||||
|     /** | ||||
|      * Handles messages that have been received from the server | ||||
|      */ | ||||
|     public void handleMessages(){ | ||||
|         List<TerrainMessage> bouncedMessages = new LinkedList<TerrainMessage>(); | ||||
|         for(TerrainMessage message : messageQueue){ | ||||
| @ -101,32 +99,14 @@ 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){ | ||||
|         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){ | ||||
|         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){ | ||||
|         assert clientWorldData != null; | ||||
|         return terrainCache.containsChunkDataAtWorldPoint( | ||||
|  | ||||
| @ -6,7 +6,6 @@ import java.util.concurrent.TimeUnit; | ||||
| import org.joml.Quaterniond; | ||||
| import org.joml.Vector3d; | ||||
| import org.joml.Vector3f; | ||||
| import org.joml.Vector3i; | ||||
| 
 | ||||
| import electrosphere.audio.AudioUtils; | ||||
| import electrosphere.audio.VirtualAudioSource; | ||||
| @ -16,9 +15,7 @@ import electrosphere.client.fluid.cells.FluidCellManager; | ||||
| import electrosphere.client.foliagemanager.ClientFoliageManager; | ||||
| import electrosphere.client.sim.ClientSimulation; | ||||
| import electrosphere.client.targeting.crosshair.Crosshair; | ||||
| import electrosphere.client.terrain.cells.DrawCell; | ||||
| import electrosphere.client.terrain.cells.DrawCellManager; | ||||
| import electrosphere.client.terrain.cells.DrawCell.DrawCellFace; | ||||
| import electrosphere.collision.CollisionEngine; | ||||
| import electrosphere.controls.ControlHandler; | ||||
| import electrosphere.engine.Globals; | ||||
| @ -31,7 +28,6 @@ import electrosphere.entity.EntityUtils; | ||||
| import electrosphere.entity.btree.BehaviorTree; | ||||
| import electrosphere.entity.state.movement.ApplyRotationTree; | ||||
| import electrosphere.entity.types.camera.CameraEntityUtils; | ||||
| import electrosphere.entity.types.terrain.TerrainChunk; | ||||
| import electrosphere.entity.types.tree.ProceduralTree; | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| import electrosphere.menu.MenuGenerators; | ||||
| @ -40,10 +36,8 @@ import electrosphere.menu.WindowUtils; | ||||
| import electrosphere.menu.mainmenu.MenuGeneratorsMultiplayer; | ||||
| import electrosphere.net.NetUtils; | ||||
| import electrosphere.net.client.ClientNetworking; | ||||
| import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData; | ||||
| import electrosphere.renderer.ui.elements.Window; | ||||
| import electrosphere.server.datacell.EntityDataCellMapper; | ||||
| import electrosphere.server.terrain.manager.ServerTerrainChunk; | ||||
| import electrosphere.util.MathUtils; | ||||
| 
 | ||||
| public class ClientLoading { | ||||
| @ -188,6 +182,7 @@ public class ClientLoading { | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|          | ||||
|         /* | ||||
|         Targeting crosshair | ||||
|         */ | ||||
|  | ||||
| @ -2,7 +2,6 @@ package electrosphere.entity.types.terrain; | ||||
| 
 | ||||
| import org.joml.Vector3d; | ||||
| 
 | ||||
| import electrosphere.client.terrain.cells.DrawCell; | ||||
| import electrosphere.client.terrain.cells.VoxelTextureAtlas; | ||||
| import electrosphere.client.terrain.manager.ClientTerrainManager; | ||||
| import electrosphere.collision.PhysicsEntityUtils; | ||||
| @ -12,8 +11,6 @@ import electrosphere.entity.EntityCreationUtils; | ||||
| import electrosphere.entity.EntityDataStrings; | ||||
| import electrosphere.entity.ServerEntityUtils; | ||||
| import electrosphere.renderer.meshgen.TerrainChunkModelGeneration; | ||||
| import electrosphere.renderer.meshgen.TransvoxelModelGeneration; | ||||
| import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData; | ||||
| import electrosphere.server.datacell.Realm; | ||||
| 
 | ||||
| /** | ||||
| @ -24,23 +21,19 @@ public class TerrainChunk { | ||||
| 
 | ||||
|     /** | ||||
|      * Creates a client terrain chunk based on weights and values provided | ||||
|      * @param chunkData the chunk data to generate with | ||||
|      * @param weights The terrain weights | ||||
|      * @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 | ||||
|      * @return The terrain chunk entity | ||||
|      */ | ||||
|     public static Entity clientCreateTerrainChunkEntity(TransvoxelChunkData chunkData, int levelOfDetail, VoxelTextureAtlas atlas){ | ||||
|     public static Entity clientCreateTerrainChunkEntity(float[][][] weights, int[][][] values, int levelOfDetail, VoxelTextureAtlas atlas){ | ||||
|          | ||||
|         TerrainChunkData data; | ||||
|         if(levelOfDetail == DrawCell.FULL_DETAIL_LOD){ | ||||
|             data = TerrainChunkModelGeneration.generateTerrainChunkData(chunkData.terrainGrid, chunkData.textureGrid, levelOfDetail); | ||||
|         } else { | ||||
|             data = TransvoxelModelGeneration.generateTerrainChunkData(chunkData); | ||||
|         } | ||||
|         TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values); | ||||
|         String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas); | ||||
| 
 | ||||
|         Entity rVal = EntityCreationUtils.createClientSpatialEntity(); | ||||
|         EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath); | ||||
|         if(data.vertices.size() > 0 && levelOfDetail == DrawCell.FULL_DETAIL_LOD){ | ||||
|         if(data.vertices.size() > 0 && levelOfDetail < 1){ | ||||
|             PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data); | ||||
|         } | ||||
| 
 | ||||
| @ -60,7 +53,7 @@ public class TerrainChunk { | ||||
|      */ | ||||
|     public static Entity serverCreateTerrainChunkEntity(Realm realm, Vector3d position, float[][][] weights, int[][][] values){ | ||||
|          | ||||
|         TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values, DrawCell.FULL_DETAIL_LOD); | ||||
|         TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values); | ||||
| 
 | ||||
|         Entity rVal = EntityCreationUtils.createServerEntity(realm, position); | ||||
|         if(data.vertices.size() > 0){ | ||||
|  | ||||
| @ -52,9 +52,6 @@ public class MenuGeneratorsLevelEditor { | ||||
|     //is the voxel selection window open | ||||
|     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 | ||||
| @ -175,7 +172,7 @@ public class MenuGeneratorsLevelEditor { | ||||
|                 Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); | ||||
|                 Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); | ||||
|                 Realm realm = Globals.realmManager.getRealms().iterator().next(); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); | ||||
|                 CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, data.getCreatureId(), null); | ||||
|                 return false; | ||||
|             }})); | ||||
| @ -205,7 +202,7 @@ public class MenuGeneratorsLevelEditor { | ||||
|                 Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); | ||||
|                 Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); | ||||
|                 Realm realm = Globals.realmManager.getRealms().iterator().next(); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); | ||||
|                 FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, data.getName(), new Random().nextLong()); | ||||
|                 return false; | ||||
|             }})); | ||||
| @ -235,7 +232,7 @@ public class MenuGeneratorsLevelEditor { | ||||
|                 Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); | ||||
|                 Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); | ||||
|                 Realm realm = Globals.realmManager.getRealms().iterator().next(); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); | ||||
|                 ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId()); | ||||
|                 return false; | ||||
|             }})); | ||||
| @ -266,7 +263,7 @@ public class MenuGeneratorsLevelEditor { | ||||
|                 Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); | ||||
|                 Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); | ||||
|                 Realm realm = Globals.realmManager.getRealms().iterator().next(); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); | ||||
|                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); | ||||
|                 ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId()); | ||||
|                 return false; | ||||
|             }})); | ||||
|  | ||||
| @ -176,16 +176,6 @@ SYNCHRONIZATION_MESSAGE, | ||||
|                             rVal = TerrainMessage.parsesendChunkDataMessage(byteBuffer); | ||||
|                         } | ||||
|                         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: | ||||
|                         if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ | ||||
|                             rVal = TerrainMessage.parseRequestFluidDataMessage(byteBuffer); | ||||
|  | ||||
| @ -16,8 +16,6 @@ public class TerrainMessage extends NetworkMessage { | ||||
|         SPAWNPOSITION, | ||||
|         REQUESTCHUNKDATA, | ||||
|         SENDCHUNKDATA, | ||||
|         REQUESTREDUCEDCHUNKDATA, | ||||
|         SENDREDUCEDCHUNKDATA, | ||||
|         REQUESTFLUIDDATA, | ||||
|         SENDFLUIDDATA, | ||||
|         UPDATEFLUIDDATA, | ||||
| @ -42,7 +40,6 @@ public class TerrainMessage extends NetworkMessage { | ||||
|     double realLocationY; | ||||
|     double realLocationZ; | ||||
|     byte[] chunkData; | ||||
|     int chunkResolution; | ||||
|     float terrainWeight; | ||||
|     int terrainValue; | ||||
| 
 | ||||
| @ -199,14 +196,6 @@ public class TerrainMessage extends NetworkMessage { | ||||
|         this.chunkData = chunkData; | ||||
|     } | ||||
| 
 | ||||
|     public int getchunkResolution() { | ||||
|         return chunkResolution; | ||||
|     } | ||||
| 
 | ||||
|     public void setchunkResolution(int chunkResolution) { | ||||
|         this.chunkResolution = chunkResolution; | ||||
|     } | ||||
| 
 | ||||
|     public float getterrainWeight() { | ||||
|         return terrainWeight; | ||||
|     } | ||||
| @ -273,14 +262,6 @@ public class TerrainMessage extends NetworkMessage { | ||||
|                 } | ||||
|             case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA: | ||||
|                 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: | ||||
|                 if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE){ | ||||
|                     return true; | ||||
| @ -497,79 +478,6 @@ public class TerrainMessage extends NetworkMessage { | ||||
|         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){ | ||||
|         TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTFLUIDDATA); | ||||
|         stripPacketHeader(byteBuffer); | ||||
| @ -899,59 +807,6 @@ public class TerrainMessage extends NetworkMessage { | ||||
|                     rawBytes[18+i] = chunkData[i]; | ||||
|                 } | ||||
|                 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: | ||||
|                 rawBytes = new byte[2+4+4+4]; | ||||
|                 //message header | ||||
|  | ||||
| @ -69,11 +69,9 @@ Message categories | ||||
|     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_SENDCHUNKDATA = 7; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA = 8; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA = 9; | ||||
|     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; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 8; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 9; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 10; | ||||
|     /* | ||||
|     Terrain packet sizes | ||||
|     */ | ||||
| @ -84,7 +82,6 @@ Message categories | ||||
|     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_REQUESTCHUNKDATA_SIZE = 14; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA_SIZE = 18; | ||||
|     public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE = 14; | ||||
|     /* | ||||
|     Server subcategories | ||||
|  | ||||
| @ -1,18 +1,23 @@ | ||||
| package electrosphere.renderer.meshgen; | ||||
| 
 | ||||
| import java.nio.FloatBuffer; | ||||
| import java.nio.IntBuffer; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| 
 | ||||
| import org.joml.Matrix4f; | ||||
| import org.joml.Vector2f; | ||||
| import org.joml.Vector3f; | ||||
| import org.lwjgl.BufferUtils; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| import static org.lwjgl.opengl.GL30.glBindVertexArray; | ||||
| import static org.lwjgl.opengl.GL30.glGenVertexArrays; | ||||
| 
 | ||||
| import electrosphere.client.terrain.cells.VoxelTextureAtlas; | ||||
| import electrosphere.engine.Globals; | ||||
| @ -20,13 +25,14 @@ import electrosphere.entity.types.terrain.TerrainChunkData; | ||||
| import electrosphere.renderer.model.Material; | ||||
| import electrosphere.renderer.model.Mesh; | ||||
| import electrosphere.renderer.model.Model; | ||||
| import electrosphere.renderer.shader.ShaderProgram; | ||||
| import electrosphere.server.terrain.manager.ServerTerrainChunk; | ||||
| 
 | ||||
| public class TerrainChunkModelGeneration { | ||||
| 
 | ||||
|     //http://paulbourke.net/geometry/polygonise/ | ||||
| 
 | ||||
|     public static int edgeTable[]={ | ||||
|     static int edgeTable[]={ | ||||
|         0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, | ||||
|         0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, | ||||
|         0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, | ||||
| @ -62,7 +68,7 @@ public class TerrainChunkModelGeneration { | ||||
|     }; | ||||
| 
 | ||||
|     //256 by 16 | ||||
|     public static int triTable[][] = { | ||||
|     static int triTable[][] = { | ||||
|         {-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, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, | ||||
| @ -619,7 +625,7 @@ public class TerrainChunkModelGeneration { | ||||
|         return new Vector3f(x,y,z); | ||||
|     } | ||||
| 
 | ||||
|     public static TerrainChunkData generateTerrainChunkData(float[][][] terrainGrid, int[][][] textureGrid, int lod){ | ||||
|     public static TerrainChunkData generateTerrainChunkData(float[][][] terrainGrid, int[][][] textureGrid){ | ||||
| 
 | ||||
|         //            5             6 | ||||
|         //            +-------------+               +-----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 | ||||
|         //which doesnt work | ||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE0); | ||||
|         openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE1); | ||||
|         openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE2); | ||||
|         openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE3); | ||||
|         openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE0); | ||||
|          | ||||
|         openGLState.glDepthTest(false); | ||||
|  | ||||
| @ -40,7 +40,7 @@ public class VolumeBufferPipeline implements RenderPipeline { | ||||
|          | ||||
|         RenderingEngine.volumeDepthBackfaceFramebuffer.bind(); | ||||
|         GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT); | ||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE0); | ||||
|         GL40.glActiveTexture(GL40.GL_TEXTURE0); | ||||
| //            glBindTexture(GL_TEXTURE_2D, woodTexture); | ||||
| //            renderScene(simpleDepthShader); | ||||
| 
 | ||||
|  | ||||
| @ -7,12 +7,14 @@ import org.joml.Vector3i; | ||||
| import electrosphere.engine.Globals; | ||||
| import electrosphere.entity.Entity; | ||||
| import electrosphere.entity.EntityUtils; | ||||
| import electrosphere.entity.ServerEntityUtils; | ||||
| import electrosphere.entity.types.creature.CreatureUtils; | ||||
| import electrosphere.entity.types.item.ItemUtils; | ||||
| import electrosphere.server.content.serialization.ContentSerialization; | ||||
| import electrosphere.server.content.serialization.EntitySerialization; | ||||
| import electrosphere.server.datacell.Realm; | ||||
| import electrosphere.server.datacell.ServerDataCell; | ||||
| import electrosphere.server.pathfinding.NavMeshUtils; | ||||
| import electrosphere.server.saves.SaveUtils; | ||||
| import electrosphere.util.FileUtils; | ||||
| 
 | ||||
| @ -52,8 +54,7 @@ public class ServerContentManager { | ||||
|                 hydrateRawContent(realm,cell,contentRaw); | ||||
|             } else { | ||||
|                 //else create from scratch | ||||
|                 //UNCOMMENT THIS WHEN YOU WANT CONTENT GENERATED FOR WORLDS AGAIN | ||||
|                 // EnvironmentGenerator.generateForest(realm, cell, worldPos, 0); | ||||
|                 EnvironmentGenerator.generateForest(realm, cell, worldPos, 0); | ||||
|             } | ||||
|         } else { | ||||
|             //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