From 950d8f20f981c00ad484d2596a95bffb63966205 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 19 May 2023 23:38:10 +0300 Subject: [PATCH] Support adding prop entities to Landscape --- source/game/landscape.cpp | 26 +++++++++++++++++++++----- source/game/landscape.h | 28 +++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/source/game/landscape.cpp b/source/game/landscape.cpp index 1612d44..c9c2814 100644 --- a/source/game/landscape.cpp +++ b/source/game/landscape.cpp @@ -1,7 +1,6 @@ #include "landscape.h" #include "entity.h" #include "root.h" -#include "transform.h" using namespace std; @@ -18,6 +17,11 @@ Landscape::Landscape(Stage &s, const HeightmapTerrainSetup &t, float b): block_size = grid_size*terrain_setup.grid_spacing; } +bool Landscape::terrain_index_compare(const Terrain &t, const LinAl::Vector &i) +{ + return t.index.y &bounds) for(int y=min_index.y; y<=max_index.y; ++y) { - auto i = lower_bound(terrains, LinAl::Vector(min_index.x, y), [](const Terrain &t, const LinAl::Vector &n){ - return t.index.y(min_index.x, y), terrain_index_compare); for(int x=min_index.x; x<=max_index.x; ++x) { @@ -48,7 +50,7 @@ void Landscape::generate(const Geometry::BoundingBox &bounds) if(generator) { LinAl::Vector base = center-block_size_vec/2.0f; - generator->generate_block({ base, base+block_size_vec }, terrain); + generator->generate_block(*this, { base, base+block_size_vec }, terrain); } i = terrains.emplace(i, index, move(entity), move(terrain)); } @@ -57,4 +59,18 @@ void Landscape::generate(const Geometry::BoundingBox &bounds) } } +LinAl::Vector Landscape::get_ground_position(const LinAl::Vector &p) const +{ + LinAl::Vector index(round(p.x/block_size), round(p.y/block_size)); + auto i = lower_bound(terrains, index, terrain_index_compare); + if(i==terrains.end() || i->index!=index) + return compose(p.slice<2>(0), 0.0f); + + LinAl::Vector center = i->entity->get_transform()->get_position(); + LinAl::Vector corner = center.slice<2>(0) - i->terrain->get_size()/2.0f; + LinAl::Vector p_xy = p.slice<2>(0); + float z = i->terrain->get_elevation(p_xy-corner); + return center+compose(p_xy, z); +} + } // namespace Msp::Game diff --git a/source/game/landscape.h b/source/game/landscape.h index b31402b..9319718 100644 --- a/source/game/landscape.h +++ b/source/game/landscape.h @@ -7,10 +7,12 @@ #include "mspgame_api.h" #include "owned.h" #include "system.h" +#include "transform.h" namespace Msp::Game { class Entity; +class Landscape; class MSPGAME_API LandscapeGenerator { @@ -18,7 +20,7 @@ protected: LandscapeGenerator() = default; public: - virtual void generate_block(const Geometry::BoundingBox &, Handle) = 0; + virtual void generate_block(Landscape &, const Geometry::BoundingBox &, Handle) = 0; }; class MSPGAME_API Landscape: public System @@ -31,22 +33,46 @@ private: Owned terrain; }; + struct Prop + { + Owned entity; + }; + Owned subroot; const HeightmapTerrainSetup &terrain_setup; float block_size = 100.0f; LandscapeGenerator *generator = nullptr; std::vector terrains; + std::vector props; public: Landscape(Stage &, const HeightmapTerrainSetup &, float); +private: + static bool terrain_index_compare(const Terrain &, const LinAl::Vector &); + +public: void set_generator(LandscapeGenerator *); void generate(const Geometry::BoundingBox &); LinAl::Vector get_ground_position(const LinAl::Vector &) const; + template + requires std::is_base_of_v + void add_prop(const T::Setup &, TransformValues); + void tick(Time::TimeDelta) override { } }; + +template + requires std::is_base_of_v +void Landscape::add_prop(const T::Setup &setup, TransformValues tf) +{ + tf.position = get_ground_position(tf.position); + Owned prop(subroot, setup, tf); + props.emplace_back(std::move(prop)); +} + } // namespace Msp::Game #endif -- 2.45.2