]> git.tdb.fi Git - libs/gl.git/blobdiff - source/builders/capsule.cpp
Rearrange soucre files into subdirectories
[libs/gl.git] / source / builders / capsule.cpp
diff --git a/source/builders/capsule.cpp b/source/builders/capsule.cpp
new file mode 100644 (file)
index 0000000..65a18eb
--- /dev/null
@@ -0,0 +1,74 @@
+#define _USE_MATH_DEFINES
+#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);
+       adjust_texture_scale(u_scale, v_scale, radius*M_PI*2, length+radius*M_PI);
+
+       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>rings/2 ? i-1 : i)*radius*M_PI/(rings-1)+(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(generate_tbn)
+                       {
+                               builder.tangent(-ss, sc, 0);
+                               builder.binormal(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(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