#pragma once #include #include #include #include #include #include #include #include "constants.h" #include "shader.h" constexpr std::size_t index(const std::size_t x, const std::size_t y) { return x + y * kGeographyShort; } class Grid { public: float get(const std::size_t x, const std::size_t y) const { return (*data_)[index(x, y)]; } void set(const std::size_t x, const std::size_t y, const float value) const { (*data_)[index(x, y)] = value; } Grid operator+(const Grid &) const; void operator+=(const Grid &) const; Grid operator-() const; Grid operator-(const Grid &) const; void operator-=(const Grid &) const; Grid operator*(float) const; void operator*=(float) const; Grid operator/(float) const; void operator/=(float) const; glm::vec3 normal_at(std::size_t, std::size_t, float = 1.) const; static Grid *PerlinNoise(int, int, std::size_t); std::array *vertices() const; static std::array *indices(); static void RandomizeBase() { base_random_ = device_() << 4; } float min() const { return *std::min_element(data_->begin(), data_->end()); } float max() const { return *std::max_element(data_->begin(), data_->end()); } private: std::unique_ptr> data_{ std::make_unique>()}; static std::random_device device_; std::mt19937 engine_{device_()}; std::uniform_real_distribution dist_{0, glm::two_pi()}; static std::mt19937::result_type base_random_; float RandomAngle() { return dist_(engine_); } void AngleSeed(const std::mt19937::result_type seed) { engine_.seed(seed); } };