226 lines
7.7 KiB
C++
226 lines
7.7 KiB
C++
#pragma once
|
|
|
|
#include <queue>
|
|
#include <memory>
|
|
#include <glm/vec3.hpp>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
|
|
#include "util/Vec.h"
|
|
#include "MapGenProps.h"
|
|
#include "NoiseSample.h"
|
|
#include "util/Voronoi3D.h"
|
|
|
|
class World;
|
|
class Chunk;
|
|
class Subgame;
|
|
class BiomeDef;
|
|
class BiomeAtlas;
|
|
class DefinitionAtlas;
|
|
|
|
class MapGen {
|
|
public:
|
|
|
|
/** A type alias for the type the map of Chunks stored in the Job. */
|
|
typedef std::unordered_map<ivec3, sptr<Chunk>, Vec::ivec3> ChunkMap;
|
|
|
|
/**
|
|
* A struct representing a single position in a chunk at which sunlight should be updated at.
|
|
*/
|
|
|
|
struct SunlightNode {
|
|
SunlightNode(u16 index, Chunk* chunk) : index(index), chunk(chunk) {};
|
|
|
|
u16 index;
|
|
Chunk* chunk;
|
|
};
|
|
|
|
/**
|
|
* A struct containing all the information for a generation job.
|
|
* Contains a list of chunks, Noise samples, and the world position of the the job's root.
|
|
*/
|
|
|
|
struct Job {
|
|
|
|
/**
|
|
* Creates a new job with the root position and size specified, and initializes the NoiseSample params.
|
|
* @param pos - The root position of the job.
|
|
* @param size - The size in chunks of the job.
|
|
*/
|
|
|
|
Job(ivec3 pos, u16 size) :
|
|
pos(pos), size(size),
|
|
volume(u16vec3(size * 16, (size + 1) * 16, size * 16), 4),
|
|
heightmap(u16vec2(size * 16), 4),
|
|
|
|
temperature(u16vec2(size * 16), 4),
|
|
humidity(u16vec2(size * 16), 4),
|
|
roughness(u16vec2(size * 16), 4) {}
|
|
|
|
ivec3 pos {};
|
|
u16 size {};
|
|
|
|
uptr<ChunkMap> chunks = make_unique<ChunkMap>();
|
|
std::queue<SunlightNode> sunlightQueue {};
|
|
|
|
NoiseSample heightmap, volume;
|
|
NoiseSample temperature, humidity, roughness;
|
|
};
|
|
|
|
typedef array<f32, 4096> ChunkData;
|
|
|
|
MapGen(const MapGen& o) = delete;
|
|
|
|
/**
|
|
* Create a MapGen object with the seed and biomes provided.
|
|
*
|
|
* @param game - A reference to the subgame, for block and biome definitions.
|
|
* @param world - A reference to the world, for assigning the blocks to.
|
|
* @param seed - A seed to base the generation off of.
|
|
* @param biomes - A list of biome identifiers or tags to include in generation.
|
|
*/
|
|
|
|
MapGen(Subgame& game, World& world, u32 seed, std::unordered_set<string> biomes);
|
|
|
|
/**
|
|
* Generate a single chunk at the dimension and position provided.
|
|
* As with all generate* functions, this may result in extraneous chunk partials being created.
|
|
* This is the least efficient generation call and should be used only in extenuating circumstances.
|
|
*
|
|
* @param dim - The dimension to insert the finished chunk into.
|
|
* @param pos - The position in the dimension to generate the chunk.
|
|
* @returns a set of positions that were generated by this function call.
|
|
*/
|
|
|
|
[[maybe_unused]] uptr<ChunkMap> generateChunk(u16 dim, ivec3 pos);
|
|
|
|
/**
|
|
* Generate a mapblock at the dimension and position provided.
|
|
* As with all generate* functions, this may result in extraneous chunk partials being created.
|
|
* Commonly used by the ServerGenStream for regular chunk generation.
|
|
*
|
|
* @param dim - The dimension to insert the finished chunk into.
|
|
* @param pos - The position in the dimension to generate the chunk.
|
|
* @returns a set of positions that were generated by this function call.
|
|
*/
|
|
|
|
uptr<ChunkMap> generateMapBlock(u16 dim, ivec3 pos);
|
|
|
|
/**
|
|
* The underlying generate function called by both generateMapBlock and generateChunk.
|
|
* Can also be called on it's own to generate an arbitrary region of chunks.
|
|
* As with all generate* functions, this may result in extraneous chunk partials being created.
|
|
*
|
|
* @param dim - The dimension to insert the finished chunk into.
|
|
* @param pos - The position in the dimension to generate the chunk.
|
|
* @return - A set of positions that were generated by this function call.
|
|
*/
|
|
|
|
uptr<ChunkMap> generateArea(u16 dim, ivec3 origin, u16 size = 1);
|
|
|
|
private:
|
|
|
|
/**
|
|
* Get the closest biome to the provided environmental values from the Vonoroi map.
|
|
* Returns the index of the matched biome.
|
|
*
|
|
* @param temperature - The temperature value of the position to check.
|
|
* @param humidity - The humidity value of the position to check.
|
|
* @param roughness - The roughness value of the position to check.
|
|
* @returns the biome index of the environmentally closest biome.
|
|
*/
|
|
|
|
u16 getBiomeAt(f32 temperature, f32 humidity, f32 roughness);
|
|
|
|
/**
|
|
* Generate the Vonoroi biome map, using the biomes listed,
|
|
* according to their definition parameters.
|
|
*
|
|
* @param biomes - The biomes to add to the map.
|
|
*/
|
|
|
|
void generateVoronoi(const std::unordered_set<u16>& biomes);
|
|
|
|
/**
|
|
* Create a density array for a chunk using a generation Job and an offset within it.
|
|
* Returns a flattened array of block densities for every point in the chunk.
|
|
*
|
|
* @param job - The Job to pull the data from.
|
|
* @param localPos - The offset of the chunk's data within the job.
|
|
* @returns a ChunkData array containing the chunk's density.
|
|
*/
|
|
|
|
static uptr<ChunkData> populateChunkDensity(Job& job, ivec3 localPos);
|
|
|
|
/**
|
|
* Create a depth array for a chunk using a generation Job and the chunk densities around it.
|
|
* Returns a flattened array of block depths for every point in the chunk.
|
|
*
|
|
* @param chunkDensity - A density array of the current chunk.
|
|
* @param chunkDensityAbove - A density array of the chunk above it.
|
|
* @returns a ChunkData array containing the chunk's depth.
|
|
*/
|
|
|
|
static uptr<ChunkData> populateChunkDepth(uptr<ChunkData>& chunkDensity, uptr<ChunkData> chunkDensityAbove);
|
|
|
|
/**
|
|
* Generates a chunk's blocks from a generation Job and an offset within it, and inserts it into the Job.
|
|
* Combines with any partials that have been previously created at that position within job.
|
|
*
|
|
* Declares the chunk generated, and counts renderable blocks within it. Though later functions manipulate
|
|
* chunk data, they do so using the chunk setBlock method, making it safe to count at this stage.
|
|
*
|
|
* @param job - The Job to pull the data from.
|
|
* @param localPos - The offset of the chunk within the job.
|
|
* @param biomeMap - The two-dimensional biome array of the entire generation area.
|
|
* @param depthMap - The depth map of the chunk being generated.
|
|
*/
|
|
|
|
void generateChunkBlocks(Job& job, ivec3 localPos, vec<u16> biomeMap, ChunkData& depthMap);
|
|
|
|
/**
|
|
* Generates structures for a Chunk based on data within the generation job and an offset within it.
|
|
* Also generates initial light cascade, which will later be refined by propogateSunlightNodes.
|
|
* May create chunk partials, inserting them back into the Job for later completion.
|
|
*
|
|
* @param job - The job to pull the data from.
|
|
* @param localPos - The offset of the chunk within the job.
|
|
* @param biomeMap - The two-dimensional biome array of the entire generation area.
|
|
* @param depthMap - The depth map of the chunk being generated.
|
|
*/
|
|
|
|
void generateChunkDecorAndLight(Job& job, ivec3 localPos, vec<u16> biomeMap, ChunkData& depthMap);
|
|
|
|
/**
|
|
* Sets a block at the position specified into the Job, if the block at said position is not filled by
|
|
* a material greater than air. If a chunk does not exist at the specified position, a partial is generated
|
|
* into the chunk map, and the block is assigned on there.
|
|
*
|
|
* @param job - The job to pull the data from.
|
|
* @param worldPos - The world position to set the block at.
|
|
* @param block - The block to set.
|
|
* @param hint - An optional parameter that may speed up the function if set to the chunk to set to.
|
|
*/
|
|
|
|
static void setBlock(Job& job, ivec3 worldPos, u16 block, sptr<Chunk> hint);
|
|
|
|
/**
|
|
* Calculates and smooths sunlight for an entire Job's chunks.
|
|
*
|
|
* @param job - The job to act upon.
|
|
*/
|
|
|
|
void propogateSunlightNodes(Job& job);
|
|
|
|
u32 seed = 0;
|
|
MapGenProps props;
|
|
|
|
constexpr const static u16 voronoiSize = 64;
|
|
Voronoi3D voronoi { voronoiSize };
|
|
|
|
FastNoise::SmartNode<> biomeGenerator;
|
|
|
|
Subgame& game;
|
|
World& world;
|
|
};
|