]> git.tdb.fi Git - libs/gl.git/blobdiff - source/builders/cylinder.cpp
Rearrange soucre files into subdirectories
[libs/gl.git] / source / builders / cylinder.cpp
diff --git a/source/builders/cylinder.cpp b/source/builders/cylinder.cpp
new file mode 100644 (file)
index 0000000..901a0f4
--- /dev/null
@@ -0,0 +1,86 @@
+#define _USE_MATH_DEFINES
+#include <cmath>
+#include "cylinder.h"
+#include "primitivebuilder.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+CylinderBuilder::CylinderBuilder(float r, float l, unsigned s):
+       radius(r),
+       length(l),
+       segments(s)
+{
+       if(segments<3)
+               segments = 3;
+}
+
+void CylinderBuilder::build(PrimitiveBuilder &builder) const
+{
+       if(generate_tbn)
+               builder.binormal(0, 1, 0);
+       for(unsigned i=0; i<2; ++i)
+       {
+               float z = (i-0.5)*length;
+               builder.normal(0, 0, i*2.0-1.0);
+               builder.texcoord(0.5, 0.5);
+               if(generate_tbn)
+                       builder.tangent((i ? 1 : -1), 0, 0);
+               builder.vertex(0, 0, z);
+               for(unsigned j=0; j<segments; ++j)
+               {
+                       float a = j*M_PI*2/segments;
+                       float c = cos(a);
+                       float s = sin(a);
+                       builder.texcoord(0.5+(i ? 0.5 : -0.5)*c, 0.5+0.5*s);
+                       builder.vertex(radius*c, radius*s, z);
+               }
+       }
+
+       float u_scale = 1.0/segments;
+       float v_scale = 1;
+       adjust_texture_scale(u_scale, v_scale, radius*M_PI*2, length);
+
+       if(generate_tbn)
+               builder.binormal(0, 0, 1);
+       for(unsigned i=0; i<2; ++i)
+       {
+               float z = (i-0.5)*length;
+               for(unsigned j=0; j<=segments; ++j)
+               {
+                       float a = j*M_PI*2/segments;
+                       float c = cos(a);
+                       float s = sin(a);
+                       builder.normal(c, s, 0);
+                       builder.texcoord(j*u_scale, i*v_scale);
+                       if(generate_tbn)
+                               builder.tangent(-s, c, 0);
+                       builder.vertex(radius*c, radius*s, z);
+               }
+       }
+
+       unsigned base = 0;
+       for(unsigned i=0; i<2; ++i)
+       {
+               builder.begin(TRIANGLE_FAN);
+               builder.element(base);
+               for(unsigned j=0; j<=segments; ++j)
+                       builder.element(base+1+j%segments);
+               builder.end();
+
+               base += segments+1;
+       }
+
+       builder.begin(TRIANGLE_STRIP);
+       for(unsigned j=0; j<=segments; ++j)
+       {
+               builder.element(base+segments+1+j);
+               builder.element(base+j);
+       }
+       builder.end();
+}
+
+} // namespace GL
+} // namespace Msp