]> git.tdb.fi Git - libs/gl.git/blob - source/grid.cpp
Add capsule and grid builders
[libs/gl.git] / source / grid.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2011  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <cmath>
9 #include "grid.h"
10 #include "primitivebuilder.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 GridBuilder::GridBuilder(float w, float h, unsigned u, unsigned v):
18         origin(-w/2, -h/2, 0),
19         side1(w, 0, 0),
20         side2(0, h, 0),
21         norm(0, 0, 1),
22         binorm(0, 1, 0),
23         u_div(u),
24         v_div(v)
25 {
26         init(false);
27 }
28
29 GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s, unsigned u, unsigned v):
30         origin(o),
31         u_div(u),
32         v_div(v)
33 {
34         if(abs(s.z)<abs(s.x) && abs(s.z)<abs(s.y))
35         {
36                 side1 = Vector3(s.x, 0, 0);
37                 side2 = Vector3(0, s.y, 0);
38         }
39         else if(abs(s.y)<abs(s.x))
40         {
41                 side1 = Vector3(0, 0, s.z);
42                 side2 = Vector3(s.x, 0, 0);
43         }
44         else
45         {
46                 side1 = Vector3(0, s.y, 0);
47                 side2 = Vector3(0, 0, s.z);
48         }
49         init(true);
50 }
51
52 GridBuilder::GridBuilder(const Vector3 &o, const Vector3 &s1, const Vector3 &s2, unsigned u, unsigned v):
53         origin(o),
54         side1(s1),
55         side2(s2),
56         u_div(u),
57         v_div(v)
58 {
59         init(true);
60 }
61
62 void GridBuilder::init(bool compute_normals)
63 {
64         if(u_div<1)
65                 u_div = 1;
66         if(v_div<1)
67                 v_div = 1;
68
69         if(compute_normals)
70         {
71                 norm.x = side1.y*side2.z-side1.z*side2.y;
72                 norm.y = side1.z*side2.x-side1.x*side2.z;
73                 norm.z = side1.x*side2.y-side1.y*side2.x;
74                 float l = sqrt(norm.x*norm.x+norm.y*norm.y+norm.z*norm.z);
75                 norm.x /= l;
76                 norm.y /= l;
77                 norm.z /= l;
78
79                 binorm.x = norm.y*side1.z-norm.z*side1.y;
80                 binorm.y = norm.z*side1.x-norm.x*side1.z;
81                 binorm.z = norm.x*side1.y-norm.y*side1.x;
82                 l = sqrt(binorm.x*binorm.x+binorm.y*binorm.y+binorm.z*binorm.z);
83                 binorm.x /= l;
84                 binorm.y /= l;
85                 binorm.z /= l;
86         }
87 }
88
89 void GridBuilder::build(PrimitiveBuilder &builder) const
90 {
91         float l1_sq = side1.x*side1.x+side1.y*side1.y+side1.z*side1.z;
92         float l2 = side2.x*binorm.x+side2.y*binorm.y+side2.z*binorm.z;
93         float u_scale = 1/l1_sq;
94         float v_scale = 1/l2;
95         adjust_texture_scale(u_scale, v_scale, sqrt(l1_sq), l2);
96
97         builder.normal(norm.x, norm.y, norm.z);
98         if(tangent_attr>=0)
99                 builder.attrib(tangent_attr, side1.x, side1.y, side1.z);
100         if(binormal_attr>=0)
101                 builder.attrib(tangent_attr, binorm.x, binorm.y, binorm.z);
102
103         for(unsigned j=0; j<=v_div; ++j)
104         {
105                 float v = j*1.0/v_div;
106                 Vector3 row(origin.x+side2.x*v, origin.y+side2.y*v, origin.z+side2.z*v);
107                 v = (row.x*binorm.x+row.y*binorm.y+row.z*binorm.z)*v_scale;
108                 for(unsigned i=0; i<=u_div; ++i)
109                 {
110                         float u = i*1.0/u_div;
111                         Vector3 p(row.x+side1.x*u, row.y+side1.y*u, row.z+side1.z*u);
112                         u = (p.x*side1.x+p.y*side1.y+p.z*side1.z)*u_scale;
113                         builder.texcoord(u, v);
114                         builder.vertex(p);
115                 }
116         }
117
118         for(unsigned j=0; j<v_div; ++j)
119         {
120                 builder.begin(TRIANGLE_STRIP);
121                 for(unsigned i=0; i<=u_div; ++i)
122                 {
123                         builder.element((j+1)*(u_div+1)+i);
124                         builder.element(j*(u_div+1)+i);
125                 }
126                 builder.end();
127         }
128 }
129
130 } // namespace GL
131 } // namespace Msp