]> git.tdb.fi Git - libs/gl.git/blobdiff - source/builders/grid.cpp
Rearrange soucre files into subdirectories
[libs/gl.git] / source / builders / grid.cpp
diff --git a/source/builders/grid.cpp b/source/builders/grid.cpp
new file mode 100644 (file)
index 0000000..3f4d5e2
--- /dev/null
@@ -0,0 +1,110 @@
+#include <cmath>
+#include "grid.h"
+#include "primitivebuilder.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+GridBuilder::GridBuilder(float w, float h, unsigned u, unsigned v):
+       origin(-w/2, -h/2, 0),
+       side1(w, 0, 0),
+       side2(0, h, 0),
+       norm(0, 0, 1),
+       binorm(0, 1, 0),
+       u_div(u),
+       v_div(v)
+{
+       init(false);
+}
+
+GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s, unsigned u, unsigned v):
+       origin(o),
+       u_div(u),
+       v_div(v)
+{
+       if(abs(s.z)<abs(s.x) && abs(s.z)<abs(s.y))
+       {
+               side1 = Vector3(s.x, 0, 0);
+               side2 = Vector3(0, s.y, 0);
+       }
+       else if(abs(s.y)<abs(s.x))
+       {
+               side1 = Vector3(0, 0, s.z);
+               side2 = Vector3(s.x, 0, 0);
+       }
+       else
+       {
+               side1 = Vector3(0, s.y, 0);
+               side2 = Vector3(0, 0, s.z);
+       }
+       init(true);
+}
+
+GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s1, const Vector3 &s2, unsigned u, unsigned v):
+       origin(o),
+       side1(s1),
+       side2(s2),
+       u_div(u),
+       v_div(v)
+{
+       init(true);
+}
+
+void GridBuilder::init(bool compute_normals)
+{
+       if(u_div<1)
+               u_div = 1;
+       if(v_div<1)
+               v_div = 1;
+
+       if(compute_normals)
+       {
+               norm = normalize(cross(side1, side2));
+               binorm = normalize(cross(norm, side1));
+       }
+}
+
+void GridBuilder::build(PrimitiveBuilder &builder) const
+{
+       float l1_sq = dot(side1, side1);
+       float l2 = dot(side2, binorm);
+       float u_scale = 1/l1_sq;
+       float v_scale = 1/l2;
+       adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2);
+
+       builder.normal(norm.x, norm.y, norm.z);
+       if(generate_tbn)
+       {
+               builder.tangent(side1);
+               builder.binormal(binorm);
+       }
+
+       for(unsigned j=0; j<=v_div; ++j)
+       {
+               Vector3 row = side2*(j*1.0f/v_div);
+               float v = dot(row, binorm)*v_scale;
+               for(unsigned i=0; i<=u_div; ++i)
+               {
+                       Vector3 p = row+side1*(i*1.0f/u_div);
+                       float u = dot(p, side1)*u_scale;
+                       builder.texcoord(u, v);
+                       builder.vertex(origin+p);
+               }
+       }
+
+       for(unsigned j=0; j<v_div; ++j)
+       {
+               builder.begin(TRIANGLE_STRIP);
+               for(unsigned i=0; i<=u_div; ++i)
+               {
+                       builder.element((j+1)*(u_div+1)+i);
+                       builder.element(j*(u_div+1)+i);
+               }
+               builder.end();
+       }
+}
+
+} // namespace GL
+} // namespace Msp