Compare commits
	
		
			No commits in common. "8dcff7efe00de17bcee633ccfe0ec5205b7b4885" and "2b715ab3254e2b7f907fdd5f3b08427bd9dbdbcd" have entirely different histories.
		
	
	
		
			8dcff7efe0
			...
			2b715ab325
		
	
		
| @ -1,3 +1,3 @@ | |||||||
| #maven.buildNumber.plugin properties file | #maven.buildNumber.plugin properties file | ||||||
| #Wed Jun 19 19:19:09 EDT 2024 | #Fri Jun 14 13:45:11 EDT 2024 | ||||||
| buildNumber=138 | buildNumber=137 | ||||||
|  | |||||||
| @ -10,7 +10,6 @@ | |||||||
| - @subpage archimprovementtargets | - @subpage archimprovementtargets | ||||||
| - @subpage savesindex | - @subpage savesindex | ||||||
| - @subpage hitboxesindex | - @subpage hitboxesindex | ||||||
| - @subpage drawcell |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # What is this section | # 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] | [TOC] | ||||||
|  - @subpage whatmakesaquestgood |  - @subpage whatmakesaquestgood | ||||||
|  - @subpage narrativearcdesign |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| TODO: describe | 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 | @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 | ||||||
| @ -13,8 +8,6 @@ TODO(?): | |||||||
| 
 | 
 | ||||||
|  - Transvoxel Algorithm |  - Transvoxel Algorithm | ||||||
| 
 | 
 | ||||||
|  - Building cube voxels w/ LOD |  | ||||||
| 
 |  | ||||||
|  - Deferred Shading Pipeline |  - Deferred Shading Pipeline | ||||||
| 
 | 
 | ||||||
|  - Audio Ray Tracing |  - Audio Ray Tracing | ||||||
| @ -24,7 +17,3 @@ TODO(?): | |||||||
|  - 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,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 |   - 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 | ||||||
| @ -401,6 +385,7 @@ 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 | ||||||
| @ -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: | 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 | ||||||
| 
 | 
 | ||||||
| @ -492,6 +457,22 @@ Shader library system | |||||||
| 
 | 
 | ||||||
| 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 | ||||||
| 
 | 
 | ||||||
| @ -599,6 +580,9 @@ 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' | ||||||
|  | |||||||
| @ -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" |                     "type" : "BYTE_ARRAY" | ||||||
|                 }, |                 }, | ||||||
| 
 | 
 | ||||||
|                 { |  | ||||||
|                     "name" : "chunkResolution", |  | ||||||
|                     "type" : "FIXED_INT" |  | ||||||
|                 }, |  | ||||||
| 
 |  | ||||||
|                 { |                 { | ||||||
|                     "name" : "terrainWeight", |                     "name" : "terrainWeight", | ||||||
|                     "type" : "FIXED_FLOAT" |                     "type" : "FIXED_FLOAT" | ||||||
| @ -191,27 +186,6 @@ | |||||||
|                         "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,47 +11,39 @@ 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.meshgen.TransvoxelModelGeneration.TransvoxelChunkData; | import electrosphere.renderer.shader.ShaderProgram; | ||||||
| import electrosphere.server.terrain.manager.ServerTerrainChunk; | 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 { | 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]; | ||||||
|      |      | ||||||
|  |     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 |     static { | ||||||
|     public static final int FULL_DETAIL_LOD = 0; | //        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(){ |     DrawCell(){ | ||||||
|          |          | ||||||
|     } |     } | ||||||
| @ -71,23 +63,18 @@ public class DrawCell { | |||||||
|     /** |     /** | ||||||
|      * Generates a drawable entity based on this chunk |      * 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){ |         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, | ||||||
| @ -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 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 { | ||||||
|      |      | ||||||
| @ -52,46 +27,45 @@ 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 = new HashSet<DrawCell>(); |     Set<DrawCell> cells; | ||||||
|     Map<String,DrawCell> keyCellMap = new HashMap<String,DrawCell>(); |     Map<String,DrawCell> keyCellMap = new HashMap<String,DrawCell>(); | ||||||
|      |     Set<String> hasNotRequested; | ||||||
|     //status of all position keys |     Set<String> hasRequested; | ||||||
|     Set<String> hasNotRequested = new HashSet<String>(); |     Set<String> drawable; | ||||||
|     Set<String> requested = new HashSet<String>(); |     Set<String> undrawable; | ||||||
|     Set<String> drawable = new HashSet<String>(); |     Set<String> updateable; | ||||||
|     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; | ||||||
|      |      | ||||||
|      |      | ||||||
|      |      | ||||||
|     //the real-space radius for which we will construct draw cells inside of |     // int drawRadius = 5; | ||||||
|     //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 drawStepdownInterval = 3; | ||||||
|     double drawFullModelRadius = 50; |     int drawStepdownValue = 25; | ||||||
| 
 | 
 | ||||||
|     //the radius we'll draw LODed chunks for |     double drawRadius = 50; | ||||||
|     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; | ||||||
| 
 | 
 | ||||||
| @ -108,22 +82,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 |         // drawRadius = Globals.userSettings.getGraphicsPerformanceLODChunkRadius(); | ||||||
|         lodLevelRadiusTable[0] = drawFullModelRadius; |         drawStepdownInterval = Globals.userSettings.getGameplayPhysicsCellRadius(); | ||||||
|         //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; |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         physicsRadius = Globals.userSettings.getGameplayPhysicsCellRadius(); |         physicsRadius = Globals.userSettings.getGameplayPhysicsCellRadius(); | ||||||
|          |          | ||||||
|         invalidateAllCells(); |         invalidateAllCells(); | ||||||
| @ -131,41 +105,29 @@ 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; | ||||||
|             //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 currentCellY = cellY - drawRadius + vector.y; | ||||||
|             //The following loop-hell does this |             // int currentCellZ = cellZ - drawRadius + vector.z; | ||||||
|             // |  | ||||||
|             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() && | ||||||
| @ -175,20 +137,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(!requested.contains(requestKey)){ |                             // if(!hasRequested.contains(targetKey)){ | ||||||
|                                 //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); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
| @ -196,12 +158,10 @@ 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++){ | ||||||
| @ -215,28 +175,25 @@ 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); | ||||||
|                 DrawCellFace higherLODFace = null; |                 // undrawable.add(targetKey); | ||||||
|                 keyCellMap.get(targetKey).generateDrawableEntity(atlas,0,higherLODFace); |                 undrawable.remove(targetKey); | ||||||
|                  |                 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); | ||||||
|             } |             } | ||||||
| @ -259,49 +216,37 @@ 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(); | ||||||
|                 DrawCellFace higherLODFace = null; |                 keyCellMap.get(targetKey).generateDrawableEntity(atlas); | ||||||
|                 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()); | ||||||
|     } |     } | ||||||
| @ -333,7 +278,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) > drawFullModelRadius){ |             if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(realPos) > drawRadius){ | ||||||
|                 cellsToRemove.add(cell); |                 cellsToRemove.add(cell); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -345,7 +290,7 @@ public class DrawCellManager { | |||||||
|             undrawable.remove(key); |             undrawable.remove(key); | ||||||
|             updateable.remove(key); |             updateable.remove(key); | ||||||
|             keyCellMap.remove(key); |             keyCellMap.remove(key); | ||||||
|             requested.remove(key); |             hasRequested.remove(key); | ||||||
|             cell.destroy(); |             cell.destroy(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -356,9 +301,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)drawFullModelRadius; x < drawFullModelRadius; x = x + ChunkData.CHUNK_SIZE){ |             for(int x = -(int)drawRadius; x < drawRadius; x = x + ChunkData.CHUNK_SIZE){ | ||||||
|                 for(int y = -(int)drawFullModelRadius; y < drawFullModelRadius; y = y + ChunkData.CHUNK_SIZE){ |                 for(int y = -(int)drawRadius; y < drawRadius; y = y + ChunkData.CHUNK_SIZE){ | ||||||
|                     for(int z = -(int)drawFullModelRadius; z < drawFullModelRadius; z = z + 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); |                         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), | ||||||
| @ -371,7 +316,7 @@ public class DrawCellManager { | |||||||
|                             Globals.clientWorldData.convertChunkToRealSpace(worldPos.z) |                             Globals.clientWorldData.convertChunkToRealSpace(worldPos.z) | ||||||
|                         ); |                         ); | ||||||
|                         if( |                         if( | ||||||
|                             playerPos.distance(chunkRealSpace) < drawFullModelRadius && |                             playerPos.distance(chunkRealSpace) < drawRadius && | ||||||
|                             worldPos.x >= 0 && |                             worldPos.x >= 0 && | ||||||
|                             worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && |                             worldPos.x < Globals.clientWorldData.getWorldDiscreteSize() && | ||||||
|                             worldPos.y >= 0 && |                             worldPos.y >= 0 && | ||||||
| @ -385,7 +330,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) && | ||||||
|                             !requested.contains(key)){ |                             !hasRequested.contains(key)){ | ||||||
|                                 hasNotRequested.add(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) |      * Splits a cell key into its constituent coordinates in array format. | ||||||
|      * @param generate true to generate graphics, false otherwise |      * @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){ |     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); | ||||||
| @ -476,11 +428,11 @@ public class DrawCellManager { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Gets the radius within which full-detail models are drawn |      * Gets the draw radius | ||||||
|      * @return the radius |      * @return the draw radius | ||||||
|      */ |      */ | ||||||
|     public double getDrawFullModelRadius(){ |     public double getDrawRadius(){ | ||||||
|         return drawFullModelRadius; |         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 |      * @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.containsKey(voxelTypeId) ? typeCoordMap.get(voxelTypeId) : -1; |         return typeCoordMap.get(voxelTypeId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| 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,6 +6,7 @@ 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; | ||||||
| 
 | 
 | ||||||
| @ -35,7 +36,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 = 500; |     static final int CACHE_SIZE = 50; | ||||||
|      |      | ||||||
|     //used for caching the macro values |     //used for caching the macro values | ||||||
|     ClientTerrainCache terrainCache; |     ClientTerrainCache terrainCache; | ||||||
| @ -54,9 +55,6 @@ 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){ | ||||||
| @ -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){ |     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,7 +6,6 @@ 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; | ||||||
| @ -16,9 +15,7 @@ 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; | ||||||
| @ -31,7 +28,6 @@ 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; | ||||||
| @ -40,10 +36,8 @@ 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 { | ||||||
| @ -188,6 +182,7 @@ public class ClientLoading { | |||||||
|         } |         } | ||||||
|          |          | ||||||
| 
 | 
 | ||||||
|  |          | ||||||
|         /* |         /* | ||||||
|         Targeting crosshair |         Targeting crosshair | ||||||
|         */ |         */ | ||||||
|  | |||||||
| @ -2,7 +2,6 @@ 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; | ||||||
| @ -12,8 +11,6 @@ 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; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -24,23 +21,19 @@ 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 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 |      * @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(TransvoxelChunkData chunkData, int levelOfDetail, VoxelTextureAtlas atlas){ |     public static Entity clientCreateTerrainChunkEntity(float[][][] weights, int[][][] values, int levelOfDetail, VoxelTextureAtlas atlas){ | ||||||
|          |          | ||||||
|         TerrainChunkData data; |         TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values); | ||||||
|         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 == DrawCell.FULL_DETAIL_LOD){ |         if(data.vertices.size() > 0 && levelOfDetail < 1){ | ||||||
|             PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data); |             PhysicsEntityUtils.clientAttachTerrainChunkRigidBody(rVal, data); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -60,7 +53,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, DrawCell.FULL_DETAIL_LOD); |         TerrainChunkData data = TerrainChunkModelGeneration.generateTerrainChunkData(weights, values); | ||||||
| 
 | 
 | ||||||
|         Entity rVal = EntityCreationUtils.createServerEntity(realm, position); |         Entity rVal = EntityCreationUtils.createServerEntity(realm, position); | ||||||
|         if(data.vertices.size() > 0){ |         if(data.vertices.size() > 0){ | ||||||
|  | |||||||
| @ -52,9 +52,6 @@ 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 | ||||||
| @ -175,7 +172,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).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); |                 CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, data.getCreatureId(), null); | ||||||
|                 return false; |                 return false; | ||||||
|             }})); |             }})); | ||||||
| @ -205,7 +202,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).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()); |                 FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, data.getName(), new Random().nextLong()); | ||||||
|                 return false; |                 return false; | ||||||
|             }})); |             }})); | ||||||
| @ -235,7 +232,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).add(cursorVerticalOffset); |                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); | ||||||
|                 ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId()); |                 ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId()); | ||||||
|                 return false; |                 return false; | ||||||
|             }})); |             }})); | ||||||
| @ -266,7 +263,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).add(cursorVerticalOffset); |                 Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); | ||||||
|                 ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId()); |                 ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId()); | ||||||
|                 return false; |                 return false; | ||||||
|             }})); |             }})); | ||||||
|  | |||||||
| @ -176,16 +176,6 @@ 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,8 +16,6 @@ public class TerrainMessage extends NetworkMessage { | |||||||
|         SPAWNPOSITION, |         SPAWNPOSITION, | ||||||
|         REQUESTCHUNKDATA, |         REQUESTCHUNKDATA, | ||||||
|         SENDCHUNKDATA, |         SENDCHUNKDATA, | ||||||
|         REQUESTREDUCEDCHUNKDATA, |  | ||||||
|         SENDREDUCEDCHUNKDATA, |  | ||||||
|         REQUESTFLUIDDATA, |         REQUESTFLUIDDATA, | ||||||
|         SENDFLUIDDATA, |         SENDFLUIDDATA, | ||||||
|         UPDATEFLUIDDATA, |         UPDATEFLUIDDATA, | ||||||
| @ -42,7 +40,6 @@ 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; | ||||||
| 
 | 
 | ||||||
| @ -199,14 +196,6 @@ 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; | ||||||
|     } |     } | ||||||
| @ -273,14 +262,6 @@ 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; | ||||||
| @ -497,79 +478,6 @@ 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); | ||||||
| @ -899,59 +807,6 @@ 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,11 +69,9 @@ 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_REQUESTREDUCEDCHUNKDATA = 8; |     public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 8; | ||||||
|     public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA = 9; |     public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 9; | ||||||
|     public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 10; |     public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 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 | ||||||
|     */ |     */ | ||||||
| @ -84,7 +82,6 @@ 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,18 +1,23 @@ | |||||||
| 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; | ||||||
| @ -20,13 +25,14 @@ 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/ | ||||||
| 
 | 
 | ||||||
|     public static int edgeTable[]={ |     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, | ||||||
| @ -62,7 +68,7 @@ public class TerrainChunkModelGeneration { | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     //256 by 16 |     //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}, |         {-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}, | ||||||
| @ -619,7 +625,7 @@ public class TerrainChunkModelGeneration { | |||||||
|         return new Vector3f(x,y,z); |         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             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); | ||||||
|         openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); |         GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE1); |         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.glActiveTexture(GL40.GL_TEXTURE2); | ||||||
|         openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0); |         GL40.glBindTexture(GL40.GL_TEXTURE_2D, 0); | ||||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE3); |         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.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); | ||||||
|         openGLState.glActiveTexture(GL40.GL_TEXTURE0); |         GL40.glActiveTexture(GL40.GL_TEXTURE0); | ||||||
| //            glBindTexture(GL_TEXTURE_2D, woodTexture); | //            glBindTexture(GL_TEXTURE_2D, woodTexture); | ||||||
| //            renderScene(simpleDepthShader); | //            renderScene(simpleDepthShader); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,12 +7,14 @@ 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; | ||||||
| 
 | 
 | ||||||
| @ -52,8 +54,7 @@ public class ServerContentManager { | |||||||
|                 hydrateRawContent(realm,cell,contentRaw); |                 hydrateRawContent(realm,cell,contentRaw); | ||||||
|             } else { |             } else { | ||||||
|                 //else create from scratch |                 //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 { |         } 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