]> git.tdb.fi Git - libs/gl.git/blob - source/grid.cpp
Drop Id tags and copyright notices from files
[libs/gl.git] / source / 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         origin(-w/2, -h/2, 0),
12         side1(w, 0, 0),
13         side2(0, h, 0),
14         norm(0, 0, 1),
15         binorm(0, 1, 0),
16         u_div(u),
17         v_div(v)
18 {
19         init(false);
20 }
21
22 GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s, unsigned u, unsigned v):
23         origin(o),
24         u_div(u),
25         v_div(v)
26 {
27         if(abs(s.z)<abs(s.x) && abs(s.z)<abs(s.y))
28         {
29                 side1 = Vector3(s.x, 0, 0);
30                 side2 = Vector3(0, s.y, 0);
31         }
32         else if(abs(s.y)<abs(s.x))
33         {
34                 side1 = Vector3(0, 0, s.z);
35                 side2 = Vector3(s.x, 0, 0);
36         }
37         else
38         {
39                 side1 = Vector3(0, s.y, 0);
40                 side2 = Vector3(0, 0, s.z);
41         }
42         init(true);
43 }
44
45 GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s1, const Vector3 &s2, unsigned u, unsigned v):
46         origin(o),
47         side1(s1),
48         side2(s2),
49         u_div(u),
50         v_div(v)
51 {
52         init(true);
53 }
54
55 void GridBuilder::init(bool compute_normals)
56 {
57         if(u_div<1)
58                 u_div = 1;
59         if(v_div<1)
60                 v_div = 1;
61
62         if(compute_normals)
63         {
64                 norm.x = side1.y*side2.z-side1.z*side2.y;
65                 norm.y = side1.z*side2.x-side1.x*side2.z;
66                 norm.z = side1.x*side2.y-side1.y*side2.x;
67                 float l = sqrt(norm.x*norm.x+norm.y*norm.y+norm.z*norm.z);
68                 norm.x /= l;
69                 norm.y /= l;
70                 norm.z /= l;
71
72                 binorm.x = norm.y*side1.z-norm.z*side1.y;
73                 binorm.y = norm.z*side1.x-norm.x*side1.z;
74                 binorm.z = norm.x*side1.y-norm.y*side1.x;
75                 l = sqrt(binorm.x*binorm.x+binorm.y*binorm.y+binorm.z*binorm.z);
76                 binorm.x /= l;
77                 binorm.y /= l;
78                 binorm.z /= l;
79         }
80 }
81
82 void GridBuilder::build(PrimitiveBuilder &builder) const
83 {
84         float l1_sq = side1.x*side1.x+side1.y*side1.y+side1.z*side1.z;
85         float l2 = side2.x*binorm.x+side2.y*binorm.y+side2.z*binorm.z;
86         float u_scale = 1/l1_sq;
87         float v_scale = 1/l2;
88         adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2);
89
90         builder.normal(norm.x, norm.y, norm.z);
91         if(tangent_attr>=0)
92                 builder.attrib(tangent_attr, side1.x, side1.y, side1.z);
93         if(binormal_attr>=0)
94                 builder.attrib(tangent_attr, binorm.x, binorm.y, binorm.z);
95
96         for(unsigned j=0; j<=v_div; ++j)
97         {
98                 float v = j*1.0/v_div;
99                 Vector3 row(origin.x+side2.x*v, origin.y+side2.y*v, origin.z+side2.z*v);
100                 v = (row.x*binorm.x+row.y*binorm.y+row.z*binorm.z)*v_scale;
101                 for(unsigned i=0; i<=u_div; ++i)
102                 {
103                         float u = i*1.0/u_div;
104                         Vector3 p(row.x+side1.x*u, row.y+side1.y*u, row.z+side1.z*u);
105                         u = (p.x*side1.x+p.y*side1.y+p.z*side1.z)*u_scale;
106                         builder.texcoord(u, v);
107                         builder.vertex(p);
108                 }
109         }
110
111         for(unsigned j=0; j<v_div; ++j)
112         {
113                 builder.begin(TRIANGLE_STRIP);
114                 for(unsigned i=0; i<=u_div; ++i)
115                 {
116                         builder.element((j+1)*(u_div+1)+i);
117                         builder.element(j*(u_div+1)+i);
118                 }
119                 builder.end();
120         }
121 }
122
123 } // namespace GL
124 } // namespace Msp