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