--- /dev/null
+#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