From: Daniel Karbach Date: Mon, 13 Nov 2017 22:30:27 +0000 (+0100) Subject: earthlike planet gen prototype X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=592c7e6d616f2cfacfd4948e17a4bb72f6444488 earthlike planet gen prototype missing lots of climate stuff, but looks rather decent already --- diff --git a/src/blobs.cpp b/src/blobs.cpp index f96dd0f..f5e0918 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -24,7 +24,6 @@ int main(int argc, char *argv[]) { sun.AngularMomentum(1.0e13); world::Planet planet(11); - world::GenerateTest(planet); planet.SetParent(sun); planet.Mass(1.0e9); planet.GetOrbit().SemiMajorAxis(941.7); @@ -33,7 +32,6 @@ int main(int argc, char *argv[]) { planet.AngularMomentum(1.25e9); world::Planet moon(3); - world::GenerateTest(moon); moon.SetParent(planet); moon.Mass(1.0e6); moon.GetOrbit().SemiMajorAxis(25.0); @@ -41,7 +39,6 @@ int main(int argc, char *argv[]) { moon.AngularMomentum(1.0e4); world::Planet second_planet(9); - world::GenerateTest(second_planet); second_planet.SetParent(sun); second_planet.Mass(1.0e9); second_planet.GetOrbit().SemiMajorAxis(350.0); @@ -55,6 +52,10 @@ int main(int argc, char *argv[]) { sim.AddPlanet(second_planet); sim.AddPlanet(moon); + world::GenerateEarthlike(planet); + world::GenerateTest(moon); + world::GenerateTest(second_planet); + std::cout << "length of year: " << planet.OrbitalPeriod() << "s" << std::endl; std::cout << "length of moon cycle: " << moon.OrbitalPeriod() << "s" << std::endl; std::cout << "length of day: " << planet.RotationalPeriod() << "s" << std::endl; @@ -66,11 +67,13 @@ int main(int argc, char *argv[]) { state.GetCamera() .Reference(planet) // sunrise - .FirstPerson(0, glm::vec3(0.0f, 0.0f, 0.1f), glm::vec3(1.0f, -0.75f, 0.1f)) + //.FirstPerson(0, glm::vec3(0.0f, 0.0f, 0.1f), glm::vec3(1.0f, -0.75f, 0.1f)) // sunset //.FirstPerson(3, glm::vec3(0.0f, 0.0f, 0.1f), glm::vec3(1.0f, -0.75f, 0.1f)) // from afar //.MapView(0, glm::vec3(0.0f, 0.0f, 25.0f), 0.0f) + // from afar, rotating + .Orbital(glm::vec3(-25.0f, 0.0f, 0.0f)) ; // system view //state.GetCamera() diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp index 0c468f5..efc804d 100644 --- a/src/world/Planet.hpp +++ b/src/world/Planet.hpp @@ -61,6 +61,8 @@ public: return 6 * TilesPerSurface(); } + glm::dvec3 TileCenter(int surface, int x, int y) const noexcept; + void BuildVAOs(); void Draw(app::Assets &, graphics::Viewport &) override; @@ -76,7 +78,8 @@ private: }; -void GenerateTest(Planet &); +void GenerateEarthlike(Planet &) noexcept; +void GenerateTest(Planet &) noexcept; } } diff --git a/src/world/world.cpp b/src/world/world.cpp index b872503..57b0804 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -8,11 +8,15 @@ #include "../const.hpp" #include "../app/Assets.hpp" #include "../graphics/Viewport.hpp" +#include "../rand/OctaveNoise.hpp" +#include "../rand/SimplexNoise.hpp" #include #include +#include #include #include +#include #include using blobs::G; @@ -258,6 +262,14 @@ Planet::Planet(int sidelength) Planet::~Planet() { } +glm::dvec3 Planet::TileCenter(int surface, int x, int y) const noexcept { + glm::dvec3 center(0.0f); + center[(surface + 0) % 3] = x + 0.5 - Radius(); + center[(surface + 1) % 3] = y + 0.5 - Radius(); + center[(surface + 2) % 3] = surface < 3 ? Radius() : -Radius(); + return center; +} + void Planet::BuildVAOs() { vao.Bind(); vao.BindAttributes(); @@ -268,7 +280,7 @@ void Planet::BuildVAOs() { vao.ReserveAttributes(TilesTotal() * 4, GL_STATIC_DRAW); { auto attrib = vao.MapAttributes(GL_WRITE_ONLY); - float offset = sidelength * 0.5f; + float offset = Radius(); // srf 0 1 2 3 4 5 // up +Z +X +Y -Z -X -Y @@ -361,7 +373,56 @@ void Planet::Draw(app::Assets &assets, graphics::Viewport &viewport) { } -void GenerateTest(Planet &p) { +void GenerateEarthlike(Planet &p) noexcept { + rand::SimplexNoise elevation_gen(0); + + constexpr int ice = 0; + constexpr int grass = 3; + constexpr int water = 4; + constexpr int sand = 5; + constexpr int rock = 8; + + constexpr double water_thresh = 0.0; + constexpr double beach_thresh = 0.1; + constexpr double mountain_thresh = 0.5; + + const glm::dvec3 axis(glm::dvec4(0.0, 1.0, 0.0, 0.0) * glm::eulerAngleXY(p.SurfaceTilt().x, p.SurfaceTilt().y)); + const double cap_thresh = std::cos(p.AxialTilt().x); + + for (int surface = 0; surface <= 5; ++surface) { + for (int y = 0; y < p.SideLength(); ++y) { + for (int x = 0; x < p.SideLength(); ++x) { + glm::dvec3 to_tile = p.TileCenter(surface, x, y); + double near_axis = std::abs(glm::dot(glm::normalize(to_tile), axis)); + if (near_axis > cap_thresh) { + p.TileAt(surface, x, y).type = ice; + continue; + } + float elevation = rand::OctaveNoise( + elevation_gen, + to_tile / p.Radius(), + 3, // octaves + 0.5, // persistence + 2 / p.Radius(), // frequency + 2, // amplitude + 2 // growth + ); + if (elevation < water_thresh) { + p.TileAt(surface, x, y).type = water; + } else if (elevation < beach_thresh) { + p.TileAt(surface, x, y).type = sand; + } else if (elevation < mountain_thresh) { + p.TileAt(surface, x, y).type = grass; + } else { + p.TileAt(surface, x, y).type = rock; + } + } + } + } + p.BuildVAOs(); +} + +void GenerateTest(Planet &p) noexcept { for (int surface = 0; surface <= 5; ++surface) { for (int y = 0; y < p.SideLength(); ++y) { for (int x = 0; x < p.SideLength(); ++x) {