]> git.tdb.fi Git - libs/gl.git/blob - source/builders/grid.cpp
f452c438fa5f3932281e919ae9e0c615bcf9c788
[libs/gl.git] / source / builders / grid.cpp
1 #include <cmath>
2 #include "grid.h"
3 #include "primitivebuilder.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace GL {
9
10 GridBuilder::GridBuilder(float w, float h, unsigned u, unsigned v):
11         GridBuilder(Vector3(-w/2, -h/2, 0), Vector3(w, 0, 0), Vector3(0, h, 0), u, v)
12 { }
13
14 GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s, unsigned u, unsigned v):
15         GridBuilder(o, get_side(s, 0), get_side(s, 1), u, v)
16 { }
17
18 GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s1, const Vector3 &s2, unsigned u, unsigned v):
19         origin(o),
20         side1(s1),
21         side2(s2),
22         u_div(max(u, 1U)),
23         v_div(max(v, 1U))
24 {
25         norm = normalize(cross(side1, side2));
26         binorm = normalize(cross(norm, side1));
27 }
28
29 Vector3 GridBuilder::get_side(const Vector3 &size, unsigned index)
30 {
31         if(!size.x)
32                 return Vector3(0, (index==0 ? size.y : 0), (index==1 ? size.z : 0));
33         else if(!size.y)
34                 return Vector3((index==0 ? size.x : 0), 0, (index==1 ? size.z : 0));
35         else
36                 return Vector3((index==0 ? size.x : 0), (index==1 ? size.z : 0), 0);
37 }
38
39 void GridBuilder::build(PrimitiveBuilder &builder) const
40 {
41         float l1_sq = dot(side1, side1);
42         float l2 = dot(side2, binorm);
43         float u_scale = 1/l1_sq;
44         float v_scale = 1/l2;
45         adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2);
46
47         builder.normal(norm.x, norm.y, norm.z);
48         if(generate_tan)
49                 builder.tangent(side1);
50
51         for(unsigned j=0; j<=v_div; ++j)
52         {
53                 Vector3 row = side2*(j*1.0f/v_div);
54                 float v = dot(row, binorm)*v_scale;
55                 for(unsigned i=0; i<=u_div; ++i)
56                 {
57                         Vector3 p = row+side1*(i*1.0f/u_div);
58                         float u = dot(p, side1)*u_scale;
59                         builder.texcoord(u, v);
60                         builder.vertex(origin+p);
61                 }
62         }
63
64         for(unsigned j=0; j<v_div; ++j)
65         {
66                 builder.begin(TRIANGLE_STRIP);
67                 for(unsigned i=0; i<=u_div; ++i)
68                 {
69                         builder.element((j+1)*(u_div+1)+i);
70                         builder.element(j*(u_div+1)+i);
71                 }
72                 builder.end();
73         }
74 }
75
76 } // namespace GL
77 } // namespace Msp