]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a builder for turning geometric shapes into meshes
authorMikko Rasa <tdb@tdb.fi>
Sun, 26 Jan 2025 15:02:45 +0000 (17:02 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 26 Jan 2025 15:02:45 +0000 (17:02 +0200)
source/builders/shape.cpp [new file with mode: 0644]
source/builders/shape.h [new file with mode: 0644]

diff --git a/source/builders/shape.cpp b/source/builders/shape.cpp
new file mode 100644 (file)
index 0000000..234f5b8
--- /dev/null
@@ -0,0 +1,48 @@
+#include <msp/geometry/extrudedshape.h>
+#include <msp/geometry/hyperbox.h>
+#include <msp/geometry/hypersphere.h>
+#include <msp/gl/error.h>
+#include "box.h"
+#include "cylinder.h"
+#include "shape.h"
+#include "sphere.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+ShapeBuilder::ShapeBuilder(const Geometry::Shape<float, 3> &s, unsigned d):
+       shape(s),
+       detail(d)
+{
+       if(detail<1)
+               detail = 1;
+}
+
+void ShapeBuilder::build(PrimitiveBuilder &builder) const
+{
+       if(const auto *sphere = dynamic_cast<const Geometry::HyperSphere<float, 3> *>(&shape))
+               return make_builder<IcoSphereBuilder>(sphere->get_radius(), detail).build(builder);
+       else if(const auto *box = dynamic_cast<const Geometry::HyperBox<float, 3> *>(&shape))
+               return make_builder<BoxBuilder>(box->get_dimension(0), box->get_dimension(1), box->get_dimension(2)).build(builder);
+       else if(const auto *ext = dynamic_cast<const Geometry::ExtrudedShape<float, 3> *>(&shape))
+       {
+               if(const auto *circle = dynamic_cast<const Geometry::HyperSphere<float, 2> *>(&ext->get_base()))
+                       return make_builder<CylinderBuilder>(circle->get_radius(), ext->get_length(), detail*6).build(builder);
+       }
+
+       throw invalid_operation("ShapeBuilder::build");
+}
+
+template<typename T, typename... Args>
+T ShapeBuilder::make_builder(Args &&... args) const
+{
+       T bld(forward<Args>(args)...);
+       bld.tangents(generate_tan);
+       bld.texture_fit(tex_fit);
+       return bld;
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/builders/shape.h b/source/builders/shape.h
new file mode 100644 (file)
index 0000000..f680744
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef MSP_GL_SHAPE_H_
+#define MSP_GL_SHAPE_H_
+
+#include <msp/geometry/shape.h>
+#include "geometrybuilder.h"
+
+namespace Msp {
+namespace GL {
+
+class MSPGL_API ShapeBuilder: public GeometryBuilder
+{
+private:
+       const Geometry::Shape<float, 3> &shape;
+       unsigned detail = 1;
+
+public:
+       ShapeBuilder(const Geometry::Shape<float, 3> &, unsigned);
+
+       using GeometryBuilder::build;
+       void build(PrimitiveBuilder &) const override;
+private:
+       template<typename T, typename... Args>
+       T make_builder(Args &&...) const;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif