add WeatherPreset
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
#include "maths/voxmaths.hpp"
|
#include "maths/voxmaths.hpp"
|
||||||
#include "util/CentredMatrix.hpp"
|
#include "util/CentredMatrix.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "presets/WeatherPreset.hpp"
|
||||||
#include "voxels/Chunk.hpp"
|
#include "voxels/Chunk.hpp"
|
||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
#include "window/Camera.hpp"
|
#include "window/Camera.hpp"
|
||||||
@@ -62,33 +63,62 @@ static inline glm::vec4 light_at(const Chunks& chunks, int x, int y, int z) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
/// @brief 'Random' vertical texture coord offset to randomize rain layers
|
||||||
timer += delta * 0.5f;
|
static constexpr float K = 21.41149;
|
||||||
batch->begin();
|
/// @brief Precipitation face size
|
||||||
|
static constexpr glm::ivec2 FACE_SIZE {1, 16};
|
||||||
|
|
||||||
util::PseudoRandom random(0);
|
static UVRegion calc_uv(
|
||||||
|
const glm::vec3& pos,
|
||||||
|
const glm::vec3& right,
|
||||||
|
float timer,
|
||||||
|
const WeatherPreset& weather
|
||||||
|
) {
|
||||||
|
static util::PseudoRandom random(0);
|
||||||
|
|
||||||
|
float scale = weather.fall.scale;
|
||||||
|
|
||||||
|
float m = glm::sign(right.x + right.z);
|
||||||
|
int ux = pos.x;
|
||||||
|
int uz = pos.z;
|
||||||
|
if (glm::abs(right.x) < glm::abs(right.z)) {
|
||||||
|
std::swap(ux, uz);
|
||||||
|
}
|
||||||
|
random.setSeed(uz);
|
||||||
|
float hspeed = (random.randFloat() * 2.0f - 1.0f) * weather.fall.hspeed;
|
||||||
|
float u1 = ux * scale + timer * hspeed * -m;
|
||||||
|
float v1 = timer * weather.fall.vspeed + pos.y * scale + uz * K;
|
||||||
|
|
||||||
|
return {u1, v1, u1 + m * scale, v1 + FACE_SIZE.y * scale};
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
||||||
|
timer += delta;
|
||||||
|
|
||||||
|
WeatherPreset weather {};
|
||||||
|
auto& fall = weather.fall;
|
||||||
|
fall.texture = "misc/rain";
|
||||||
|
|
||||||
|
const int radius = 6;
|
||||||
|
const int depth = 12;
|
||||||
|
|
||||||
int x = glm::floor(camera.position.x);
|
int x = glm::floor(camera.position.x);
|
||||||
int y = glm::floor(camera.position.y);
|
int y = glm::floor(camera.position.y);
|
||||||
int z = glm::floor(camera.position.z);
|
int z = glm::floor(camera.position.z);
|
||||||
|
|
||||||
auto& texture = assets.require<Texture>("misc/snow");
|
util::CentredMatrix<int, (depth + 1) * 2> heights;
|
||||||
|
heights.setCenter(x, z);
|
||||||
|
for (int z = heights.beginY(); z < heights.endY(); z++) {
|
||||||
|
for (int x = heights.beginX(); x < heights.endX(); x++) {
|
||||||
|
heights.at(x, z) = getHeightAt(x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
batch->begin();
|
||||||
|
auto& texture = assets.require<Texture>(fall.texture);
|
||||||
texture.setMipMapping(false);
|
texture.setMipMapping(false);
|
||||||
batch->setTexture(&texture, {});
|
batch->setTexture(&texture, {});
|
||||||
|
|
||||||
const auto& front = camera.front;
|
|
||||||
glm::ivec2 size {1, 16};
|
|
||||||
|
|
||||||
float horizontal = 0.5f * 5;
|
|
||||||
|
|
||||||
glm::vec4 light = light_at(chunks, x, y, z);
|
|
||||||
|
|
||||||
const int radius = 6;
|
|
||||||
const int depth = 12;
|
|
||||||
float scale = 0.4f;
|
|
||||||
int quads = 0;
|
|
||||||
float k = 21.41149;
|
|
||||||
|
|
||||||
const struct {
|
const struct {
|
||||||
glm::vec3 right;
|
glm::vec3 right;
|
||||||
glm::vec3 front;
|
glm::vec3 front;
|
||||||
@@ -99,14 +129,6 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
|||||||
{{0, 0, 1}, {1, 0, 0}},
|
{{0, 0, 1}, {1, 0, 0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
util::CentredMatrix<int, (depth + 1) * 2> heights;
|
|
||||||
heights.setCenter(x, z);
|
|
||||||
for (int z = heights.beginY(); z < heights.endY(); z++) {
|
|
||||||
for (int x = heights.beginX(); x < heights.endX(); x++) {
|
|
||||||
heights.at(x, z) = getHeightAt(x, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& face : faces) {
|
for (const auto& face : faces) {
|
||||||
for (int lx = -radius; lx <= radius; lx++) {
|
for (int lx = -radius; lx <= radius; lx++) {
|
||||||
for (int lz = depth; lz > 0; lz--) {
|
for (int lz = depth; lz > 0; lz--) {
|
||||||
@@ -114,34 +136,20 @@ void PrecipitationRenderer::render(const Camera& camera, float delta) {
|
|||||||
glm::vec3 pos = face.right * static_cast<float>(lx) +
|
glm::vec3 pos = face.right * static_cast<float>(lx) +
|
||||||
face.front * static_cast<float>(lz);
|
face.front * static_cast<float>(lz);
|
||||||
pos += glm::vec3(x, 0, z);
|
pos += glm::vec3(x, 0, z);
|
||||||
pos.y = glm::max(y - size.y / 2, heights.at(pos.x, pos.z)) +
|
pos.y =
|
||||||
size.y / 2 + 1;
|
glm::max(y - FACE_SIZE.y / 2, heights.at(pos.x, pos.z)) +
|
||||||
|
FACE_SIZE.y / 2 + 1;
|
||||||
pos += glm::vec3(0.5f, 0.0f, 0.5f);
|
pos += glm::vec3(0.5f, 0.0f, 0.5f);
|
||||||
|
|
||||||
// UV coords calculations
|
|
||||||
float m = glm::sign(face.right.x + face.right.z);
|
|
||||||
int ux = pos.x;
|
|
||||||
int uz = pos.z;
|
|
||||||
|
|
||||||
if (glm::abs(face.right.x) < glm::abs(face.right.z)) {
|
|
||||||
std::swap(ux, uz);
|
|
||||||
}
|
|
||||||
|
|
||||||
random.setSeed(uz);
|
|
||||||
float hspeed = (random.randFloat() * 2.0f - 1.0f) * horizontal;
|
|
||||||
float u1 = ux * scale + timer * hspeed * -m;
|
|
||||||
float v1 = timer + pos.y * scale + uz * k;
|
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
glm::vec4 light = light_at(chunks, pos.x, y, pos.z);
|
|
||||||
batch->quad(
|
batch->quad(
|
||||||
pos,
|
pos,
|
||||||
face.right,
|
face.right,
|
||||||
{0, 1, 0},
|
{0, 1, 0},
|
||||||
size,
|
FACE_SIZE,
|
||||||
light,
|
light_at(chunks, pos.x, y, pos.z),
|
||||||
glm::vec3(1.0f),
|
glm::vec3(1.0f),
|
||||||
UVRegion(u1, v1, u1 + m * scale, v1 + size.y * scale)
|
calc_uv(pos, face.right, timer, weather)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#include "WeatherPreset.hpp"
|
||||||
|
|
||||||
|
#include "data/dv_util.hpp"
|
||||||
|
|
||||||
|
dv::value WeatherPreset::serialize() const {
|
||||||
|
auto root = dv::object();
|
||||||
|
|
||||||
|
auto froot = dv::object();
|
||||||
|
froot["texture"] = fall.texture;
|
||||||
|
froot["vspeed"] = fall.vspeed;
|
||||||
|
froot["hspeed"] = fall.hspeed;
|
||||||
|
froot["scale"] = fall.scale;
|
||||||
|
root["fall"] = froot;
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeatherPreset::deserialize(const dv::value& src) {
|
||||||
|
if (src.has("fall")) {
|
||||||
|
const auto& froot = src["fall"];
|
||||||
|
froot.at("texture").get(fall.texture);
|
||||||
|
froot.at("vspeed").get(fall.vspeed);
|
||||||
|
froot.at("hspeed").get(fall.hspeed);
|
||||||
|
froot.at("scale").get(fall.scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "interfaces/Serializable.hpp"
|
||||||
|
|
||||||
|
struct WeatherPreset : Serializable {
|
||||||
|
struct {
|
||||||
|
/// @brief Precipitation texture
|
||||||
|
std::string texture;
|
||||||
|
/// @brief Vertical speed
|
||||||
|
float vspeed = 1.0f;
|
||||||
|
/// @brief Max horizontal speed
|
||||||
|
float hspeed = 0.1f;
|
||||||
|
/// @brief UV scaling
|
||||||
|
float scale = 0.1f;
|
||||||
|
} fall {};
|
||||||
|
|
||||||
|
dv::value serialize() const override;
|
||||||
|
void deserialize(const dv::value& src) override;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user