X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Fworld%2FPlanet.hpp;h=237159994c47da1c9dbd1e23bd235ffd2214cbb0;hb=cd80d7cfcac3c58d601db2ab4e0381dd77c06f44;hp=6106ccf06aa8a770d5928b4e1def95a1c8463a7c;hpb=91dfd6cd62ea0723c3c83572b4ebfa4ef7b4ac5f;p=blobs.git diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp index 6106ccf..2371599 100644 --- a/src/world/Planet.hpp +++ b/src/world/Planet.hpp @@ -1,75 +1,98 @@ #ifndef BLOBS_WORLD_PLANET_HPP_ #define BLOBS_WORLD_PLANET_HPP_ +#include "Body.hpp" + +#include "Set.hpp" #include "Tile.hpp" +#include "../graphics/SimpleVAO.hpp" +#include "../math/glm.hpp" #include #include +#include +#include namespace blobs { namespace world { -struct Tile; +class TileType; -/// A planet has six surfaces, numbered 0 to 5, each with tiles from -/// +radius to -radius. -class Planet { +/// A planet has six surfaces, numbered 0 to 5, each filled with +/// sidelength² tiles. +class Planet +: public Body { public: - explicit Planet(int radius); + explicit Planet(int sidelength); ~Planet(); - Planet(Planet &&); - Planet &operator =(Planet &&); - Planet(const Planet &) = delete; Planet &operator =(const Planet &) = delete; + Planet(Planet &&) = delete; + Planet &operator =(Planet &&) = delete; + public: + /// surface normal + glm::dvec3 NormalAt(const glm::dvec3 &p) const noexcept { return normalize(p); } + /// height over surface + double ElevationAt(const glm::dvec3 &p) const noexcept { return length(p) - Radius(); } + /// distance to planet center + double DistanceAt(const glm::dvec3 &p) const noexcept { return length(p); } + + /// get ground tile + Tile &TileAt(const glm::dvec3 &) noexcept; + const Tile &TileAt(const glm::dvec3 &) const noexcept; + const TileType &TileTypeAt(const glm::dvec3 &) const noexcept; + /// Get the tile at given surface and coordinates. - Tile &TileAt(int surface, int x, int y) { - return tiles[IndexOf(surface, x, y)]; - } - const Tile &TileAt(int surface, int x, int y) const { - return tiles[IndexOf(surface, x, y)]; - } + Tile &TileAt(int surface, int x, int y) noexcept; + const Tile &TileAt(int surface, int x, int y) const noexcept; + const TileType &TypeAt(int surface, int x, int y) const noexcept; + + /// The length in tiles of the side of each surface. + int SideLength() const { return sidelength; } + // center point of tile on surface at elevation + glm::dvec3 TileCenter(int surface, int x, int y, double elevation = 0.0) const noexcept; + + void BuildVAO(const Set &); + void Draw(app::Assets &, graphics::Viewport &) override; + +private: /// Convert coordinates into a tile index. int IndexOf(int surface, int x, int y) const { assert(0 <= surface && surface <= 5); - assert(-radius <= x && x <= radius); - assert(-radius <= y && y <= radius); - return surface * SurfaceArea() + ToOffset(y) * SideLength() + ToOffset(x); - } - /// Convert coordinate into offset - int ToOffset(int c) const { - return c + radius; + assert(0 <= x && x < sidelength); + assert(0 <= y && y < sidelength); + return surface * TilesPerSurface() + y * SideLength() + x; } - /// The "radius" of the planet. - int Radius() const { - return radius; - } - /// The length of the side of each surface. - int SideLength() const { - return 2 * radius + 1; - } - /// The area (or number of tiles) of one surface - int SurfaceArea() const { + /// The number of tiles of one surface. + int TilesPerSurface() const { return SideLength() * SideLength(); } - /// Total area of all surfaces combined. - int TotalArea() const { - return 6 * SurfaceArea(); + /// Total number of tiles of all surfaces combined. + int TilesTotal() const { + return 6 * TilesPerSurface(); } private: - int radius; - std::unique_ptr tiles; + int sidelength; + std::vector tiles; + + struct Attributes { + glm::vec3 position; + glm::vec3 normal; + glm::vec3 tex_coord; + }; + std::unique_ptr> vao; }; -void GenerateTest(Planet &); +void GenerateEarthlike(const Set &, Planet &) noexcept; +void GenerateTest(const Set &, Planet &) noexcept; } }