A voxel engine for godot, focusing more on editor integration, gameplay-related features, and extendability (even from gdscript), without sacrificing too much speed.
This is an engine module! Which means that you will need to compile it into Godot! [See the compiling section here.](#compiling)
You can find a demonstration project (with pre-built binaries) here: https://github.com/Relintai/the_tower
## Godot Version Support
I'm currently mostly using [Terraman](https://github.com/Relintai/terraman) instead of this, so it might get temporarily a bit behind.\
If compile breaks, and I don't notice please report.
3.2 - Will likely work, probably needs changes by now. (TODO check.)\
3.3 - Will more likely work, might need smaller changes by now. (TODO check.)\
3.4 - Should work without any issues. (TODO check.)\
4.0 - Have been fixing support from time to time. Currently it won't build. Mostly done with the fix though.
## Optional Dependencies
`https://github.com/Relintai/texture_packer`: You get access to [VoxelLibraryMerger](#voxellibrarymerger) and [VoxelLibraryMergerPCM](#voxellibrarymergerpcm). \
`https://github.com/Relintai/mesh_data_resource`: You get access to a bunch of properties, and methods that can manipulate meshes.\
`https://github.com/Relintai/props`: You get access to a bunch of properties, and methods that can manipulate, and use props.\
`https://github.com/Relintai/mesh_utils`: Lets you use lod levels higher than 4 by default.
## Usage
First create a scene, and add a VoxelWorldBlocky / VoxelWorldMarchingCubes node into it. Create a VoxelLibrary, and assign it to the Library property.
Also, add a VoxelSurface into your library.
Tick the editable property, deselect, then select the world again, and click the insert button at the top toolbar, or press B to insert a
voxel at the inspector's camera's location.
Select the add button, and now you can just add voxels with the mouse, by clicking on the newly added voxel.
## VoxelLibrary
This class stores the materials, and the VoxelSurfaces.
Lod levels will automatically try to use materials of their own index.\
For example lod level 1 will try to use material index 1, lod level 2 will try to use material index 2, etc.\
If a material index is not available, they'll use the highest that is.\
For example lod level 5 will try to get material index 5, but if you only have 3 materials it will use the 3rd.
### VoxelLibrarySimple
The simplest library, just assign a material with a texture, and using the atlas_rows and atlas_culomns properties to tell the system
You will only have this if your godot also contains https://github.com/Relintai/texture_packer
You can assign any texture to your surfaces with this, and it will merge them together.
### VoxelLibraryMergerPCM
(PCM = Per Chunk Material)
You will only have this if your godot also contains https://github.com/Relintai/texture_packer
You can assign any texture to your surfaces with this, and it will merge them together, but it will do it for every required chunk/voxel combination.
For example if you have a chunk with voxel Grass, and voxel Stone used in it, this library will create a material with a merged texture for Stone and Grass.
If you have an anouther chunk which only has Grass and Stone in it, this material will be reused.
And if you have a third chunk which only has a Grass voxel used in it, it will get a new merged material and texture only containing Grass voxel.
## Worlds
The 2 base classes. These won't do meshing on their own:
VoxelWorld: Basic world, does not do anything until you implemnent the required virtual methods!\
VoxelWorldDefault: This adds threading, and LoD storage support to VoxelWorld. Will not create meshes for you!
### VoxelWorldBlocky
The most basic world. It is the Minecraft-style world.
### VoxelWorldMarchingCubes
A marching cubes based Voxel World. Actually it uses a modified version of the Transvoxel tables, because it is UV mapped.
### VoxelWorldCubic
This is my own meshing algorithm, it's basicly a Minecraft style mesher that can take isolevel into account.
It's kind of a pain to use, it might get removed.
### Level generation
Assign a VoxelManLevelGenerator to the `World`'s `Level Generator` property.
You can write your own algorithm by implementing the ``` void _generate_chunk(chunk: VoxelChunk) virtual ``` method.
`VoxelManLevelGeneratorFlat` is also available, it will generate a floor for you, if you use it.
## VoxelJobs
Producing just a terrain mesh for a chunk is not that hard by itself. However when you start adding layers/features
vertex lights, props, snapping props, props with vertex lights, etc
chunk mesh generation can quicly become a serious mess.
VoxelJobs are meant to solve the issue with less complexity.
They also provide a way to easily modularize mesh and lod generation.
### VoxelJob
Base class for jobs.
If the [thread pool](https://github.com/Relintai/thread_pool) module is present, this is inherited from `ThreadPoolJob`,
else it implements the same api as `ThreadPoolJob`, but it's not going to use threading.
A job has a reference to it's owner chunk.
If you implement your own jobs, when your job finishes call `next_job()`.
### VoxelLightJob
This is the job that will generate vertex light based ao, random ao, and will bake your `VoxelLight`s.
### VoxelTerrainJob
This will generate your terrain collider and mesh (with lods) for you, using the meshers that you add into it.
Your lod setup is easily customizable with [VoxelMesherJobSteps](https://github.com/Relintai/voxelman/blob/master/world/jobs/voxel_mesher_job_step.h). The setup happens in your selected world's `_create_chunk` method.
### VoxelPropJob
This will generate your prop meshes (with lods).
Also supports [VoxelMesherJobSteps](https://github.com/Relintai/voxelman/blob/master/world/jobs/voxel_mesher_job_step.h).
### Internal workings
#### VoxelWorld
Whenever you want to spawn a chunk your World will create it using the ``` VoxelChunk _create_chunk(x: int, y: int, z: int, chunk: VoxelChunk) virtual ``` method.
Since properly initializing a chunk usually takes quite a few steps that you probably don't want to repeat everywhere the `chunk`
parameter was added. This means you can just call the super `_create_chunk` methods, and you won't need to worry about your chunk
You can look at the world implementations for more examples: [VoxelWorldBlocky](https://github.com/Relintai/voxelman/blob/master/world/blocky/voxel_world_blocky.cpp), [VoxelWorldMarchingCubes](https://github.com/Relintai/voxelman/blob/master/world/marching_cubes/voxel_world_marching_cubes.cpp).
#### VoxelChunk
Stores terrain data, prop data. And mesh data (VoxelChunkDefault), and the mesh generation jobs.