]> git.tdb.fi Git - libs/gl.git/commitdiff
Add classes for building some geometric shapes
authorMikko Rasa <tdb@tdb.fi>
Wed, 26 Jan 2011 15:23:26 +0000 (15:23 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Jan 2011 15:23:26 +0000 (15:23 +0000)
source/box.cpp [new file with mode: 0644]
source/box.h [new file with mode: 0644]
source/capsule.cpp [new file with mode: 0644]
source/capsule.h [new file with mode: 0644]
source/geometrybuilder.cpp [new file with mode: 0644]
source/geometrybuilder.h [new file with mode: 0644]

diff --git a/source/box.cpp b/source/box.cpp
new file mode 100644 (file)
index 0000000..3d6f15f
--- /dev/null
@@ -0,0 +1,74 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <cmath>
+#include "box.h"
+#include "primitivebuilder.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+BoxBuilder::BoxBuilder(float w, float h, float d):
+       origin(-w/2, -h/2, -d/2),
+       span(w, h, d)
+{ }
+
+BoxBuilder::BoxBuilder(const Vector3 &o, const Vector3 &s):
+       origin(o),
+       span(s)
+{ }
+
+void BoxBuilder::build(PrimitiveBuilder &builder) const
+{
+       builder.normal(1, 0, 0);
+       build_face(builder, Vector3(origin.x+span.x, origin.y, origin.z), Vector3(0, span.y, 0), Vector3(0, 0, span.z));
+       builder.normal(0, 1, 0);
+       build_face(builder, Vector3(origin.x+span.x, origin.y+span.y, origin.z), Vector3(-span.x, 0, 0), Vector3(0, 0, span.z));
+       builder.normal(-1, 0, 0);
+       build_face(builder, Vector3(origin.x, origin.y+span.y, origin.z), Vector3(0, -span.y, 0), Vector3(0, 0, span.z));
+       builder.normal(0, -1, 0);
+       build_face(builder, origin, Vector3(span.x, 0, 0), Vector3(0, 0, span.z));
+       builder.normal(0, 0, 1);
+       build_face(builder, Vector3(origin.x, origin.y, origin.z+span.z), Vector3(span.x, 0, 0), Vector3(0, span.y, 0));
+       builder.normal(0, 0, -1);
+       build_face(builder, Vector3(origin.x+span.x, origin.y, origin.z), Vector3(-span.x, 0, 0), Vector3(0, span.y, 0));
+}
+
+void BoxBuilder::build_face(PrimitiveBuilder &builder, const Vector3 &o, const Vector3 &s1, const Vector3 &s2) const
+{
+       if(tangent_attr>=0)
+       {
+               builder.attrib(tangent_attr, s1.x, s1.y, s1.z);
+               builder.attrib(binormal_attr, s2.x, s2.y, s2.z);
+       }
+       float u_size = 1;
+       float v_size = 1;
+       if(tex_fit!=STRETCH)
+       {
+               float l1 = sqrt(s1.x*s1.x+s1.y*s1.y+s1.z*s1.z);
+               float l2 = sqrt(s2.x*s2.x+s2.y*s2.y+s2.z*s2.z);
+               if((l1<l2)==(tex_fit==CUT))
+                       u_size = l1/l2;
+               else
+                       v_size = l2/l1;
+       }
+       builder.begin(TRIANGLE_STRIP);
+       builder.texcoord(0, v_size);
+       builder.vertex(o.x+s2.x, o.y+s2.y, o.z+s2.z);
+       builder.texcoord(0, 0);
+       builder.vertex(o.x, o.y, o.z);
+       builder.texcoord(u_size, v_size);
+       builder.vertex(o.x+s1.x+s2.x, o.y+s1.y+s2.y, o.z+s1.z+s2.z);
+       builder.texcoord(u_size, 0);
+       builder.vertex(o.x+s1.x, o.y+s1.y, o.z+s1.z);
+       builder.end();
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/box.h b/source/box.h
new file mode 100644 (file)
index 0000000..7e4b3e5
--- /dev/null
@@ -0,0 +1,35 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_BOX_H_
+#define MSP_GL_BOX_H_
+
+#include "geometrybuilder.h"
+#include "vector.h"
+
+namespace Msp {
+namespace GL {
+
+class BoxBuilder: public GeometryBuilder
+{
+private:
+       Vector3 origin;
+       Vector3 span;
+
+public:
+       BoxBuilder(float, float, float);
+       BoxBuilder(const Vector3 &, const Vector3 &);
+
+       virtual void build(PrimitiveBuilder &) const;
+private:
+       void build_face(PrimitiveBuilder &, const Vector3 &, const Vector3 &, const Vector3 &) const;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
diff --git a/source/capsule.cpp b/source/capsule.cpp
new file mode 100644 (file)
index 0000000..86f5d57
--- /dev/null
@@ -0,0 +1,88 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <cmath>
+#include "capsule.h"
+#include "primitivebuilder.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+CapsuleBuilder::CapsuleBuilder(float r, float l, unsigned s, unsigned n):
+       radius(r),
+       length(l),
+       segments(s),
+       rings(n)
+{
+       if(segments<3)
+               segments = 3;
+       rings |= 1;
+       if(rings<3)
+               rings = 3;
+}
+
+void CapsuleBuilder::build(PrimitiveBuilder &builder) const
+{
+       float u_scale = 1.0/segments;
+       float v_scale = 1/(length+radius*M_PI);
+       if(tex_fit!=STRETCH)
+       {
+               float l1 = radius*M_PI*2;
+               float l2 = length+radius*M_PI;
+               if((l1<l2)==(tex_fit==CUT))
+                       u_scale *= l1/l2;
+               else
+                       v_scale *= l2/l1;
+       }
+
+       builder.normal(0, 0, -1);
+       builder.texcoord(0.5, 0);
+       builder.vertex(0, 0, -length/2+radius);
+       for(unsigned i=1; i<rings; ++i)
+       {
+               float cz = length*(i>rings/2 ? 0.5 : -0.5);
+               float v = (i*radius*M_PI/rings+(i>rings/2 ? length : 0))*v_scale;
+               float ra = (i>rings/2 ? i-1 : i)*M_PI/(rings-1);
+               float rc = cos(ra);
+               float rs = sin(ra);
+               for(unsigned j=0; j<=segments; ++j)
+               {
+                       float sa = j*M_PI*2/segments;
+                       float sc = cos(sa);
+                       float ss = sin(sa);
+                       builder.normal(rs*sc, rs*ss, -rc);
+                       if(tangent_attr)
+                       {
+                               builder.attrib(tangent_attr, -ss, sc, 0);
+                               builder.attrib(binormal_attr, rc*sc, rc*ss, rs);
+                       }
+                       builder.texcoord(j*u_scale, v);
+                       builder.vertex(rs*sc*radius, rs*ss*radius, cz-rc*radius);
+               }
+       }
+       builder.normal(0, 0, 1);
+       builder.texcoord(0.5, (length+radius*M_PI)*v_scale);
+       builder.vertex(0, 0, length/2-radius);
+
+       for(unsigned i=0; i<segments; ++i)
+       {
+               builder.begin(GL::TRIANGLE_STRIP);
+               builder.element(0);
+               for(unsigned j=0; j+1<rings; ++j)
+               {
+                       builder.element(1+j*(segments+1)+i+1);
+                       builder.element(1+j*(segments+1)+i);
+               }
+               builder.element((segments+1)*(rings-1)+1);
+               builder.end();
+       }
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/capsule.h b/source/capsule.h
new file mode 100644 (file)
index 0000000..456a782
--- /dev/null
@@ -0,0 +1,33 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_CAPSULE_H_
+#define MSP_GL_CAPSULE_H_
+
+#include <msp/gl/geometrybuilder.h>
+
+namespace Msp {
+namespace GL {
+
+class CapsuleBuilder: public GeometryBuilder
+{
+private:
+       float radius;
+       float length;
+       unsigned segments;
+       unsigned rings;
+
+public:
+       CapsuleBuilder(float, float, unsigned = 16, unsigned = 9);
+
+       virtual void build(PrimitiveBuilder &) const;
+};
+
+} // namepace GL
+} // namespace Msp
+
+#endif
diff --git a/source/geometrybuilder.cpp b/source/geometrybuilder.cpp
new file mode 100644 (file)
index 0000000..97c88e0
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "geometrybuilder.h"
+#include "meshbuilder.h"
+
+namespace Msp {
+namespace GL {
+
+GeometryBuilder::GeometryBuilder():
+       tangent_attr(-1),
+       binormal_attr(-1),
+       tex_fit(STRETCH)
+{ }
+
+GeometryBuilder &GeometryBuilder::tangent(unsigned t)
+{
+       tangent_attr = t;
+       return *this;
+}
+
+GeometryBuilder &GeometryBuilder::binormal(unsigned b)
+{
+       binormal_attr = b;
+       return *this;
+}
+
+GeometryBuilder &GeometryBuilder::texture_fit(TextureFit tf)
+{
+       tex_fit = tf;
+       return *this;
+}
+
+void GeometryBuilder::build(Mesh &mesh) const
+{
+       MeshBuilder builder(mesh);
+       build(builder);
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/geometrybuilder.h b/source/geometrybuilder.h
new file mode 100644 (file)
index 0000000..a0538b5
--- /dev/null
@@ -0,0 +1,46 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2011  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_GEOMETRYBUILDER_H_
+#define MSP_GL_GEOMETRYBUILDER_H_
+
+namespace Msp {
+namespace GL {
+
+class Mesh;
+class PrimitiveBuilder;
+
+class GeometryBuilder
+{
+public:
+       enum TextureFit
+       {
+               STRETCH,
+               CUT,
+               WRAP
+       };
+
+protected:
+       int tangent_attr;
+       int binormal_attr;
+       TextureFit tex_fit;
+
+       GeometryBuilder();
+
+public:
+       GeometryBuilder &tangent(unsigned);
+       GeometryBuilder &binormal(unsigned);
+       GeometryBuilder &texture_fit(TextureFit);
+
+       virtual void build(PrimitiveBuilder &) const = 0;
+       void build(Mesh &) const;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif