Add biome color computation

Rather than using fixed values for all biomes, generate grass and foliage
colors based on (height-dependent) temperature and rainfall parameters.

This changes a lot of colors; in general, the new colors should be closer
to the actual Minecraft rendering. It also fixes a few colors that were
completely off (like in the badlands biomes) and adds the MC 1.13 biomes
(which were rendered in black).

Some of the newer biomes (warm/cold/... oceans) don't have proper
parameters yet, and we do not derive the water color from the biome yet.

Fixes #1.
This commit is contained in:
Matthias Schiffer 2018-11-08 17:12:40 +01:00
parent 4ffa28dd63
commit 0bdf249307
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
7 changed files with 382 additions and 219 deletions

View file

@ -10,7 +10,6 @@ add_executable(MinedMap
NBT/Tag.cpp NBT/Tag.cpp
Resource/Biome.cpp Resource/Biome.cpp
Resource/BlockType.cpp Resource/BlockType.cpp
World/Block.cpp
World/Chunk.cpp World/Chunk.cpp
World/ChunkData.cpp World/ChunkData.cpp
World/Level.cpp World/Level.cpp

View file

@ -51,7 +51,7 @@ namespace MinedMap {
static const size_t DIM = World::Region::SIZE*World::Chunk::SIZE; static const size_t DIM = World::Region::SIZE*World::Chunk::SIZE;
static void addChunk(World::Block::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) { static void addChunk(Resource::Color image[DIM*DIM], uint8_t lightmap[2*DIM*DIM], size_t X, size_t Z, const World::ChunkData *data) {
World::Chunk chunk(data); World::Chunk chunk(data);
World::Chunk::Blocks layer = chunk.getTopLayer(); World::Chunk::Blocks layer = chunk.getTopLayer();
@ -137,7 +137,7 @@ static void doRegion(const std::string &input, const std::string &output, const
std::printf("Generating %s from %s...\n", output.c_str(), input.c_str()); std::printf("Generating %s from %s...\n", output.c_str(), input.c_str());
try { try {
std::unique_ptr<World::Block::Color[]> image(new World::Block::Color[DIM*DIM]); std::unique_ptr<Resource::Color[]> image(new Resource::Color[DIM*DIM]);
std::memset(image.get(), 0, 4*DIM*DIM); std::memset(image.get(), 0, 4*DIM*DIM);
std::unique_ptr<uint8_t[]> lightmap(new uint8_t[2*DIM*DIM]); std::unique_ptr<uint8_t[]> lightmap(new uint8_t[2*DIM*DIM]);

View file

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net> Copyright (c) 2015, 2018, Matthias Schiffer <mschiffer@universe-factory.net>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -26,179 +26,344 @@
#include "Biome.hpp" #include "Biome.hpp"
#include "BlockType.hpp"
#include "../Util.hpp"
namespace MinedMap { namespace MinedMap {
namespace Resource { namespace Resource {
const Biome BIOMES[256] = { static Biome::FloatColor operator+(const Biome::FloatColor &a, const Biome::FloatColor &b){
/* 0 */ {0.25, 1, 0.25}, return Biome::FloatColor {
/* 1 */ {0.3, 1, 0.3}, a.r+b.r,
/* 2 */ {1, 1, 0.25}, a.g+b.g,
/* 3 */ {0.3, 0.9, 0.3}, a.b+b.b,
/* 4 */ {0.15, 0.75, 0.15}, };
/* 5 */ {0.5, 0.75, 0.5}, }
/* 6 */ {0.75, 1, 0.25},
/* 7 */ {0.25, 1, 0.25}, static Biome::FloatColor & operator*=(Biome::FloatColor &a, const Biome::FloatColor &b) {
/* 8 */ {1, 0.1, 0.1}, a.r *= b.r;
/* 9 */ {1.5, 1.5, 0.75}, a.g *= b.g;
/* 10 */ {0.25, 1, 0.25}, a.b *= b.b;
/* 11 */ {0.25, 1, 0.25},
/* 12 */ {0.3, 1, 0.3}, return a;
/* 13 */ {0.3, 0.9, 0.3}, }
/* 14 */ {0.75, 0.1, 0.75},
/* 15 */ {0.75, 0.1, 0.75}, static Biome::FloatColor operator*(float s, const Biome::FloatColor &c) {
/* 16 */ {1, 1, 0.25}, return Biome::FloatColor {
/* 17 */ {1, 1, 0.25}, s*c.r,
/* 18 */ {0.15, 0.75, 0.15}, s*c.g,
/* 19 */ {0.5, 0.75, 0.5}, s*c.b,
/* 20 */ {0.3, 0.9, 0.3}, };
/* 21 */ {0.1, 1.25, 0.1}, }
/* 22 */ {0.1, 1.25, 0.1},
/* 23 */ {0.1, 1.25, 0.1}, static Biome::FloatColor colorFromParams(float temp, float rain, bool grass) {
/* 24 */ {0.25, 1, 0.25}, const Biome::FloatColor grassColors[3] = {
/* 25 */ {1, 1, 0.25}, {0.502f, 0.706f, 0.592f}, // lower right
/* 26 */ {1, 1, 0.25}, {0.247f, 0.012f, -0.259f}, // lower left - lower right
/* 27 */ {0.15, 0.75, 0.15}, {-0.471f, 0.086f, -0.133f}, // upper left - lower left
/* 28 */ {0.15, 0.75, 0.15}, };
/* 29 */ {0.15, 0.75, 0.15}, const Biome::FloatColor foliageColors[3] = {
/* 30 */ {0.5, 0.75, 0.5}, {0.376f, 0.631f, 0.482f}, // lower right
/* 31 */ {0.5, 0.75, 0.5}, {0.306f, 0.012f, -0.317f}, // lower left - lower right
/* 32 */ {0.5, 0.75, 0.5}, {-0.580f, 0.106f, -0.165f}, // upper left - lower left
/* 33 */ {0.5, 0.75, 0.5}, };
/* 34 */ {0.3, 0.9, 0.3},
/* 35 */ {0.6, 1, 0.25}, const Biome::FloatColor *colors = grass ? grassColors : foliageColors;
/* 36 */ {0.6, 1, 0.25},
/* 37 */ {0.25, 1, 1.25}, return colors[0] + temp*colors[1] + rain*colors[2];
/* 38 */ {0.25, 1, 1.25}, }
/* 39 */ {0.25, 1, 1.25},
/* 40 */ {},
/* 41 */ {}, Biome::FloatColor Biome::getGrassColor(float temp, float rain) const {
/* 42 */ {}, return colorFromParams(temp, rain, true);
/* 43 */ {}, }
/* 44 */ {},
/* 45 */ {}, Biome::FloatColor Biome::getFoliageColor(float temp, float rain) const {
/* 46 */ {}, return colorFromParams(temp, rain, false);
/* 47 */ {}, }
/* 48 */ {},
/* 49 */ {}, Biome::FloatColor Biome::getWaterColor(float, float) const {
/* 50 */ {}, return {0.161f, 0.365f, 0.996f};
/* 51 */ {}, }
/* 52 */ {},
/* 53 */ {},
/* 54 */ {}, Color Biome::getBlockColor(const BlockType *type, unsigned height) const {
/* 55 */ {}, Biome::FloatColor c = {
/* 56 */ {}, float(type->color.r),
/* 57 */ {}, float(type->color.g),
/* 58 */ {}, float(type->color.b),
/* 59 */ {}, };
/* 60 */ {},
/* 61 */ {}, float t = clamp(temp - std::max(0.0f, (height-64)/600.0f), 0, 1);
/* 62 */ {}, float r = clamp(rain, 0, 1) * t;
/* 63 */ {},
/* 64 */ {}, if (type->grass)
/* 65 */ {}, c *= getGrassColor(t, r);
/* 66 */ {}, if (type->foliage)
/* 67 */ {}, c *= getFoliageColor(t, r);
/* 68 */ {}, if (type->blue)
/* 69 */ {}, c *= getWaterColor(t, r);
/* 70 */ {},
/* 71 */ {}, float h = 0.5f + height * 0.005f;
/* 72 */ {},
/* 73 */ {}, return Color {
/* 74 */ {}, uint8_t(clamp(c.r * h, 0, 255)),
/* 75 */ {}, uint8_t(clamp(c.g * h, 0, 255)),
/* 76 */ {}, uint8_t(clamp(c.b * h, 0, 255)),
/* 77 */ {}, 0xff,
/* 78 */ {}, };
/* 79 */ {}, }
/* 80 */ {},
/* 81 */ {},
/* 82 */ {}, class SwampBiome : public Biome {
/* 83 */ {}, protected:
/* 84 */ {}, virtual FloatColor getGrassColor(float, float) const {
/* 85 */ {}, return {0.417f, 0.439f, 0.224f};
/* 86 */ {}, }
/* 87 */ {}, virtual FloatColor getFoliageColor(float temp, float rain) const {
/* 88 */ {}, return getGrassColor(temp, rain);
/* 89 */ {}, }
/* 90 */ {}, virtual FloatColor getWaterColor(float, float) const {
/* 91 */ {}, return {0.141f, 0.365f, 0.680f};
/* 92 */ {}, }
/* 93 */ {},
/* 94 */ {}, public:
/* 95 */ {}, SwampBiome(float temp0, float rain0) : Biome(temp0, rain0) {}
/* 96 */ {}, };
/* 97 */ {},
/* 98 */ {}, class DarkForestBiome : public Biome {
/* 99 */ {}, private:
/* 100 */ {}, const FloatColor darkGreen = {0.157f, 0.204f, 0.039f};
/* 101 */ {},
/* 102 */ {}, protected:
/* 103 */ {}, virtual FloatColor getGrassColor(float temp, float rain) const {
/* 104 */ {}, return 0.5 * (darkGreen + colorFromParams(temp, rain, true));
/* 105 */ {}, }
/* 106 */ {},
/* 107 */ {}, virtual FloatColor getFoliageColor(float temp, float rain) const {
/* 108 */ {}, return 0.5 * (darkGreen + colorFromParams(temp, rain, false));
/* 109 */ {}, }
/* 110 */ {},
/* 111 */ {}, public:
/* 112 */ {}, DarkForestBiome(float temp0, float rain0) : Biome(temp0, rain0) {}
/* 113 */ {}, };
/* 114 */ {},
/* 115 */ {}, class BadlandsBiome : public Biome {
/* 116 */ {}, protected:
/* 117 */ {}, virtual FloatColor getGrassColor(float, float) const {
/* 118 */ {}, return {0.565f, 0.506f, 0.302f};
/* 119 */ {}, }
/* 120 */ {}, virtual FloatColor getFoliageColor(float, float) const {
/* 121 */ {}, return {0.620f, 0.506f, 0.302f};
/* 122 */ {}, }
/* 123 */ {},
/* 124 */ {}, public:
/* 125 */ {}, BadlandsBiome(float temp0, float rain0) : Biome(temp0, rain0) {}
/* 126 */ {}, };
/* 127 */ {},
/* 128 */ {0.3, 1, 0.3},
/* 129 */ {0.3, 1, 0.3}, /* Values from https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp */
/* 130 */ {1, 1, 0.25},
/* 131 */ {0.3, 0.9, 0.3}, static const Biome BiomeDefault(0.5f, 0.5f);
/* 132 */ {0.15, 0.75, 0.15}, static const Biome BiomePlains(0.8f, 0.4f);
/* 133 */ {0.5, 0.75, 0.5}, static const Biome BiomeDesert(2.0f, 0.0f);
/* 134 */ {0.75, 1, 0.25}, static const Biome BiomeMountains(0.2f, 0.3f);
/* 135 */ {}, static const Biome BiomeForest(0.7f, 0.8f);
/* 136 */ {}, static const Biome BiomeTaiga(0.25f, 0.8f);
/* 137 */ {}, static const SwampBiome BiomeSwamp(0.8f, 0.9f);
/* 138 */ {}, static const Biome BiomeFrozen(0.0f, 0.5f);
/* 139 */ {}, static const Biome BiomeMushroomFields(0.9f, 1.0f);
/* 140 */ {0.3, 1, 0.3}, static const Biome BiomeJungle(0.95f, 0.9f);
/* 141 */ {}, static const Biome BiomeJungleEdge(0.95f, 0.8f);
/* 142 */ {}, static const Biome BiomeSnowyBeach(0.05f, 0.3f);
/* 143 */ {}, static const Biome BiomeBirchForest(0.6f, 0.6f);
/* 144 */ {}, static const DarkForestBiome BiomeDarkForest(0.7f, 0.8f);
/* 145 */ {}, static const Biome BiomeSnowyTaiga(-0.5f, 0.4f);
/* 146 */ {}, static const Biome BiomeGiantTreeTaiga(0.3f, 0.8f);
/* 147 */ {}, static const Biome BiomeSavanna(1.2f, 0.0f);
/* 148 */ {}, static const Biome BiomeSavannaPlateau(1.0f, 0.0f);
/* 149 */ {0.1, 1.25, 0.1}, static const Biome BiomeShatteredSavanna(1.1f, 0.0f);
/* 150 */ {}, static const BadlandsBiome BiomeBadlands(2.0f, 0.0f);
/* 151 */ {0.1, 1.25, 0.1},
/* 152 */ {}, extern const Biome *const BIOME_DEFAULT = &BiomeDefault;
/* 153 */ {},
/* 154 */ {}, /*
/* 155 */ {0.15, 0.75, 0.15}, * TODO: Add proper temp/rain values for oceans 44-50
/* 156 */ {0.15, 0.75, 0.15}, *
/* 157 */ {0.15, 0.75, 0.15}, * It does not matter much at the moment, as we do not compute
/* 158 */ {0.5, 0.75, 0.5}, * the water color anyways
/* 159 */ {}, */
/* 160 */ {0.5, 0.75, 0.5},
/* 161 */ {0.5, 0.75, 0.5}, const Biome *const BIOMES[256] = {
/* 162 */ {0.3, 0.9, 0.3}, /* 0 */ &BiomeDefault, /* Ocean */
/* 163 */ {0.6, 1, 0.25}, /* 1 */ &BiomePlains,
/* 164 */ {0.6, 1, 0.25}, /* 2 */ &BiomeDesert,
/* 165 */ {0.25, 1, 1.25}, /* 3 */ &BiomeMountains,
/* 166 */ {0.25, 1, 1.25}, /* 4 */ &BiomeForest,
/* 167 */ {0.25, 1, 1.25}, /* 5 */ &BiomeTaiga,
/* 6 */ &BiomeSwamp,
/* 7 */ &BiomeDefault, /* River */
/* 8 */ &BiomeDesert, /* Nether */
/* 9 */ &BiomeDefault, /* The End */
/* 10 */ &BiomeFrozen, /* Frozen Ocean */
/* 11 */ &BiomeFrozen, /* Frozen River */
/* 12 */ &BiomeFrozen, /* Snowy Tundra */
/* 13 */ &BiomeFrozen, /* Snowy Mountains */
/* 14 */ &BiomeMushroomFields,
/* 15 */ &BiomeMushroomFields, /* Mushroom Field Shore */
/* 16 */ &BiomePlains, /* Beach */
/* 17 */ &BiomeDesert, /* Desert Hills */
/* 18 */ &BiomeForest, /* Wooded Hiils */
/* 19 */ &BiomeTaiga, /* Taiga Hills */
/* 20 */ &BiomeMountains, /* Moutain Edge */
/* 21 */ &BiomeJungle,
/* 22 */ &BiomeJungle, /* Jungle Hills */
/* 23 */ &BiomeJungleEdge,
/* 24 */ &BiomeDefault, /* Deep Ocean */
/* 25 */ &BiomeMountains, /* Stone Shore */
/* 26 */ &BiomeSnowyBeach,
/* 27 */ &BiomeBirchForest,
/* 28 */ &BiomeBirchForest, /* Birch Forest Hills */
/* 29 */ &BiomeDarkForest,
/* 30 */ &BiomeSnowyTaiga,
/* 31 */ &BiomeSnowyTaiga, /* Snowy Taiga Hills */
/* 32 */ &BiomeGiantTreeTaiga,
/* 33 */ &BiomeGiantTreeTaiga, /* Giant Tree Taiga Hills */
/* 34 */ &BiomeMountains, /* Wooded Mountains */
/* 35 */ &BiomeSavanna,
/* 36 */ &BiomeSavanna, /* Savanna Plateau */
/* 37 */ &BiomeBadlands,
/* 38 */ &BiomeBadlands, /* Wooded Badlands Plateau */
/* 39 */ &BiomeBadlands, /* Badlands Plateau */
/* 40 */ &BiomeDefault, /* Small End Islands */
/* 41 */ &BiomeDefault, /* End Midlands */
/* 42 */ &BiomeDefault, /* End Highlands */
/* 43 */ &BiomeDefault, /* End Barrens */
/* 44 */ &BiomeDefault, /* Warm Ocean */
/* 45 */ &BiomeDefault, /* Lukewarm Ocean */
/* 46 */ &BiomeDefault, /* Cold Ocean */
/* 47 */ &BiomeDefault, /* Deep Warm Ocean */
/* 48 */ &BiomeDefault, /* Deep Lukewarm Ocean */
/* 49 */ &BiomeDefault, /* Deep Cold Ocean */
/* 50 */ &BiomeFrozen, /* Deep Frozen Ocean */
/* 51 */ nullptr,
/* 52 */ nullptr,
/* 53 */ nullptr,
/* 54 */ nullptr,
/* 55 */ nullptr,
/* 56 */ nullptr,
/* 57 */ nullptr,
/* 58 */ nullptr,
/* 59 */ nullptr,
/* 60 */ nullptr,
/* 61 */ nullptr,
/* 62 */ nullptr,
/* 63 */ nullptr,
/* 64 */ nullptr,
/* 65 */ nullptr,
/* 66 */ nullptr,
/* 67 */ nullptr,
/* 68 */ nullptr,
/* 69 */ nullptr,
/* 70 */ nullptr,
/* 71 */ nullptr,
/* 72 */ nullptr,
/* 73 */ nullptr,
/* 74 */ nullptr,
/* 75 */ nullptr,
/* 76 */ nullptr,
/* 77 */ nullptr,
/* 78 */ nullptr,
/* 79 */ nullptr,
/* 80 */ nullptr,
/* 81 */ nullptr,
/* 82 */ nullptr,
/* 83 */ nullptr,
/* 84 */ nullptr,
/* 85 */ nullptr,
/* 86 */ nullptr,
/* 87 */ nullptr,
/* 88 */ nullptr,
/* 89 */ nullptr,
/* 90 */ nullptr,
/* 91 */ nullptr,
/* 92 */ nullptr,
/* 93 */ nullptr,
/* 94 */ nullptr,
/* 95 */ nullptr,
/* 96 */ nullptr,
/* 97 */ nullptr,
/* 98 */ nullptr,
/* 99 */ nullptr,
/* 100 */ nullptr,
/* 101 */ nullptr,
/* 102 */ nullptr,
/* 103 */ nullptr,
/* 104 */ nullptr,
/* 105 */ nullptr,
/* 106 */ nullptr,
/* 107 */ nullptr,
/* 108 */ nullptr,
/* 109 */ nullptr,
/* 110 */ nullptr,
/* 111 */ nullptr,
/* 112 */ nullptr,
/* 113 */ nullptr,
/* 114 */ nullptr,
/* 115 */ nullptr,
/* 116 */ nullptr,
/* 117 */ nullptr,
/* 118 */ nullptr,
/* 119 */ nullptr,
/* 120 */ nullptr,
/* 121 */ nullptr,
/* 122 */ nullptr,
/* 123 */ nullptr,
/* 124 */ nullptr,
/* 125 */ nullptr,
/* 126 */ nullptr,
/* 127 */ &BiomeDefault, /* The Void */
/* 128 */ nullptr,
/* 129 */ &BiomeDefault, /* Sunflower Plains */
/* 130 */ &BiomeDesert, /* Desert Lakes */
/* 131 */ &BiomeMountains, /* Gravelly Mountains */
/* 132 */ &BiomeForest, /* Flower Forest */
/* 133 */ &BiomeTaiga, /* Taiga Mountains */
/* 134 */ &BiomeSwamp, /* Swamp Hills */
/* 135 */ nullptr,
/* 136 */ nullptr,
/* 137 */ nullptr,
/* 138 */ nullptr,
/* 139 */ nullptr,
/* 140 */ &BiomeFrozen, /* Ice Spikes */
/* 141 */ nullptr,
/* 142 */ nullptr,
/* 143 */ nullptr,
/* 144 */ nullptr,
/* 145 */ nullptr,
/* 146 */ nullptr,
/* 147 */ nullptr,
/* 148 */ nullptr,
/* 149 */ &BiomeJungle, /* Modified Jungle */
/* 150 */ nullptr,
/* 151 */ &BiomeJungleEdge, /* Modified Jungle Edge */
/* 152 */ nullptr,
/* 153 */ nullptr,
/* 154 */ nullptr,
/* 155 */ &BiomeBirchForest, /* Tall Birch Forest */
/* 156 */ &BiomeBirchForest, /* Tall Birch Hills */
/* 157 */ &BiomeDarkForest, /* Dark Forest Hills */
/* 158 */ &BiomeSnowyTaiga, /* Snowy Taiga Mountains */
/* 159 */ nullptr,
/* 160 */ &BiomeTaiga, /* Giant Spruce Taiga */
/* 161 */ &BiomeTaiga, /* Giant Spruce Taiga Hills */
/* 162 */ &BiomeMountains, /* Gravelly Mountains+ */
/* 163 */ &BiomeShatteredSavanna,
/* 164 */ &BiomeSavannaPlateau, /* Shattered Savanna Plateau */
/* 165 */ &BiomeBadlands, /* Eroded Badlands */
/* 166 */ &BiomeBadlands, /* Modified Wooded Badlands Plateau */
/* 167 */ &BiomeBadlands, /* Modified Badlands Plateau */
}; };
} }

View file

@ -26,14 +26,36 @@
#pragma once #pragma once
#include "Color.hpp"
namespace MinedMap { namespace MinedMap {
namespace Resource { namespace Resource {
struct Biome { class BlockType;
class Biome {
public:
struct FloatColor {
float r, g, b; float r, g, b;
};
private:
float temp, rain;
protected:
virtual FloatColor getGrassColor(float temp, float rain) const;
virtual FloatColor getFoliageColor(float temp, float rain) const;
virtual FloatColor getWaterColor(float temp, float rain) const;
public:
Biome(float temp0, float rain0) : temp(temp0), rain(rain0) {}
Color getBlockColor(const BlockType *type, unsigned height) const;
}; };
extern const Biome BIOMES[256]; extern const Biome *const BIOME_DEFAULT;
extern const Biome *const BIOMES[256];
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net> Copyright (c) 2018, Matthias Schiffer <mschiffer@universe-factory.net>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -24,47 +24,17 @@
*/ */
#include "Block.hpp" #pragma once
#include "../Resource/Biome.hpp"
#include <cstdint>
namespace MinedMap { namespace MinedMap {
namespace World { namespace Resource {
Block::Color Block::getColor() const { struct Color {
if (!type || !type->opaque) uint8_t r, g, b, a;
return Color {}; };
float r = type->color.r;
float g = type->color.g;
float b = type->color.b;
float heightCoef = height/255.0f + 0.5f;
r *= heightCoef;
g *= heightCoef;
b *= heightCoef;
if (type->grass || type->foliage) {
const Resource::Biome &biomeDef = Resource::BIOMES[biome];
r *= biomeDef.r;
g *= biomeDef.g;
b *= biomeDef.b;
}
if (type->blue) {
r *= 0.265;
g *= 0.382;
b *= 1.379;
}
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
return Color {uint8_t(r), uint8_t(g), uint8_t(b), 0xff};
}
} }
} }

View file

@ -26,6 +26,7 @@
#pragma once #pragma once
#include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
@ -39,4 +40,8 @@ template <typename T> static inline T assertValue(T&& val) {
return std::forward<T>(val); return std::forward<T>(val);
} }
static inline float clamp(float v, float min, float max) {
return std::max(std::min(v, max), min);
}
} }

View file

@ -27,6 +27,7 @@
#pragma once #pragma once
#include "../NBT/CompoundTag.hpp" #include "../NBT/CompoundTag.hpp"
#include "../Resource/Biome.hpp"
#include "../Resource/BlockType.hpp" #include "../Resource/BlockType.hpp"
@ -34,17 +35,18 @@ namespace MinedMap {
namespace World { namespace World {
struct Block { struct Block {
struct Color {
uint8_t r, g, b, a;
};
const Resource::BlockType *type; const Resource::BlockType *type;
unsigned height; unsigned height;
uint8_t blockLight; uint8_t blockLight;
uint8_t biome; uint8_t biome;
Color getColor() const; Resource::Color getColor() const {
if (!type || !type->opaque)
return Resource::Color {};
return (Resource::BIOMES[biome] ?: Resource::BIOME_DEFAULT)->getBlockColor(type, height);
}
operator bool() const { operator bool() const {
return type; return type;