--- /dev/null
+#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
--- /dev/null
+#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
#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"
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)
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))
namespace Msp::GameView {
+class DynamicMeshSource;
class LightEmitter;
class MeshRenderer;
struct RenderedEntity
{
Game::Handle<Game::Entity> entity;
+ Game::Owned<DynamicMeshSource> generated_mesh;
Game::Owned<MeshRenderer> mesh_renderer;
Game::Owned<LightEmitter> light_emitter;