]> git.localhorst.tv Git - blobs.git/blob - src/world/Planet.hpp
camera controls
[blobs.git] / src / world / Planet.hpp
1 #ifndef BLOBS_WORLD_PLANET_HPP_
2 #define BLOBS_WORLD_PLANET_HPP_
3
4 #include "Body.hpp"
5
6 #include "Set.hpp"
7 #include "Tile.hpp"
8 #include "../graphics/SimpleVAO.hpp"
9 #include "../math/glm.hpp"
10
11 #include <cassert>
12 #include <memory>
13 #include <vector>
14 #include <GL/glew.h>
15
16
17 namespace blobs {
18 namespace world {
19
20 class TileType;
21
22 /// A planet has six surfaces, numbered 0 to 5, each filled with
23 /// sidelength² tiles.
24 class Planet
25 : public Body {
26
27 public:
28         explicit Planet(int sidelength);
29         ~Planet();
30
31         Planet(const Planet &) = delete;
32         Planet &operator =(const Planet &) = delete;
33
34         Planet(Planet &&) = delete;
35         Planet &operator =(Planet &&) = delete;
36
37 public:
38         /// Get the tile at given surface and coordinates.
39         Tile &TileAt(int surface, int x, int y) {
40                 return tiles[IndexOf(surface, x, y)];
41         }
42         const Tile &TileAt(int surface, int x, int y) const {
43                 return tiles[IndexOf(surface, x, y)];
44         }
45
46         const TileType &TypeAt(int surface, int x, int y) const;
47
48         /// Convert coordinates into a tile index.
49         int IndexOf(int surface, int x, int y) const {
50                 assert(0 <= surface && surface <= 5);
51                 assert(0 <= x && x < sidelength);
52                 assert(0 <= y && y < sidelength);
53                 return surface * TilesPerSurface() + y * SideLength() + x;
54         }
55         /// The length of the side of each surface.
56         int SideLength() const {
57                 return sidelength;
58         }
59         /// The number of tiles of one surface.
60         int TilesPerSurface() const {
61                 return SideLength() * SideLength();
62         }
63         /// Total number of tiles of all surfaces combined.
64         int TilesTotal() const {
65                 return 6 * TilesPerSurface();
66         }
67
68         double TileToPosition(int t) const noexcept { return double(t) - Radius(); }
69         int PositionToTile(double p) const noexcept { return int(p + Radius()); }
70
71         // tile coordinates of position on surface
72         glm::ivec2 SurfacePosition(int surface, const glm::dvec3 &) const noexcept;
73         // height of point over surface
74         double SurfaceElevation(int surface, const glm::dvec3 &) const noexcept;
75         // center point of tile on surface at elevation
76         glm::dvec3 TileCenter(int surface, int x, int y, double elevation = 0.0) const noexcept;
77
78         static glm::dvec3 SurfaceNormal(int srf) noexcept {
79                 glm::dvec3 nrm(0.0);
80                 nrm[(srf + 2) % 3] = srf < 3 ? 1.0 : -1.0;
81                 return nrm;
82         }
83         static glm::dmat3 SurfaceOrientation(int srf) noexcept {
84                 glm::dmat3 mat(0.0);
85                 mat[(srf + 0) % 3][0] = 1.0;
86                 mat[(srf + 2) % 3][1] = srf < 3 ? 1.0 : -1.0;
87                 mat[(srf + 1) % 3][2] = srf < 3 ? 1.0 : -1.0;
88                 return mat;
89         }
90
91         void BuildVAO(const Set<TileType> &);
92         void Draw(app::Assets &, graphics::Viewport &) override;
93
94 private:
95         int sidelength;
96         std::vector<Tile> tiles;
97
98         struct Attributes {
99                 glm::vec3 position;
100                 glm::vec3 tex_coord;
101         };
102         std::unique_ptr<graphics::SimpleVAO<Attributes, unsigned int>> vao;
103
104 };
105
106 void GenerateEarthlike(const Set<TileType> &, Planet &) noexcept;
107 void GenerateTest(const Set<TileType> &, Planet &) noexcept;
108
109 }
110 }
111
112 #endif