]> git.tdb.fi Git - libs/game.git/commitdiff
Add a component for creating meshes via geometry definitions
authorMikko Rasa <tdb@tdb.fi>
Sun, 26 Jan 2025 16:33:10 +0000 (18:33 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 27 Jan 2025 11:28:31 +0000 (13:28 +0200)
source/game/shape.cpp [new file with mode: 0644]
source/game/shape.h [new file with mode: 0644]
source/gameview/renderer.cpp
source/gameview/renderer.h

diff --git a/source/game/shape.cpp b/source/game/shape.cpp
new file mode 100644 (file)
index 0000000..ba17721
--- /dev/null
@@ -0,0 +1,27 @@
+#include "shape.h"
+#include <msp/geometry/loader.h>
+
+namespace Msp::Game {
+
+ShapeSetup::Loader::Loader(ShapeSetup &s):
+       ObjectLoader(s)
+{
+       static ActionMap shared_actions;
+       set_actions(shared_actions);
+}
+
+void ShapeSetup::Loader::init_actions()
+{
+       add("render_detail", &ShapeSetup::render_detail);
+       add("shape", &Loader::shape);
+       add("technique_name", &ShapeSetup::technique_name);
+}
+
+void ShapeSetup::Loader::shape()
+{
+       Geometry::Loader<float, 3> ldr;
+       load_sub_with(ldr);
+       obj.shape = ldr.take_shape();
+}
+
+} // namespace Msp::Game
diff --git a/source/game/shape.h b/source/game/shape.h
new file mode 100644 (file)
index 0000000..692cf0c
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef MSP_GAME_SHAPE_H_
+#define MSP_GAME_SHAPE_H_
+
+#include <memory>
+#include <msp/datafile/objectloader.h>
+#include <msp/geometry/shape.h>
+#include "component.h"
+#include "mspgame_api.h"
+
+namespace Msp::Game {
+
+// TODO Make this visible to the setup generator
+struct MSPGAME_API ShapeSetup
+{
+       class MSPGAME_API Loader: public DataFile::ObjectLoader<ShapeSetup>
+       {
+       public:
+               Loader(ShapeSetup &);
+
+       private:
+               void init_actions() override;
+
+               void shape();
+       };
+
+       std::unique_ptr<Geometry::Shape<float, 3>> shape;
+       std::string technique_name;
+       unsigned render_detail = 4;
+};
+
+class MSPGAME_API Shape: public Component
+{
+public:
+       using Setup = ShapeSetup;
+
+private:
+       const Setup &setup;
+
+public:
+       Shape(Handle<Entity> p, const Setup &s): Component(p), setup(s) { }
+
+       const Geometry::Shape<float, 3> *get_shape() const { return setup.shape.get(); }
+       const std::string &get_technique_name() const { return setup.technique_name; }
+       unsigned get_render_detail() const { return setup.render_detail; }
+};
+
+} // namespace Msp::Game
+
+#endif
index b521ccb76df91af06c5e15f3b0083112272a6243..0e71fc36df5d7bf2eb341824b829d39cfb3fcec8 100644 (file)
@@ -3,11 +3,13 @@
 #include <msp/game/light.h>
 #include <msp/game/meshsource.h>
 #include <msp/game/shadowtarget.h>
+#include <msp/game/shape.h>
 #include <msp/game/stage.h>
 #include <msp/game/transform.h>
 #include <msp/gl/colorcurve.h>
 #include <msp/gl/directionallight.h>
 #include <msp/gl/pointlight.h>
+#include <msp/gl/shape.h>
 #include "dynamicmeshsource.h"
 #include "lightemitter.h"
 #include "meshrenderer.h"
@@ -106,6 +108,18 @@ void Renderer::create_sequence()
 
 void Renderer::component_created(const Game::Events::ComponentCreated &event)
 {
+       Game::Handle<Game::Shape> shape = dynamic_handle_cast<Game::Shape>(event.component);
+       if(shape)
+       {
+               RenderedEntity &re = get_rendered_entity(event.component->get_entity());
+               if(!re.generated_mesh)
+               {
+                       const GL::Technique &tech = stage.get_resources().get<GL::Technique>(shape->get_technique_name());
+                       re.generated_mesh = Game::Owned<DynamicMeshSource>(re.entity, (GL::VERTEX3, GL::NORMAL3), tech);
+                       GL::ShapeBuilder(*shape->get_shape(), shape->get_render_detail()).build(re.generated_mesh->get_mesh());
+               }
+       }
+
        Game::Handle<Game::MeshSource> mesh_source = dynamic_handle_cast<Game::MeshSource>(event.component);
        Game::Handle<DynamicMeshSource> dyn_mesh_src = dynamic_handle_cast<DynamicMeshSource>(event.component);
        if(mesh_source || dyn_mesh_src)
@@ -149,6 +163,8 @@ void Renderer::component_destroyed(const Game::Events::ComponentDestroyed &event
        auto i = lower_bound_member(entities, entity, &RenderedEntity::entity);
        if(i!=entities.end() && i->entity==entity)
        {
+               if(dynamic_handle_cast<Game::Shape>(event.component))
+                       i->generated_mesh = nullptr;
                if(dynamic_handle_cast<Game::MeshSource>(event.component))
                        i->mesh_renderer = nullptr;
                if(auto light = dynamic_handle_cast<Game::Light>(event.component))
index 04d24391dbd875b7ccbac9602203bb6d33a0bee5..4657e35998b6b409c7da30ba4f9fb9dbe6b03dcf 100644 (file)
@@ -20,6 +20,7 @@
 
 namespace Msp::GameView {
 
+class DynamicMeshSource;
 class LightEmitter;
 class MeshRenderer;
 
@@ -29,6 +30,7 @@ private:
        struct RenderedEntity
        {
                Game::Handle<Game::Entity> entity;
+               Game::Owned<DynamicMeshSource> generated_mesh;
                Game::Owned<MeshRenderer> mesh_renderer;
                Game::Owned<LightEmitter> light_emitter;