]> git.localhorst.tv Git - blobs.git/blob - src/world/Planet.hpp
fix friction
[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         /// surface normal
39         glm::dvec3 NormalAt(const glm::dvec3 &p) const noexcept { return glm::normalize(p); }
40         /// height over surface
41         double ElevationAt(const glm::dvec3 &p) const noexcept { return glm::length(p) - Radius(); }
42         /// distance to planet center
43         double DistanceAt(const glm::dvec3 &p) const noexcept { return glm::length(p); }
44         /// acceleration due to gravity at given point
45         glm::dvec3 GravityAt(const glm::dvec3 &p) const noexcept { return NormalAt(p) * (-GravitationalParameter() / glm::length2(p)); }
46
47         /// get ground tile
48         Tile &TileAt(const glm::dvec3 &) noexcept;
49         const Tile &TileAt(const glm::dvec3 &) const noexcept;
50         const TileType &TileTypeAt(const glm::dvec3 &) const noexcept;
51
52         /// Get the tile at given surface and coordinates.
53         Tile &TileAt(int surface, int x, int y) noexcept;
54         const Tile &TileAt(int surface, int x, int y) const noexcept;
55         const TileType &TypeAt(int surface, int x, int y) const noexcept;
56
57         /// The length in tiles of the side of each surface.
58         int SideLength() const { return sidelength; }
59
60         // center point of tile on surface at elevation
61         glm::dvec3 TileCenter(int surface, int x, int y, double elevation = 0.0) const noexcept;
62
63         void BuildVAO(const Set<TileType> &);
64         void Draw(app::Assets &, graphics::Viewport &) override;
65
66 private:
67         /// Convert coordinates into a tile index.
68         int IndexOf(int surface, int x, int y) const {
69                 assert(0 <= surface && surface <= 5);
70                 assert(0 <= x && x < sidelength);
71                 assert(0 <= y && y < sidelength);
72                 return surface * TilesPerSurface() + y * SideLength() + x;
73         }
74         /// The number of tiles of one surface.
75         int TilesPerSurface() const {
76                 return SideLength() * SideLength();
77         }
78         /// Total number of tiles of all surfaces combined.
79         int TilesTotal() const {
80                 return 6 * TilesPerSurface();
81         }
82
83 private:
84         int sidelength;
85         std::vector<Tile> tiles;
86
87         struct Attributes {
88                 glm::vec3 position;
89                 glm::vec3 normal;
90                 glm::vec3 tex_coord;
91         };
92         std::unique_ptr<graphics::SimpleVAO<Attributes, unsigned int>> vao;
93
94 };
95
96 void GenerateEarthlike(const Set<TileType> &, Planet &) noexcept;
97 void GenerateTest(const Set<TileType> &, Planet &) noexcept;
98
99 }
100 }
101
102 #endif