glVertex  5.5.2
glvertex_geometry.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 
5 #ifndef GLVERTEX_GEOMETRY_H
6 #define GLVERTEX_GEOMETRY_H
7 
8 #include "glvertex.h"
9 #include "glvertex_bezier.h"
10 #include "glvertex_objformat.h"
11 #include "glvertex_vectortext.h"
12 
19 class lglCube: public lglVBO
20 {
21 public:
22 
23  lglCube(bool color = false)
24  : lglVBO("cube")
25  {
26  addQuads(this, color);
27  }
28 
29  static void addQuads(lglVBO *vbo, bool color = false, double dx = 1, double dy = 1, double dz = 1, bool facecolors = true)
30  {
31  vec4 col = vbo->lglGetColor();
32 
33  vbo->lglBegin(LGL_QUADS);
34 
35  if (color && !facecolors) vbo->lglColor(col);
36 
37  // left quad
38  if (color && facecolors) vbo->lglColor(1,0,0);
39  vbo->lglNormal(-1,0,0);
40  vbo->lglTexCoord(0,0);
41  vbo->lglVertex(-0.5*dx,-0.5*dy,-0.5*dz);
42  vbo->lglTexCoord(0,1);
43  vbo->lglVertex(-0.5*dx,-0.5*dy,0.5*dz);
44  vbo->lglTexCoord(-1,1);
45  vbo->lglVertex(-0.5*dx,0.5*dy,0.5*dz);
46  vbo->lglTexCoord(-1,0);
47  vbo->lglVertex(-0.5*dx,0.5*dy,-0.5*dz);
48 
49  // right quad
50  if (color && facecolors) vbo->lglColor(0,1,1);
51  vbo->lglNormal(1,0,0);
52  vbo->lglTexCoord(1,0);
53  vbo->lglVertex(0.5*dx,-0.5*dy,0.5*dz);
54  vbo->lglTexCoord(1,1);
55  vbo->lglVertex(0.5*dx,-0.5*dy,-0.5*dz);
56  vbo->lglTexCoord(2,1);
57  vbo->lglVertex(0.5*dx,0.5*dy,-0.5*dz);
58  vbo->lglTexCoord(2,0);
59  vbo->lglVertex(0.5*dx,0.5*dy,0.5*dz);
60 
61  // front quad
62  if (color && facecolors) vbo->lglColor(0,1,0);
63  vbo->lglNormal(0,0,1);
64  vbo->lglTexCoord(0,0);
65  vbo->lglVertex(-0.5*dx,-0.5*dy,0.5*dz);
66  vbo->lglTexCoord(1,0);
67  vbo->lglVertex(0.5*dx,-0.5*dy,0.5*dz);
68  vbo->lglTexCoord(1,-1);
69  vbo->lglVertex(0.5*dx,0.5*dy,0.5*dz);
70  vbo->lglTexCoord(0,-1);
71  vbo->lglVertex(-0.5*dx,0.5*dy,0.5*dz);
72 
73  // back quad
74  if (color && facecolors) vbo->lglColor(1,0,1);
75  vbo->lglNormal(0,0,-1);
76  vbo->lglTexCoord(1,1);
77  vbo->lglVertex(0.5*dx,-0.5*dy,-0.5*dz);
78  vbo->lglTexCoord(0,1);
79  vbo->lglVertex(-0.5*dx,-0.5*dy,-0.5*dz);
80  vbo->lglTexCoord(0,2);
81  vbo->lglVertex(-0.5*dx,0.5*dy,-0.5*dz);
82  vbo->lglTexCoord(1,2);
83  vbo->lglVertex(0.5*dx,0.5*dy,-0.5*dz);
84 
85  // bottom quad
86  if (color && facecolors) vbo->lglColor(0,0,1);
87  vbo->lglNormal(0,-1,0);
88  vbo->lglTexCoord(0,1);
89  vbo->lglVertex(-0.5*dx,-0.5*dy,-0.5*dz);
90  vbo->lglTexCoord(1,1);
91  vbo->lglVertex(0.5*dx,-0.5*dy,-0.5*dz);
92  vbo->lglTexCoord(1,0);
93  vbo->lglVertex(0.5*dx,-0.5*dy,0.5*dz);
94  vbo->lglTexCoord(0,0);
95  vbo->lglVertex(-0.5*dx,-0.5*dy,0.5*dz);
96 
97  // top quad
98  if (color && facecolors) vbo->lglColor(1,1,0);
99  vbo->lglNormal(0,1,0);
100  vbo->lglTexCoord(3,0);
101  vbo->lglVertex(-0.5*dx,0.5*dy,0.5*dz);
102  vbo->lglTexCoord(2,0);
103  vbo->lglVertex(0.5*dx,0.5*dy,0.5*dz);
104  vbo->lglTexCoord(2,1);
105  vbo->lglVertex(0.5*dx,0.5*dy,-0.5*dz);
106  vbo->lglTexCoord(3,1);
107  vbo->lglVertex(-0.5*dx,0.5*dy,-0.5*dz);
108 
109  vbo->lglEnd();
110  }
111 
112  static void addTo(lglVBO *vbo, bool color = false, double dx = 1, double dy = 1, double dz = 1, bool facecolors = true)
113  {
114  vec4 col = vbo->lglGetColor();
115 
116  vbo->lglBegin(LGL_QUAD_STRIP);
117 
118  if (color && !facecolors) vbo->lglColor(col);
119 
120  // left quad
121  if (color && facecolors) vbo->lglColor(1,0,0);
122  vbo->lglNormal(-1,0,0);
123  vbo->lglTexCoord(0,0);
124  vbo->lglVertex(-0.5*dx,-0.5*dy,-0.5*dz);
125  vbo->lglTexCoord(0,1);
126  vbo->lglVertex(-0.5*dx,-0.5*dy,0.5*dz);
127  vbo->lglTexCoord(-1,0);
128  vbo->lglVertex(-0.5*dx,0.5*dy,-0.5*dz);
129  vbo->lglTexCoord(-1,1);
130  vbo->lglVertex(-0.5*dx,0.5*dy,0.5*dz);
131 
132  vbo->lglEnd();
133 
134  vbo->lglBegin(LGL_QUAD_STRIP);
135 
136  // right quad
137  if (color && facecolors) vbo->lglColor(0,1,1);
138  vbo->lglNormal(1,0,0);
139  vbo->lglTexCoord(1,0);
140  vbo->lglVertex(0.5*dx,-0.5*dy,0.5*dz);
141  vbo->lglTexCoord(1,1);
142  vbo->lglVertex(0.5*dx,-0.5*dy,-0.5*dz);
143  vbo->lglTexCoord(2,0);
144  vbo->lglVertex(0.5*dx,0.5*dy,0.5*dz);
145  vbo->lglTexCoord(2,1);
146  vbo->lglVertex(0.5*dx,0.5*dy,-0.5*dz);
147 
148  vbo->lglEnd();
149 
150  vbo->lglBegin(LGL_QUAD_STRIP);
151 
152  // front quad
153  if (color && facecolors) vbo->lglColor(0,1,0);
154  vbo->lglNormal(0,0,1);
155  vbo->lglTexCoord(0,0);
156  vbo->lglVertex(-0.5*dx,-0.5*dy,0.5*dz);
157  vbo->lglTexCoord(1,0);
158  vbo->lglVertex(0.5*dx,-0.5*dy,0.5*dz);
159  vbo->lglTexCoord(0,-1);
160  vbo->lglVertex(-0.5*dx,0.5*dy,0.5*dz);
161  vbo->lglTexCoord(1,-1);
162  vbo->lglVertex(0.5*dx,0.5*dy,0.5*dz);
163 
164  vbo->lglEnd();
165 
166  vbo->lglBegin(LGL_QUAD_STRIP);
167 
168  // back quad
169  if (color && facecolors) vbo->lglColor(1,0,1);
170  vbo->lglNormal(0,0,-1);
171  vbo->lglTexCoord(1,1);
172  vbo->lglVertex(0.5*dx,-0.5*dy,-0.5*dz);
173  vbo->lglTexCoord(0,1);
174  vbo->lglVertex(-0.5*dx,-0.5*dy,-0.5*dz);
175  vbo->lglTexCoord(1,2);
176  vbo->lglVertex(0.5*dx,0.5*dy,-0.5*dz);
177  vbo->lglTexCoord(0,2);
178  vbo->lglVertex(-0.5*dx,0.5*dy,-0.5*dz);
179 
180  vbo->lglEnd();
181 
182  vbo->lglBegin(LGL_QUAD_STRIP);
183 
184  // bottom quad
185  if (color && facecolors) vbo->lglColor(0,0,1);
186  vbo->lglNormal(0,-1,0);
187  vbo->lglTexCoord(0,1);
188  vbo->lglVertex(-0.5*dx,-0.5*dy,-0.5*dz);
189  vbo->lglTexCoord(1,1);
190  vbo->lglVertex(0.5*dx,-0.5*dy,-0.5*dz);
191  vbo->lglTexCoord(0,0);
192  vbo->lglVertex(-0.5*dx,-0.5*dy,0.5*dz);
193  vbo->lglTexCoord(1,0);
194  vbo->lglVertex(0.5*dx,-0.5*dy,0.5*dz);
195 
196  vbo->lglEnd();
197 
198  vbo->lglBegin(LGL_QUAD_STRIP);
199 
200  // top quad
201  if (color && facecolors) vbo->lglColor(1,1,0);
202  vbo->lglNormal(0,1,0);
203  vbo->lglTexCoord(3,0);
204  vbo->lglVertex(-0.5*dx,0.5*dy,0.5*dz);
205  vbo->lglTexCoord(2,0);
206  vbo->lglVertex(0.5*dx,0.5*dy,0.5*dz);
207  vbo->lglTexCoord(3,1);
208  vbo->lglVertex(-0.5*dx,0.5*dy,-0.5*dz);
209  vbo->lglTexCoord(2,1);
210  vbo->lglVertex(0.5*dx,0.5*dy,-0.5*dz);
211 
212  vbo->lglEnd();
213  }
214 
215 };
216 
222 class lglBox: public lglVBO
223 {
224 public:
225 
226  lglBox(double dx, double dy, double dz,
227  bool color = false)
228  : lglVBO("box")
229  {
230  lglCube::addQuads(this, color, dx, dy, dz);
231  }
232 
233  lglBox(vec3 size,
234  bool color = false)
235  : lglVBO("box")
236  {
237  lglCube::addQuads(this, color, size.x, size.y, size.z);
238  }
239 
240  static void addQuads(lglVBO *vbo, bool color = false, double dx = 1, double dy = 1, double dz = 1, bool facecolors = true)
241  {
242  lglCube::addQuads(vbo, color, dx, dy, dz, facecolors);
243  }
244 
245  static void addTo(lglVBO *vbo, bool color = false, double dx = 1, double dy = 1, double dz = 1, bool facecolors = true)
246  {
247  lglCube::addTo(vbo, color, dx, dy, dz, facecolors);
248  }
249 
250 };
251 
258 class lglTet: public lglVBO
259 {
260 public:
261 
262  lglTet(bool color = false)
263  : lglVBO("tetrahedron")
264  {
265  addTriangles(this, color);
266  }
267 
268  static void addTriangles(lglVBO *vbo, bool color = false, bool facecolors = true)
269  {
270  static const double c1 = sqrt(3.0)/6;
271  static const double c2 = sqrt(6.0)/6;
272  static const double c3 = sqrt(3.0)/3;
273 
274  static const vec3 a(-0.5,-c2,c1);
275  static const vec3 b(0.5,-c2,c1);
276  static const vec3 c(0,-c2,-c3);
277  static const vec3 d(0,c2,0);
278 
279  vec4 col = vbo->lglGetColor();
280 
281  vbo->lglBegin(LGL_TRIANGLES);
282 
283  if (color && !facecolors) vbo->lglColor(col);
284 
285  // bottom triangle
286  if (color && facecolors) vbo->lglColor(1,1,1);
287  vbo->lglNormal((c-b).cross(b-a).normalize());
288  vbo->lglTexCoord(0,0);
289  vbo->lglVertex(c);
290  vbo->lglTexCoord(1,0);
291  vbo->lglVertex(b);
292  vbo->lglTexCoord(0,1);
293  vbo->lglVertex(a);
294 
295  // side triangle
296  if (color && facecolors) vbo->lglColor(1,0,0);
297  vbo->lglNormal((a-b).cross(b-d).normalize());
298  vbo->lglTexCoord(0,1);
299  vbo->lglVertex(a);
300  vbo->lglTexCoord(1,0);
301  vbo->lglVertex(b);
302  vbo->lglTexCoord(1,1);
303  vbo->lglVertex(d);
304 
305  // side triangle
306  if (color && facecolors) vbo->lglColor(0,1,0);
307  vbo->lglNormal((b-c).cross(c-d).normalize());
308  vbo->lglTexCoord(1,0);
309  vbo->lglVertex(b);
310  vbo->lglTexCoord(2,0);
311  vbo->lglVertex(c);
312  vbo->lglTexCoord(1,1);
313  vbo->lglVertex(d);
314 
315  // side triangle
316  if (color && facecolors) vbo->lglColor(0,0,1);
317  vbo->lglNormal((c-a).cross(a-d).normalize());
318  vbo->lglTexCoord(2,0);
319  vbo->lglVertex(c);
320  vbo->lglTexCoord(2,1);
321  vbo->lglVertex(a);
322  vbo->lglTexCoord(1,1);
323  vbo->lglVertex(d);
324 
325  vbo->lglEnd();
326  }
327 
328 };
329 
336 class lglPyramid: public lglVBO
337 {
338 public:
339 
340  lglPyramid(bool color = false)
341  : lglVBO("pyramid")
342  {
343  addTriangles(this, color);
344  }
345 
346  static void addTriangles(lglVBO *vbo, bool color = false, bool facecolors = true)
347  {
348  static const vec3 a(-0.5,-0.5,0.5);
349  static const vec3 b(0.5,-0.5,0.5);
350  static const vec3 c(0.5,-0.5,-0.5);
351  static const vec3 d(-0.5,-0.5,-0.5);
352  static const vec3 e(0,0.5,0);
353 
354  vec4 col = vbo->lglGetColor();
355 
356  vbo->lglBegin(LGL_TRIANGLES);
357 
358  if (color && !facecolors) vbo->lglColor(col);
359 
360  // bottom triangles
361  if (color && facecolors) vbo->lglColor(1,1,1);
362  vbo->lglNormal((d-c).cross(c-b).normalize());
363  vbo->lglTexCoord(1,1);
364  vbo->lglVertex(d);
365  vbo->lglTexCoord(0,1);
366  vbo->lglVertex(c);
367  vbo->lglTexCoord(0,0);
368  vbo->lglVertex(b);
369  vbo->lglVertex(b);
370  vbo->lglTexCoord(1,0);
371  vbo->lglVertex(a);
372  vbo->lglTexCoord(1,1);
373  vbo->lglVertex(d);
374 
375  // front triangle
376  if (color && facecolors) vbo->lglColor(1,1,0);
377  vbo->lglNormal((a-b).cross(b-e).normalize());
378  vbo->lglTexCoord(1,0);
379  vbo->lglVertex(a);
380  vbo->lglTexCoord(2,0);
381  vbo->lglVertex(b);
382  vbo->lglTexCoord(1.5,0.5);
383  vbo->lglVertex(e);
384 
385  // right triangle
386  if (color && facecolors) vbo->lglColor(0,1,1);
387  vbo->lglNormal((b-c).cross(c-e).normalize());
388  vbo->lglTexCoord(2,0);
389  vbo->lglVertex(b);
390  vbo->lglTexCoord(2,1);
391  vbo->lglVertex(c);
392  vbo->lglTexCoord(1.5,0.5);
393  vbo->lglVertex(e);
394 
395  // back triangle
396  if (color && facecolors) vbo->lglColor(0,0,1);
397  vbo->lglNormal((c-d).cross(d-e).normalize());
398  vbo->lglTexCoord(2,1);
399  vbo->lglVertex(c);
400  vbo->lglTexCoord(1,1);
401  vbo->lglVertex(d);
402  vbo->lglTexCoord(1.5,0.5);
403  vbo->lglVertex(e);
404 
405  // left triangle
406  if (color && facecolors) vbo->lglColor(1,0,0);
407  vbo->lglNormal((d-a).cross(a-e).normalize());
408  vbo->lglTexCoord(1,1);
409  vbo->lglVertex(d);
410  vbo->lglTexCoord(1,0);
411  vbo->lglVertex(a);
412  vbo->lglTexCoord(1.5,0.5);
413  vbo->lglVertex(e);
414 
415  vbo->lglEnd();
416  }
417 
418 };
419 
426 class lglPyramidBase: public lglVBO
427 {
428 public:
429 
430  lglPyramidBase(double size = 1, double height = 1, double base = 0.5, bool color = false)
431  : lglVBO()
432  {
433  std::string name = "pyramid_base";
434  name += std::string("(");
435  name += glslmath::to_string(size) + ", ";
436  name += glslmath::to_string(height) + ", ";
437  name += glslmath::to_string(base);
438  name += std::string(")");
439  setName(name);
440 
441  addTriangles(this, size, height, base, color);
442  }
443 
444  static void addTriangles(lglVBO *vbo, double size = 1, double height = 1, double base = 0.5, bool color = false)
445  {
446  const vec3 a(-0.5*size,-0.5*base,0.5*size);
447  const vec3 b(0.5*size,-0.5*base,0.5*size);
448  const vec3 c(0.5*size,-0.5*base,-0.5*size);
449  const vec3 d(-0.5*size,-0.5*base,-0.5*size);
450  const vec3 e(0,-0.5*base+height,0);
451 
452  double w = base/height;
453  const vec3 f = (1-w)*a + w*e;
454  const vec3 g = (1-w)*b + w*e;
455  const vec3 h = (1-w)*c + w*e;
456  const vec3 i = (1-w)*d + w*e;
457 
458  vec4 col = vbo->lglGetColor();
459 
460  vbo->lglBegin(LGL_QUADS);
461 
462  if (color) vbo->lglColor(col);
463 
464  // bottom quad
465  vbo->lglNormal((d-c).cross(c-b).normalize());
466  vbo->lglTexCoord(0,-1);
467  vbo->lglVertex(d);
468  vbo->lglTexCoord(1,-1);
469  vbo->lglVertex(c);
470  vbo->lglTexCoord(1,0);
471  vbo->lglVertex(b);
472  vbo->lglTexCoord(0,0);
473  vbo->lglVertex(a);
474 
475  // front quad
476  vbo->lglNormal((a-b).cross(b-e).normalize());
477  vbo->lglTexCoord(0,0);
478  vbo->lglVertex(a);
479  vbo->lglTexCoord(1,0);
480  vbo->lglVertex(b);
481  vbo->lglTexCoord(1,1);
482  vbo->lglVertex(g);
483  vbo->lglTexCoord(1,0);
484  vbo->lglVertex(f);
485 
486  // right quad
487  vbo->lglNormal((b-c).cross(c-e).normalize());
488  vbo->lglTexCoord(1,0);
489  vbo->lglVertex(b);
490  vbo->lglTexCoord(2,0);
491  vbo->lglVertex(c);
492  vbo->lglTexCoord(2,1);
493  vbo->lglVertex(h);
494  vbo->lglTexCoord(1,1);
495  vbo->lglVertex(g);
496 
497  // back quad
498  vbo->lglNormal((c-d).cross(d-e).normalize());
499  vbo->lglTexCoord(2,0);
500  vbo->lglVertex(c);
501  vbo->lglTexCoord(3,0);
502  vbo->lglVertex(d);
503  vbo->lglTexCoord(3,1);
504  vbo->lglVertex(i);
505  vbo->lglTexCoord(2,1);
506  vbo->lglVertex(h);
507 
508  // left quad
509  vbo->lglNormal((d-a).cross(a-e).normalize());
510  vbo->lglTexCoord(-1,0);
511  vbo->lglVertex(d);
512  vbo->lglTexCoord(0,0);
513  vbo->lglVertex(a);
514  vbo->lglTexCoord(0,1);
515  vbo->lglVertex(f);
516  vbo->lglTexCoord(-1,1);
517  vbo->lglVertex(i);
518 
519  // top quad
520  if (w < 1)
521  {
522  vbo->lglNormal((f-g).cross(g-h).normalize());
523  vbo->lglTexCoord(0,1);
524  vbo->lglVertex(f);
525  vbo->lglTexCoord(1,1);
526  vbo->lglVertex(g);
527  vbo->lglTexCoord(1,2);
528  vbo->lglVertex(h);
529  vbo->lglTexCoord(0,2);
530  vbo->lglVertex(i);
531  }
532 
533  vbo->lglEnd();
534  }
535 
536 };
537 
549 class lglPrism: public lglVBO
550 {
551 public:
552 
553  lglPrism(double slanting = 0, bool color = false)
554  : lglVBO("prism")
555  {
556  addTriangles(this, slanting, color);
557  }
558 
559  static void addTriangles(lglVBO *vbo, double slanting = 0, bool color = false, bool facecolors = true)
560  {
561  static const vec3 a(-0.5,-0.5,0.5);
562  static const vec3 b(0.5,-0.5,0.5);
563  static const vec3 c(slanting,0.5,0.5);
564  static const vec3 d(-0.5,-0.5,-0.5);
565  static const vec3 e(0.5,-0.5,-0.5);
566  static const vec3 f(slanting,0.5,-0.5);
567 
568  vec4 col = vbo->lglGetColor();
569 
570  vbo->lglBegin(LGL_TRIANGLES);
571 
572  if (color && !facecolors) vbo->lglColor(col);
573 
574  // front triangle
575  if (color && facecolors) vbo->lglColor(1,1,0);
576  vbo->lglNormal((a-b).cross(b-c).normalize());
577  vbo->lglTexCoord(0,0);
578  vbo->lglVertex(a);
579  vbo->lglTexCoord(1,0);
580  vbo->lglVertex(b);
581  vbo->lglTexCoord(0,1);
582  vbo->lglVertex(c);
583 
584  // back triangle
585  if (color && facecolors) vbo->lglColor(0,1,1);
586  vbo->lglNormal((f-e).cross(e-d).normalize());
587  vbo->lglTexCoord(0,1);
588  vbo->lglVertex(f);
589  vbo->lglTexCoord(1,0);
590  vbo->lglVertex(e);
591  vbo->lglTexCoord(1,1);
592  vbo->lglVertex(d);
593 
594  // left triangles
595  if (color && facecolors) vbo->lglColor(1,0,0);
596  vbo->lglNormal((f-d).cross(d-a).normalize());
597  vbo->lglTexCoord(2,1);
598  vbo->lglVertex(f);
599  vbo->lglTexCoord(1,1);
600  vbo->lglVertex(d);
601  vbo->lglTexCoord(1,0);
602  vbo->lglVertex(a);
603  vbo->lglTexCoord(1,0);
604  vbo->lglVertex(a);
605  vbo->lglTexCoord(2,0);
606  vbo->lglVertex(c);
607  vbo->lglTexCoord(2,1);
608  vbo->lglVertex(f);
609 
610  // right triangles
611  if (color && facecolors) vbo->lglColor(0,1,0);
612  vbo->lglNormal((e-f).cross(f-c).normalize());
613  vbo->lglTexCoord(3,1);
614  vbo->lglVertex(e);
615  vbo->lglTexCoord(2,1);
616  vbo->lglVertex(f);
617  vbo->lglTexCoord(2,0);
618  vbo->lglVertex(c);
619  vbo->lglTexCoord(2,0);
620  vbo->lglVertex(c);
621  vbo->lglTexCoord(3,0);
622  vbo->lglVertex(b);
623  vbo->lglTexCoord(3,1);
624  vbo->lglVertex(e);
625 
626  // bottom triangles
627  if (color && facecolors) vbo->lglColor(0,0,1);
628  vbo->lglNormal((d-e).cross(e-b).normalize());
629  vbo->lglTexCoord(4,1);
630  vbo->lglVertex(d);
631  vbo->lglTexCoord(3,1);
632  vbo->lglVertex(e);
633  vbo->lglTexCoord(3,0);
634  vbo->lglVertex(b);
635  vbo->lglTexCoord(3,0);
636  vbo->lglVertex(b);
637  vbo->lglTexCoord(4,0);
638  vbo->lglVertex(a);
639  vbo->lglTexCoord(5,1);
640  vbo->lglVertex(d);
641 
642  vbo->lglEnd();
643  }
644 
645 };
646 
653 class lglSphere: public lglVBO
654 {
655 public:
656 
657  lglSphere(bool color = false, int tessel = 8)
658  : lglVBO("sphere")
659  {
660  addTo(this, color, tessel);
661  }
662 
663  static void addTo(lglVBO *vbo, bool color = false, int tessel = 8)
664  {
665  int i, j;
666 
667  double u, v;
668  double alpha, beta;
669  vec3 p;
670 
671  int alpha_steps = 4*tessel;
672  int beta_steps = tessel;
673 
674  vec4 col = vbo->lglGetColor();
675 
676  for (j=-beta_steps; j<beta_steps; j++)
677  {
678  vbo->lglBegin(LGL_QUAD_STRIP);
679 
680  if (color) vbo->lglColor(col);
681 
682  for (i=0; i<=alpha_steps; i++)
683  {
684  u = (double)i/alpha_steps;
685  v = (double)j/beta_steps;
686 
687  alpha = u*2*PI;
688  beta = v*PI/2;
689 
690  p = vec3(sin(alpha)*cos(beta),
691  cos(alpha)*cos(beta),
692  sin(beta));
693 
694  vbo->lglNormal(p);
695  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
696  vbo->lglVertex(p/2);
697 
698  v = (double)(j+1)/beta_steps;
699  beta = v*PI/2;
700 
701  p = vec3(sin(alpha)*cos(beta),
702  cos(alpha)*cos(beta),
703  sin(beta));
704 
705  vbo->lglNormal(p);
706  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
707  vbo->lglVertex(p/2);
708  }
709 
710  vbo->lglEnd();
711  }
712  }
713 
714 };
715 
720 class lglHemisphere: public lglVBO
721 {
722 public:
723 
724  lglHemisphere(bool color = false, int tessel = 8)
725  : lglVBO("hemisphere")
726  {
727  addTo(this, color, tessel);
728  }
729 
730  static void addTo(lglVBO *vbo, bool color = false, int tessel = 8)
731  {
732  int i, j;
733 
734  double u, v;
735  double alpha, beta;
736  vec3 p;
737 
738  int alpha_steps = 4*tessel;
739  int beta_steps = tessel;
740 
741  vec4 col = vbo->lglGetColor();
742 
743  for (j=0; j<beta_steps; j++)
744  {
745  vbo->lglBegin(LGL_QUAD_STRIP);
746 
747  if (color) vbo->lglColor(col);
748 
749  for (i=0; i<=alpha_steps; i++)
750  {
751  u = (double)i/alpha_steps;
752  v = (double)j/beta_steps;
753 
754  alpha = u*2*PI;
755  beta = v*PI/2;
756 
757  p = vec3(sin(alpha)*cos(beta),
758  sin(beta),
759  -cos(alpha)*cos(beta));
760 
761  vbo->lglNormal(p);
762  vbo->lglTexCoord(1.0f-(float)u,1.0f-(float)v);
763  vbo->lglVertex(p/2);
764 
765  v = (double)(j+1)/beta_steps;
766  beta = v*PI/2;
767 
768  p = vec3(sin(alpha)*cos(beta),
769  sin(beta),
770  -cos(alpha)*cos(beta));
771 
772  vbo->lglNormal(p);
773  vbo->lglTexCoord(1.0f-(float)u,1.0f-(float)v);
774  vbo->lglVertex(p/2);
775  }
776 
777  vbo->lglEnd();
778  }
779  }
780 
781 };
782 
789 class lglCylinder: public lglVBO
790 {
791 public:
792 
793  lglCylinder(bool caps = false, bool color = false, int tessel = 8)
794  : lglVBO()
795  {
796  std::string name = "cylinder";
797  name += std::string("(");
798  name += std::string(caps?"caps":"nocaps");
799  name += std::string(")");
800  setName(name);
801 
802  addTo(this, caps, color, tessel);
803  }
804 
805  static void addTo(lglVBO *vbo, bool caps = false, bool color = false, int tessel = 8)
806  {
807  int i;
808 
809  double u;
810  double alpha;
811 
812  int steps = 4*tessel;
813 
814  vec4 col = vbo->lglGetColor();
815 
816  vbo->lglBegin(LGL_QUAD_STRIP);
817 
818  if (color) vbo->lglColor(col);
819 
820  for (i=0; i<=steps; i++)
821  {
822  u = (double)i/steps;
823  alpha = u*2*PI;
824 
825  double s = sin(alpha);
826  double c = cos(alpha);
827 
828  vbo->lglNormal(vec3(s,c,0));
829  vbo->lglTexCoord(1.0f-(float)u,0);
830  vbo->lglVertex(vec3(s,c,-1)/2);
831  vbo->lglTexCoord(1.0f-(float)u,1);
832  vbo->lglVertex(vec3(s,c,1)/2);
833  }
834 
835  vbo->lglEnd();
836 
837  if (caps)
838  {
839  steps = 2*tessel;
840 
841  vbo->lglBegin(LGL_QUAD_STRIP);
842 
843  if (color) vbo->lglColor(col);
844 
845  vbo->lglNormal(0,0,1);
846 
847  for (i=0; i<=steps; i++)
848  {
849  u = (double)i/steps;
850  alpha = u*PI;
851 
852  double s = sin(alpha)/2;
853  double c = cos(alpha)/2;
854 
855  vbo->lglTexCoord(1.5f+(float)s,0.5f+(float)c);
856  vbo->lglVertex(vec3(s,c,0.5));
857 
858  vbo->lglTexCoord(1.5f-(float)s,0.5f+(float)c);
859  vbo->lglVertex(vec3(-s,c,0.5));
860  }
861 
862  vbo->lglEnd();
863 
864  vbo->lglBegin(LGL_QUAD_STRIP);
865 
866  if (color) vbo->lglColor(col);
867 
868  vbo->lglNormal(0,0,-1);
869 
870  for (i=0; i<=steps; i++)
871  {
872  u = (double)i/steps;
873  alpha = u*PI;
874 
875  double s = sin(alpha)/2;
876  double c = cos(alpha)/2;
877 
878  vbo->lglTexCoord(1.5f+(float)s,0.5f+(float)c);
879  vbo->lglVertex(vec3(-s,c,-0.5));
880 
881  vbo->lglTexCoord(1.5f-(float)s,0.5f+(float)c);
882  vbo->lglVertex(vec3(s,c,-0.5));
883  }
884 
885  vbo->lglEnd();
886  }
887  }
888 
889 };
890 
895 class lglHemiCylinder: public lglVBO
896 {
897 public:
898 
899  lglHemiCylinder(bool caps = false, double angle = 180, bool color = false, int tessel = 8)
900  : lglVBO()
901  {
902  std::string name = "hemi_cylinder";
903  name += std::string("(");
904  name += std::string(caps?"caps":"nocaps") + ", ";
905  name += glslmath::to_string(angle);
906  name += std::string(")");
907  setName(name);
908 
909  addTo(this, caps, angle, color, tessel);
910  }
911 
912  static void addTo(lglVBO *vbo, bool caps = false, double angle = 180, bool color = false, int tessel = 8)
913  {
914  int i;
915 
916  double u;
917  double alpha;
918 
919  int steps = (int)ceil(angle/360*4*tessel);
920 
921  vec4 col = vbo->lglGetColor();
922 
923  vbo->lglBegin(LGL_QUAD_STRIP);
924 
925  if (color) vbo->lglColor(col);
926 
927  for (i=0; i<=steps; i++)
928  {
929  u = (double)i/steps;
930  alpha = (u*angle/360-(angle-180)/2)*2*PI;
931 
932  double s = sin(alpha);
933  double c = cos(alpha);
934 
935  vbo->lglNormal(vec3(-c,s,0));
936  vbo->lglTexCoord(1.0f-(float)u,0);
937  vbo->lglVertex(vec3(-c,s,-1)/2);
938  vbo->lglTexCoord(1.0f-(float)u,1);
939  vbo->lglVertex(vec3(-c,s,1)/2);
940  }
941 
942  vbo->lglEnd();
943 
944  if (caps)
945  {
946  vbo->lglBegin(LGL_QUAD_STRIP);
947 
948  if (color) vbo->lglColor(col);
949 
950  vbo->lglNormal(0,0,1);
951 
952  for (i=0; i<=steps; i++)
953  {
954  u = (double)i/steps;
955  alpha = u*PI;
956 
957  double s = sin(alpha)/2;
958  double c = cos(alpha)/2;
959 
960  vbo->lglTexCoord(0.5f-(float)c,1);
961  vbo->lglVertex(vec3(-c,0,0.5));
962 
963  vbo->lglTexCoord(0.5f-(float)c,1.0f-(float)s*2);
964  vbo->lglVertex(vec3(-c,s,0.5));
965  }
966 
967  vbo->lglEnd();
968 
969  vbo->lglBegin(LGL_QUAD_STRIP);
970 
971  if (color) vbo->lglColor(col);
972 
973  vbo->lglNormal(0,0,-1);
974 
975  for (i=0; i<=steps; i++)
976  {
977  u = (double)i/steps;
978  alpha = u*PI;
979 
980  double s = sin(alpha)/2;
981  double c = cos(alpha)/2;
982 
983  vbo->lglTexCoord(1.5f+(float)c,1.0f-(float)s*2);
984  vbo->lglVertex(vec3(-c,s,-0.5));
985 
986  vbo->lglTexCoord(1.5f+(float)c,1);
987  vbo->lglVertex(vec3(-c,0,-0.5));
988  }
989 
990  vbo->lglEnd();
991  }
992  }
993 
994 };
995 
1002 class lglDisc: public lglVBO
1003 {
1004 public:
1005 
1006  lglDisc(bool color = false, int tessel = 8)
1007  : lglVBO("disc")
1008  {
1009  addTo(this, color, tessel);
1010  }
1011 
1012  static void addTo(lglVBO *vbo, bool color = false, int tessel = 8)
1013  {
1014  int i;
1015 
1016  double u;
1017  double alpha;
1018 
1019  int steps = 2*tessel;
1020 
1021  vec4 col = vbo->lglGetColor();
1022 
1023  vbo->lglBegin(LGL_QUAD_STRIP);
1024 
1025  if (color) vbo->lglColor(col);
1026 
1027  vbo->lglNormal(0,0,1);
1028 
1029  for (i=0; i<=steps; i++)
1030  {
1031  u = (double)i/steps;
1032  alpha = u*PI;
1033 
1034  double s = sin(alpha)/2;
1035  double c = cos(alpha)/2;
1036 
1037  vbo->lglTexCoord(0.5f+(float)s,0.5f+(float)c);
1038  vbo->lglVertex(vec3(s,c,0));
1039 
1040  vbo->lglTexCoord(0.5f-(float)s,0.5f+(float)c);
1041  vbo->lglVertex(vec3(-s,c,0));
1042  }
1043 
1044  vbo->lglEnd();
1045  }
1046 
1047 };
1048 
1053 class lglHemiDisc: public lglVBO
1054 {
1055 public:
1056 
1057  lglHemiDisc(double angle = 180, bool color = false, int tessel = 8)
1058  : lglVBO()
1059  {
1060  std::string name = "hemi_disc";
1061  name += std::string("(");
1062  name += glslmath::to_string(angle);
1063  name += std::string(")");
1064  setName(name);
1065 
1066  addTo(this, angle, color, tessel);
1067  }
1068 
1069  static void addTo(lglVBO *vbo, double angle = 180, bool color = false, int tessel = 8)
1070  {
1071  int i;
1072 
1073  double u;
1074  double alpha;
1075 
1076  int steps = (int)ceil(angle/360*4*tessel);
1077 
1078  vec4 col = vbo->lglGetColor();
1079 
1080  vbo->lglBegin(LGL_QUAD_STRIP);
1081 
1082  if (color) vbo->lglColor(col);
1083 
1084  vbo->lglNormal(0,0,1);
1085 
1086  for (i=0; i<=steps; i++)
1087  {
1088  u = (double)i/steps;
1089  alpha = (u*angle/360-(angle-180)/2)*2*PI;
1090 
1091  double s = sin(alpha)/2;
1092  double c = cos(alpha)/2;
1093 
1094  if (angle > 180) vbo->lglTexCoord(0.5f,0.5f);
1095  else vbo->lglTexCoord(0.5f,1);
1096  vbo->lglVertex(vec3(0,0,0));
1097 
1098  if (angle > 180) vbo->lglTexCoord(0.5f-(float)c,0.5f-(float)s);
1099  else vbo->lglTexCoord(0.5f-(float)c,1.0f-(float)s*2);
1100  vbo->lglVertex(vec3(-c,s,0));
1101  }
1102 
1103  vbo->lglEnd();
1104  }
1105 
1106 };
1107 
1114 class lglCone: public lglVBO
1115 {
1116 public:
1117 
1118  lglCone(bool color = false, int tessel = 8)
1119  : lglVBO("cone")
1120  {
1121  addTo(this, color, tessel);
1122  }
1123 
1124  static void addTo(lglVBO *vbo, bool color = false, int tessel = 8)
1125  {
1126  int i;
1127 
1128  double u;
1129  double alpha;
1130 
1131  int steps = 4*tessel;
1132 
1133  vec4 col = vbo->lglGetColor();
1134 
1135  vbo->lglBegin(LGL_QUAD_STRIP);
1136 
1137  if (color) vbo->lglColor(col);
1138 
1139  for (i=0; i<=steps; i++)
1140  {
1141  u = (double)i/steps;
1142  alpha = u*2*PI;
1143 
1144  double s = sin(alpha);
1145  double c = cos(alpha);
1146 
1147  vbo->lglNormal(vec3(s,c,0.5));
1148  vbo->lglTexCoord(0.5f+(float)s/2,0.5f+(float)c/2);
1149  vbo->lglVertex(vec3(s,c,-1)/2);
1150 
1151  vbo->lglNormal(vec3(0,0,0));
1152  vbo->lglTexCoord(0.5f,0.5f);
1153  vbo->lglVertex(vec3(0,0,0.5));
1154  }
1155 
1156  vbo->lglEnd();
1157  }
1158 
1159 };
1160 
1167 class lglConeBase: public lglVBO
1168 {
1169 public:
1170 
1171  lglConeBase(double size = 1, double height = 1, double base = 0.5, bool color = false, int tessel = 8)
1172  : lglVBO()
1173  {
1174  std::string name = "cone_base";
1175  name += std::string("(");
1176  name += glslmath::to_string(size) + ", ";
1177  name += glslmath::to_string(height) + ", ";
1178  name += glslmath::to_string(base);
1179  name += std::string(")");
1180  setName(name);
1181 
1182  addTo(this, size, height, base, color, tessel);
1183  }
1184 
1185  static void addTo(lglVBO *vbo,
1186  double size = 1, double height = 1, double base = 0.5,
1187  bool color = false, int tessel = 8)
1188  {
1189  int i;
1190 
1191  double u;
1192  double alpha;
1193 
1194  int steps = 4*tessel;
1195 
1196  double w = base/height;
1197  vec3 t = vec3(0,-base/2+height,0);
1198 
1199  vec4 col = vbo->lglGetColor();
1200 
1201  vbo->lglBegin(LGL_QUAD_STRIP);
1202 
1203  if (color) vbo->lglColor(col);
1204 
1205  for (i=0; i<=steps; i++)
1206  {
1207  u = (double)i/steps;
1208  alpha = u*2*PI;
1209 
1210  double s = sin(alpha)*size/2;
1211  double c = cos(alpha)*size/2;
1212  vec3 v = vec3(s,-base/2,c);
1213 
1214  vbo->lglNormal(vec3(s,size*size/height/4,c));
1215  vbo->lglTexCoord((float)u,0.5f);
1216  vbo->lglVertex((1-w)*v+w*t);
1217  vbo->lglTexCoord((float)u,1);
1218  vbo->lglVertex(v);
1219  }
1220 
1221  vbo->lglEnd();
1222 
1223  vbo->lglBegin(LGL_QUAD_STRIP);
1224 
1225  if (color) vbo->lglColor(col);
1226 
1227  for (i=0; i<=steps; i++)
1228  {
1229  u = (double)i/steps;
1230  alpha = -u*2*PI;
1231 
1232  double s = sin(alpha)*size/2;
1233  double c = cos(alpha)*size/2;
1234  vec3 v = vec3(s,-base/2,c);
1235 
1236  vbo->lglNormal(vec3(0,-1,0));
1237  vbo->lglTexCoord((float)u,0);
1238  vbo->lglVertex(vec3(0,-base/2,0));
1239  vbo->lglTexCoord((float)u,0.5f);
1240  vbo->lglVertex(v);
1241  }
1242 
1243  vbo->lglEnd();
1244 
1245  if (w < 1)
1246  {
1247  vbo->lglBegin(LGL_QUAD_STRIP);
1248 
1249  if (color) vbo->lglColor(col);
1250 
1251  for (i=0; i<=steps; i++)
1252  {
1253  u = (double)i/steps;
1254  alpha = u*2*PI;
1255 
1256  double s = sin(alpha)*size/2;
1257  double c = cos(alpha)*size/2;
1258  vec3 v = vec3(s,-base/2,c);
1259 
1260  vbo->lglNormal(vec3(0,1,0));
1261  vbo->lglTexCoord((float)u,0);
1262  vbo->lglVertex(vec3(0,base/2,0));
1263  vbo->lglTexCoord((float)u,0.5f);
1264  vbo->lglVertex((1-w)*v+w*t);
1265  }
1266 
1267  vbo->lglEnd();
1268  }
1269  }
1270 
1271 };
1272 
1280 class lglRing: public lglVBO
1281 {
1282 public:
1283 
1284  lglRing(double outer = 1.0, double inner = 0.0, double displace = 0.0,
1285  bool color = false, int tessel = 8)
1286  : lglVBO()
1287  {
1288  std::string name = "ring";
1289  name += std::string("(");
1290  name += glslmath::to_string(outer) + ", ";
1291  name += glslmath::to_string(inner) + ", ";
1292  name += glslmath::to_string(displace);
1293  name += std::string(")");
1294  setName(name);
1295 
1296  addTo(this, outer, inner, displace, color, tessel);
1297  }
1298 
1299  static void addTo(lglVBO *vbo,
1300  double outer = 1.0, double inner = 0.0, double displace = 0.0,
1301  bool color = false, int tessel = 8)
1302  {
1303  int i;
1304 
1305  double u;
1306  double alpha;
1307 
1308  int steps = 4*tessel;
1309 
1310  vec4 col = vbo->lglGetColor();
1311 
1312  vbo->lglBegin(LGL_QUAD_STRIP);
1313 
1314  if (color) vbo->lglColor(col);
1315 
1316  for (i=0; i<=steps; i++)
1317  {
1318  u = (double)i/steps;
1319  alpha = u*2*PI;
1320 
1321  double s = sin(alpha);
1322  double c = cos(alpha);
1323 
1324  double d = displace/(outer-inner);
1325  vbo->lglNormal(vec3(d*s,d*c,1));
1326 
1327  vbo->lglTexCoord((float)u,1);
1328  vbo->lglVertex(vec3(outer*s,outer*c,0));
1329 
1330  vbo->lglTexCoord((float)u,0);
1331  vbo->lglVertex(vec3(inner*s,inner*c,displace));
1332  }
1333 
1334  vbo->lglEnd();
1335  }
1336 
1337 };
1338 
1343 class lglHemiRing: public lglVBO
1344 {
1345 public:
1346 
1347  lglHemiRing(double outer = 1.0, double inner = 0.0, double displace = 0.0,
1348  double angle = 180, bool color = false, int tessel = 8)
1349  : lglVBO()
1350  {
1351  std::string name = "hemi_ring";
1352  name += std::string("(");
1353  name += glslmath::to_string(outer) + ", ";
1354  name += glslmath::to_string(inner) + ", ";
1355  name += glslmath::to_string(displace) + ", ";
1356  name += glslmath::to_string(angle);
1357  name += std::string(")");
1358  setName(name);
1359 
1360  addTo(this, outer, inner, displace, angle, color, tessel);
1361  }
1362 
1363  static void addTo(lglVBO *vbo,
1364  double outer = 1.0, double inner = 0.0, double displace = 0.0,
1365  double angle = 180, bool color = false, int tessel = 8)
1366  {
1367  int i;
1368 
1369  double u;
1370  double alpha;
1371 
1372  int steps = (int)ceil(angle/360*4*tessel);
1373 
1374  vec4 col = vbo->lglGetColor();
1375 
1376  vbo->lglBegin(LGL_QUAD_STRIP);
1377 
1378  if (color) vbo->lglColor(col);
1379 
1380  for (i=0; i<=steps; i++)
1381  {
1382  u = (double)i/steps;
1383  alpha = (u*angle/360-(angle-180)/2)*2*PI;
1384 
1385  double s = sin(alpha);
1386  double c = cos(alpha);
1387 
1388  double d = displace/(outer-inner);
1389  vbo->lglNormal(vec3(-d*c,d*s,1));
1390 
1391  vbo->lglTexCoord((float)u,1);
1392  vbo->lglVertex(vec3(-outer*c,outer*s,0));
1393 
1394  vbo->lglTexCoord((float)u,0);
1395  vbo->lglVertex(vec3(-inner*c,inner*s,displace));
1396  }
1397 
1398  vbo->lglEnd();
1399  }
1400 
1401 };
1402 
1406 class lglArc: public lglVBO
1407 {
1408 public:
1409 
1410  lglArc(double outer = 1.0, double inner = 0.0,
1411  double angle = 180, bool color = false, int tessel = 8)
1412  : lglVBO()
1413  {
1414  std::string name = "arc";
1415  name += std::string("(");
1416  name += glslmath::to_string(outer) + ", ";
1417  name += glslmath::to_string(inner) + ", ";
1418  name += glslmath::to_string(angle);
1419  name += std::string(")");
1420  setName(name);
1421 
1422  addTo(this, outer, inner, angle, color, tessel);
1423  }
1424 
1425  static void addTo(lglVBO *vbo,
1426  double outer = 1.0, double inner = 0.0,
1427  double angle = 180, bool color = false, int tessel = 8)
1428  {
1429  vbo->lglMatrixMode(LGL_PREMODEL);
1430  vbo->lglPushMatrix();
1431  vbo->lglScale(outer);
1432  lglHemiCylinder::addTo(vbo, false, angle, color, tessel);
1433  vbo->lglPopMatrix();
1434  vbo->lglPushMatrix();
1435  vbo->lglScale(-inner);
1436  vbo->lglRotateZ(180);
1437  lglHemiCylinder::addTo(vbo, false, angle, color, tessel);
1438  vbo->lglPopMatrix();
1439  vbo->lglPushMatrix();
1440  vbo->lglTranslate(0,0,0.5);
1441  lglHemiRing::addTo(vbo, outer, inner, 0, angle, color, tessel);
1442  vbo->lglPopMatrix();
1443  vbo->lglPushMatrix();
1444  vbo->lglTranslate(0,0,-0.5);
1445  vbo->lglScale(0,0,-1);
1446  lglHemiRing::addTo(vbo, outer, inner, 0, angle, color, tessel);
1447  vbo->lglPopMatrix();
1448  vbo->lglMatrixMode(LGL_MODELVIEW);
1449  }
1450 
1451 };
1452 
1457 class lglObj: public lglVBO
1458 {
1459 public:
1460 
1461  lglObj()
1462  : lglVBO(),
1463  maxcoord(0)
1464  {}
1465 
1466  lglObj(const char *path, bool silent = false, lgl_texgenmode_enum texgen = LGL_TEXGEN_NONE)
1467  : lglVBO(),
1468  maxcoord(0)
1469  {
1470  load(path, silent, texgen);
1471  }
1472 
1473  lglObj(std::string path, bool silent = false, lgl_texgenmode_enum texgen = LGL_TEXGEN_NONE)
1474  : lglVBO(),
1475  maxcoord(0)
1476  {
1477  load(path, silent, texgen);
1478  }
1479 
1480  bool load(const char *path, bool silent = false, lgl_texgenmode_enum texgen = LGL_TEXGEN_NONE)
1481  {
1482  bool ok = lglLoadObj(this, path, silent, texgen);
1483  if (ok) maxcoord = lglGetMaxAbsCoord();
1484  return(ok);
1485  }
1486 
1487  bool load(std::string path, bool silent = false, lgl_texgenmode_enum texgen = LGL_TEXGEN_NONE)
1488  {
1489  return(load(path.c_str(), silent, texgen));
1490  }
1491 
1492  ~lglObj()
1493  {}
1494 
1495  virtual void lglRender(const LGL_VBO_TYPE *vbo = NULL)
1496  {
1497  if (maxcoord > 0)
1498  {
1499  lglPushMatrix();
1500  lglScale(0.5/maxcoord);
1501  lglVBO::lglRender(vbo);
1502  lglPopMatrix();
1503  }
1504  }
1505 
1506 protected:
1507 
1508  double maxcoord;
1509 };
1510 
1518 class lglTeapot: public lglObj
1519 {
1520 public:
1521 
1522  lglTeapot(lgl_texgenmode_enum texgen = LGL_TEXGEN_MIXED_HEDGEHOG)
1523  : lglObj("teapot.obj", true, texgen)
1524  {}
1525 
1526 };
1527 
1529 class lglSheet: public lglVBO
1530 {
1531 public:
1532 
1533  lglSheet(const std::string &name = "sheet")
1534  : lglVBO(name)
1535  {}
1536 
1537  void create(int tessel = 8, double size = 1.0, bool color = false)
1538  {
1539  clear();
1540  addTo(this, tessel, size, color);
1541  }
1542 
1543  void addTo(lglVBO *vbo, int tessel = 8, double size = 1.0, bool color = false)
1544  {
1545  double u;
1546  vec2 op, ip, n;
1547  bool align;
1548 
1549  int steps = 4*tessel;
1550 
1551  vec4 col = vbo->lglGetColor();
1552 
1553  vbo->lglBegin(LGL_QUAD_STRIP);
1554 
1555  if (color) vbo->lglColor(col);
1556 
1557  align = true;
1558 
1559  for (u=outer_first(steps, &align);
1560  u<outer_last(steps);
1561  u=outer_next(u, steps, &align))
1562  {
1563  op = outer_point(u);
1564 
1565  if (align)
1566  {
1567  n = outer_normal(u);
1568 
1569  vbo->lglNormal(vec3(n,0));
1570  vbo->lglTexCoord(op);
1571  vbo->lglVertex(vec3(op,-0.5*size));
1572  vbo->lglVertex(vec3(op,0.5*size));
1573  }
1574  else
1575  {
1576  n = outer_normal(u, -1);
1577 
1578  vbo->lglNormal(vec3(n,0));
1579  vbo->lglTexCoord(op);
1580  vbo->lglVertex(vec3(op,-0.5*size));
1581  vbo->lglVertex(vec3(op,0.5*size));
1582 
1583  n = outer_normal(u, +1);
1584 
1585  vbo->lglNormal(vec3(n,0));
1586  vbo->lglTexCoord(op);
1587  vbo->lglVertex(vec3(op,-0.5*size));
1588  vbo->lglVertex(vec3(op,0.5*size));
1589  }
1590  }
1591 
1592  vbo->lglEnd();
1593 
1594  vbo->lglBegin(LGL_QUAD_STRIP);
1595 
1596  if (color) vbo->lglColor(col);
1597 
1598  align = true;
1599 
1600  for (u=inner_first(steps, &align);
1601  u<inner_last(steps);
1602  u=inner_next(u, steps, &align))
1603  {
1604  ip = inner_point(u);
1605 
1606  if (align)
1607  {
1608  n = inner_normal(u);
1609 
1610  vbo->lglNormal(vec3(n,0));
1611  vbo->lglTexCoord(ip);
1612  vbo->lglVertex(vec3(ip,0.5*size));
1613  vbo->lglVertex(vec3(ip,-0.5*size));
1614  }
1615  else
1616  {
1617  n = inner_normal(u, -1);
1618 
1619  vbo->lglNormal(vec3(n,0));
1620  vbo->lglTexCoord(ip);
1621  vbo->lglVertex(vec3(ip,0.5*size));
1622  vbo->lglVertex(vec3(ip,-0.5*size));
1623 
1624  n = inner_normal(u, +1);
1625 
1626  vbo->lglNormal(vec3(n,0));
1627  vbo->lglTexCoord(ip);
1628  vbo->lglVertex(vec3(ip,0.5*size));
1629  vbo->lglVertex(vec3(ip,-0.5*size));
1630  }
1631  }
1632 
1633  vbo->lglEnd();
1634 
1635  vbo->lglBegin(LGL_QUAD_STRIP);
1636 
1637  if (color) vbo->lglColor(col);
1638 
1639  vbo->lglNormal(vec3(0,0,-1));
1640  for (u=0; u<1+0.5/steps; u=next(u, steps))
1641  {
1642  op = outer_point(u);
1643  ip = inner_point(u);
1644 
1645  vbo->lglTexCoord(ip);
1646  vbo->lglVertex(vec3(ip,-0.5*size));
1647  vbo->lglTexCoord(op);
1648  vbo->lglVertex(vec3(op,-0.5*size));
1649  }
1650 
1651  vbo->lglEnd();
1652 
1653  vbo->lglBegin(LGL_QUAD_STRIP);
1654 
1655  if (color) vbo->lglColor(col);
1656 
1657  vbo->lglNormal(vec3(0,0,1));
1658  for (u=0; u<1+0.5/steps; u=next(u, steps))
1659  {
1660  op = outer_point(u);
1661  ip = inner_point(u);
1662 
1663  vbo->lglTexCoord(op);
1664  vbo->lglVertex(vec3(op,0.5*size));
1665  vbo->lglTexCoord(ip);
1666  vbo->lglVertex(vec3(ip,0.5*size));
1667  }
1668 
1669  vbo->lglEnd();
1670  }
1671 
1672 protected:
1673 
1674  virtual vec2 outer_point(double u) = 0;
1675 
1676  virtual vec2 inner_point(double u)
1677  {
1678  return(vec2(0,0));
1679  }
1680 
1681  virtual vec2 outer_normal(double u, int mode = 0, double d = 0.001)
1682  {
1683  int k = outer_tessel();
1684 
1685  double maxd = 1;
1686  if (k > 0) maxd = 0.01/k;
1687  if (maxd < d) d = maxd;
1688 
1689  double ld = d;
1690  double rd = d;
1691 
1692  if (mode < 0) rd = 0;
1693  if (mode > 0) ld = 0;
1694 
1695  vec2 p1 = outer_point(u-ld);
1696  vec2 p2 = outer_point(u+rd);
1697 
1698  vec2 df = p2-p1;
1699  vec2 n = vec2(-df.y, df.x);
1700 
1701  return(n.normalize());
1702  }
1703 
1704  virtual vec2 inner_normal(double u, int mode = 0, double d = 0.001)
1705  {
1706  int k = inner_tessel();
1707 
1708  double maxd = 1;
1709  if (k > 0) maxd = 0.01/k;
1710  if (maxd < d) d = maxd;
1711 
1712  double ld = d;
1713  double rd = d;
1714 
1715  if (mode < 0) rd = 0;
1716  if (mode > 0) ld = 0;
1717 
1718  vec2 p1 = inner_point(u-ld);
1719  vec2 p2 = inner_point(u+rd);
1720 
1721  vec2 df = p2-p1;
1722  vec2 n = vec2(df.y, -df.x);
1723 
1724  return(n.normalize());
1725  }
1726 
1727  virtual double outer_first(int steps, bool *align = NULL)
1728  {
1729  return(0);
1730  }
1731 
1732  virtual double inner_first(int steps, bool *align = NULL)
1733  {
1734  return(0);
1735  }
1736 
1737  virtual double outer_last(int steps)
1738  {
1739  return(1+0.5/steps);
1740  }
1741 
1742  virtual double inner_last(int steps)
1743  {
1744  return(1+0.5/steps);
1745  }
1746 
1747  virtual double outer_next(double u, int steps, bool *align = NULL)
1748  {
1749  return(u+1.0/steps);
1750  }
1751 
1752  virtual double inner_next(double u, int steps, bool *align = NULL)
1753  {
1754  return(u+1.0/steps);
1755  }
1756 
1757  virtual double next(double u, int steps)
1758  {
1759  double v = inner_next(u, steps);
1760  u = outer_next(u, steps);
1761  if (v < u) u = v;
1762  return(u);
1763  }
1764 
1765  virtual int outer_tessel() {return(1);}
1766  virtual int inner_tessel() {return(1);}
1767 };
1768 
1776 {
1777 public:
1778 
1780  const lgl_BezierPath2D &inner = lgl_BezierPath2D())
1781  : lglSheet("sheet_bezier"),
1782  outer_(outer), inner_(inner)
1783  {}
1784 
1785  void setOuterPath(const lgl_BezierPath2D &outer)
1786  {
1787  outer_ = outer;
1788  }
1789 
1790  void setInnerPath(const lgl_BezierPath2D &inner)
1791  {
1792  inner_ = inner;
1793  }
1794 
1795  void addOuterPoint(vec2 point, bool align = true)
1796  {
1797  outer_.addPoint(point, align);
1798  }
1799 
1800  void addInnerPoint(vec2 point, bool align = true)
1801  {
1802  inner_.addPoint(point, align);
1803  }
1804 
1805  void outerStraighten()
1806  {
1807  outer_.straighten();
1808  }
1809 
1810  void innerStraighten()
1811  {
1812  inner_.straighten();
1813  }
1814 
1815  void outerClose()
1816  {
1817  outer_.close();
1818  }
1819 
1820  void innerClose()
1821  {
1822  inner_.close();
1823  }
1824 
1825  void outerAlign()
1826  {
1827  outer_.alignCurves();
1828  }
1829 
1830  void innerAlign()
1831  {
1832  inner_.alignCurves();
1833  }
1834 
1835  void release()
1836  {
1837  inner_.clear();
1838  outer_.clear();
1839  }
1840 
1841 protected:
1842 
1843  lgl_BezierPath2D outer_, inner_;
1844 
1845  virtual vec2 outer_point(double u)
1846  {
1847  return(outer_.evaluate(u));
1848  }
1849 
1850  virtual vec2 inner_point(double u)
1851  {
1852  return(inner_.evaluate(u));
1853  }
1854 
1855  virtual double outer_first(int steps, bool *align = NULL)
1856  {
1857  return(outer_.first(steps, align));
1858  }
1859 
1860  virtual double inner_first(int steps, bool *align = NULL)
1861  {
1862  return(inner_.first(steps, align));
1863  }
1864 
1865  virtual double outer_last(int steps)
1866  {
1867  return(outer_.last(steps));
1868  }
1869 
1870  virtual double inner_last(int steps)
1871  {
1872  return(inner_.last(steps));
1873  }
1874 
1875  virtual double outer_next(double u, int steps, bool *align = NULL)
1876  {
1877  return(outer_.next(u, steps, align));
1878  }
1879 
1880  virtual double inner_next(double u, int steps, bool *align = NULL)
1881  {
1882  return(inner_.next(u, steps, align));
1883  }
1884 
1885  virtual int outer_tessel() {return(outer_.size());}
1886  virtual int inner_tessel() {return(inner_.size());}
1887 };
1888 
1896 class lglSheetDisc: public lglSheet
1897 {
1898 public:
1899 
1900  lglSheetDisc(int tessel = 8, double size = 1.0, bool color = false)
1901  : lglSheet()
1902  {
1903  std::string name = "sheet_disc";
1904  name += std::string("(");
1905  name += glslmath::to_string(size);
1906  name += std::string(")");
1907  setName(name);
1908 
1909  addTo(this, tessel, size, color);
1910  }
1911 
1912 protected:
1913 
1914  virtual vec2 outer_point(double u)
1915  {
1916  double a = u*2*PI;
1917  double s = sin(a);
1918  double c = cos(a);
1919 
1920  return(0.5*vec2(c,-s));
1921  }
1922 
1923 };
1924 
1934 class lglShim: public lglSheet
1935 {
1936 public:
1937 
1938  lglShim(double outer = 1.0, double inner = 0.0,
1939  int tessel = 8, double size = 1.0, bool color = false)
1940  : lglSheet(),
1941  outer_(outer), inner_(inner)
1942  {
1943  std::string name = "shim";
1944  name += std::string("(");
1945  name += glslmath::to_string(outer) + ", ";
1946  name += glslmath::to_string(inner) + ", ";
1947  name += glslmath::to_string(size);
1948  name += std::string(")");
1949  setName(name);
1950 
1951  addTo(this, tessel, size, color);
1952  }
1953 
1954 protected:
1955 
1956  double outer_, inner_;
1957 
1958  virtual vec2 outer_point(double u)
1959  {
1960  double a = u*2*PI;
1961  double s = sin(a);
1962  double c = cos(a);
1963 
1964  return(outer_*vec2(c,-s));
1965  }
1966 
1967  virtual vec2 inner_point(double u)
1968  {
1969  double a = u*2*PI;
1970  double s = sin(a);
1971  double c = cos(a);
1972 
1973  return(inner_*vec2(c,-s));
1974  }
1975 
1976 };
1977 
1982 class lglHemiShim: public lglSheet
1983 {
1984 public:
1985 
1986  lglHemiShim(double outer = 1.0, double inner = 0.0,
1987  int tessel = 8, double size = 1.0, bool color = false)
1988  : lglSheet(),
1989  outer_(outer), inner_(inner)
1990  {
1991  std::string name = "hemi_shim";
1992  name += std::string("(");
1993  name += glslmath::to_string(outer) + ", ";
1994  name += glslmath::to_string(inner) + ", ";
1995  name += glslmath::to_string(size);
1996  name += std::string(")");
1997  setName(name);
1998 
1999  addTo(this, tessel, size, color);
2000  }
2001 
2002 protected:
2003 
2004  double outer_, inner_;
2005 
2006  virtual vec2 outer_point(double u)
2007  {
2008  double a = u*PI;
2009  double s = sin(a);
2010  double c = cos(a);
2011 
2012  return(outer_*vec2(s,-c));
2013  }
2014 
2015  virtual vec2 inner_point(double u)
2016  {
2017  double a = u*PI;
2018  double s = sin(a);
2019  double c = cos(a);
2020 
2021  return(inner_*vec2(s,-c));
2022  }
2023 
2024 };
2025 
2037 class lglSpiral: public lglSheet
2038 {
2039 public:
2040 
2041  lglSpiral(double outer = 1.0, double inner = 0.1,
2042  double thickness = 0.01, double windings = 10.0,
2043  int tessel = 8, double size = 1.0, bool color = false)
2044  : lglSheet(),
2045  outer_(outer), inner_(inner),
2046  thickness_(thickness), windings_(windings)
2047  {
2048  std::string name = "spiral";
2049  name += std::string("(");
2050  name += glslmath::to_string(outer) + ", ";
2051  name += glslmath::to_string(inner) + ", ";
2052  name += glslmath::to_string(size);
2053  name += std::string(")");
2054  setName(name);
2055 
2056  addTo(this, (int)ceil(tessel*windings+0.5), size, color);
2057  }
2058 
2059 protected:
2060 
2061  double outer_, inner_;
2062  double thickness_, windings_;
2063 
2064  virtual vec2 outer_point(double u)
2065  {
2066  static const double p = 5.0;
2067 
2068  double a = u*2*PI*windings_;
2069  double s = sin(a);
2070  double c = cos(a);
2071 
2072  u = u/2;
2073  u = 1-pow(1-u, p);
2074  u = u/(1-pow(0.5, p));
2075 
2076  double d = (1-u)*(inner_+thickness_)+u*outer_;
2077 
2078  return(d*vec2(c,-s));
2079  }
2080 
2081  virtual vec2 inner_point(double u)
2082  {
2083  static const double p = 5.0;
2084 
2085  double a = u*2*PI*windings_;
2086  double s = sin(a);
2087  double c = cos(a);
2088 
2089  u = u/2;
2090  u = 1-pow(1-u, p);
2091  u = u/(1-pow(0.5, p));
2092 
2093  double d = (1-u)*(inner_+thickness_)+u*outer_-thickness_;
2094 
2095  return(d*vec2(c,-s));
2096  }
2097 
2098 };
2099 
2113 {
2114 public:
2115 
2116  lglGear(double outer = 1.0, double inner = 0.0,
2117  double modul = 1.0/16, double angle = 0.0,
2118  double hk = 1.0,
2119  double hf = 0.167)
2120  : lglSheetBezier(),
2121  inner_radius_(inner)
2122  {
2123  std::string name = "gear";
2124  name += std::string("(");
2125  name += glslmath::to_string(outer) + ", ";
2126  name += glslmath::to_string(inner) + ", ";
2127  name += glslmath::to_string(modul) + ", ";
2128  name += glslmath::to_string(angle) + ", ";
2129  name += glslmath::to_string(hk) + ", ";
2130  name += glslmath::to_string(hf);
2131  name += std::string(")");
2132  setName(name);
2133 
2134  const int steps = 128;
2135 
2136  int z = (int)floor(2*outer/modul+0.5);
2137  modul = 2*outer/z;
2138 
2139  double d = outer;
2140  double df = outer-hk*modul;
2141  double dk = outer+hk*modul;
2142  double dg = outer-hk*modul;
2143 
2144  double a = acos(dg/d)*180/PI;
2145  if (angle > a) dg = d*cos(angle*PI/180);
2146  else angle = a;
2147 
2148  r_ = d;
2149  a_ = angle;
2150 
2151  m_ = modul;
2152  hk_ = hk;
2153  hf_ = hf;
2154 
2155  double u = -0.25*modul*PI/d;
2156 
2157  for (int i=0; i<z; i++)
2158  {
2159  int j = 0;
2160  double s;
2161 
2162  {
2163  vec2 p1 = d*vec2(cos(u),-sin(u));
2164 
2165  double l = sqrt(d*d-dg*dg);
2166  vec2 p2 = construct(vec2(0,0), p1, dg, l);
2167 
2168  double d = -l;
2169  vec2 p3 = evolve(vec2(0,0), -l, p2, d);
2170 
2171  for (int k=0; k<steps; k++)
2172  {
2173  vec2 a = p2;
2174  vec2 b = p3;
2175  double v = d;
2176  p3 = evolve(vec2(0,0), 2*l/steps, p2, d);
2177  if (p3.norm() > df*df)
2178  {
2179  p2 = a;
2180  p3 = b;
2181  d = v;
2182  break;
2183  }
2184  }
2185 
2186  addOuterPoint(p3*(df-hf*modul)/df, false);
2187 
2188  addOuterPoint(p3, false);
2189  for (; j<steps; j++)
2190  {
2191  vec2 p = p2;
2192  double v = d;
2193  p3 = evolve(vec2(0,0), 2*l/steps, p2, d);
2194  if (p3.norm() > dk*dk)
2195  {
2196  p2 = p;
2197  d = v;
2198  break;
2199  }
2200  addOuterPoint(p3);
2201  }
2202 
2203  outerStraighten();
2204 
2205  s = d+l;
2206  }
2207 
2208  u += 0.5*modul*PI/d;
2209 
2210  {
2211  vec2 p1 = d*vec2(cos(u),-sin(u));
2212 
2213  double l = sqrt(d*d-dg*dg);
2214  vec2 p2 = construct(p1, vec2(0,0), l, dg);
2215 
2216  double d = l;
2217  vec2 p3 = evolve(vec2(0,0), s, p2, d);
2218 
2219  addOuterPoint(p3, false);
2220  for (; j>0; j--)
2221  {
2222  p3 = evolve(vec2(0,0), 2*l/steps, p2, d);
2223  addOuterPoint(p3);
2224  }
2225 
2226  outerStraighten();
2227 
2228  addOuterPoint(p3*(df-hf*modul)/df, false);
2229  }
2230 
2231  u += 0.5*modul*PI/d;
2232  }
2233 
2234  outerClose();
2235  outerAlign();
2236  }
2237 
2238  double contactRadius()
2239  {
2240  return(r_);
2241  }
2242 
2243  double contactAngle()
2244  {
2245  return(a_);
2246  }
2247 
2248  double toothModul()
2249  {
2250  return(m_);
2251  }
2252 
2253  int teeth()
2254  {
2255  return((int)floor(2*r_/m_+0.5));
2256  }
2257 
2258 protected:
2259 
2260  double r_; // contact radius
2261  double a_; // contact angle
2262 
2263  double m_; // tooth modul
2264  double hk_; // tooth geometry
2265  double hf_; // foot geometry
2266 
2267  double inner_radius_;
2268 
2269  vec2 evolve(vec2 center, double delta, vec2 &point, double &dist)
2270  {
2271  double radius = (point-center).length();
2272  double angle = delta/radius*180/PI;
2273 
2274  mat2 R = mat2::rotate(angle);
2275  point = R * (point - center) + center;
2276  dist -= delta;
2277 
2278  vec2 d = point - center;
2279  vec2 n = vec2(d.y,-d.x).normalize();
2280 
2281  return(point + n*dist);
2282  }
2283 
2284  vec2 construct(vec2 p1, vec2 p2, double d1, double d2)
2285  {
2286  vec2 d = p2 - p1;
2287  double l = d.length();
2288 
2289  double h = d1*d2/l;
2290  double m = sqrt(d1*d1-h*h);
2291 
2292  vec2 p = p1 + m/l*d;
2293  vec2 n = vec2(d.y,-d.x)/l;
2294 
2295  return(p + n*h);
2296  }
2297 
2298  virtual vec2 inner_point(double u)
2299  {
2300  return(inner_radius_*outer_point(u).normalize());
2301  }
2302 
2303  virtual double inner_first(int steps, bool *align = NULL)
2304  {
2305  return(outer_first(steps, align));
2306  }
2307 
2308  virtual double inner_last(int steps)
2309  {
2310  return(outer_last(steps));
2311  }
2312 
2313  virtual double inner_next(double u, int steps, bool *align = NULL)
2314  {
2315  return(outer_next(u, steps, align));
2316  }
2317 
2318 };
2319 
2321 class lglFunctional: public lglVBO
2322 {
2323 public:
2324 
2325  lglFunctional(const std::string &name = "functional")
2326  : lglVBO(name)
2327  {}
2328 
2329 protected:
2330 
2331  virtual vec3 point(double u, double v) = 0;
2332 
2333  virtual vec3 normal(double u, double v, double d,
2334  bool swapx, bool swapy)
2335  {
2336  vec3 p1 = point(u-d, v);
2337  vec3 p2 = point(u+d, v);
2338  vec3 p3 = point(u, v-d);
2339  vec3 p4 = point(u, v+d);
2340 
2341  double dx = swapx? -d : d;
2342  double dy = swapy? -d : d;
2343 
2344  vec3 p5 = point(u-d, v-d);
2345  vec3 p6 = point(u+dx, v+dy);
2346  vec3 p7 = point(u-dx, v+d);
2347  vec3 p8 = point(u+d, v-dy);
2348 
2349  vec3 du = p2-p1+p6-p5+p8-p7;
2350  vec3 dv = p4-p3+p7-p8+p6-p5;
2351 
2352  vec3 n = dv.cross(du);
2353 
2354  return(n.normalize());
2355  }
2356 
2357  virtual vec3 normal(double u, double v, double d = 0.001)
2358  {
2359  return(normal(u, v, d, false, false));
2360  }
2361 
2362 };
2363 
2366 {
2367 public:
2368 
2369  lglRotational(const std::string &name = "rotational")
2370  : lglFunctional(name),
2371  begin_(0), end_(1)
2372  {}
2373 
2374  void setRange(double begin, double end)
2375  {
2376  begin_ = begin/360;
2377  end_ = end/360;
2378  }
2379 
2380  void create(int tessel = 8, bool color = false)
2381  {
2382  clear();
2383  addTo(this, tessel, color);
2384  }
2385 
2386  void addTo(lglVBO *vbo, int tessel = 8, bool color = false)
2387  {
2388  int i, j;
2389 
2390  double u, v, w;
2391  vec3 p, n;
2392 
2393  int alpha_steps = 4*tessel;
2394  int beta_steps = (int)ceil(tessel*(end_-begin_));
2395 
2396  vec4 col = vbo->lglGetColor();
2397 
2398  for (j=-beta_steps; j<beta_steps; j++)
2399  {
2400  vbo->lglBegin(LGL_QUAD_STRIP);
2401 
2402  if (color) vbo->lglColor(col);
2403 
2404  for (i=0; i<=alpha_steps; i++)
2405  {
2406  u = (double)i/alpha_steps;
2407  v = (double)j/beta_steps;
2408 
2409  w = (1-v)*begin_ + v*end_;
2410 
2411  p = point(u, w);
2412  n = normal(u, w);
2413 
2414  vbo->lglNormal(n);
2415  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
2416  vbo->lglVertex(p);
2417 
2418  v = (double)(j+1)/beta_steps;
2419 
2420  w = (1-v)*begin_ + v*end_;
2421 
2422  p = point(u, w);
2423  n = normal(u, w);
2424 
2425  vbo->lglNormal(n);
2426  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
2427  vbo->lglVertex(p);
2428  }
2429 
2430  vbo->lglEnd();
2431  }
2432  }
2433 
2434 protected:
2435 
2436  double begin_, end_;
2437 
2438  virtual vec3 point(double u, double v)
2439  {
2440  vec2 p = evaluate(u, v);
2441  vec4 p4 = vec4(0, p.y, p.x);
2442 
2443  double alpha = u*360;
2444  mat4 R = mat4::rotate(alpha, vec3(0,0,-1));
2445 
2446  return(R * p4);
2447  }
2448 
2449  virtual vec3 normal(double u, double v, double d = 0.001)
2450  {
2451  if (v==-1 || v==1)
2452  if (vec2(point(u,v)).norm() == 0)
2453  {
2454  if (v==-1)
2455  return(-lglFunctional::normal(u, v, d, true, false));
2456  else
2457  return(lglFunctional::normal(u, v, d, true, false));
2458  }
2459 
2460  return(lglFunctional::normal(u, v, d));
2461  }
2462 
2463  virtual vec2 evaluate(double u, double v) = 0;
2464 };
2465 
2472 {
2473 public:
2474 
2475  lglRotationalBezier(vec2 a, vec2 b, vec2 c, vec2 d)
2476  : lglRotational("rotational_bezier"),
2477  path_(a, b, c, d)
2478  {}
2479 
2481  : lglRotational("rotational_bezier"),
2482  path_(a, b)
2483  {}
2484 
2486  : lglRotational("rotational_bezier"),
2487  path_(path)
2488  {}
2489 
2491  : lglRotational("rotational_bezier"),
2492  path_(path)
2493  {}
2494 
2495  void release()
2496  {
2497  path_.clear();
2498  }
2499 
2500 protected:
2501 
2502  lgl_BezierMultiPath2D path_;
2503 
2504  virtual vec2 evaluate(double u, double v)
2505  {
2506  double w = 0.5*v+0.5;
2507  return(path_.evaluate(u, w));
2508  }
2509 
2510 };
2511 
2519 {
2520 public:
2521 
2522  lglCylindrical(const std::string &name = "cylindrical")
2523  : lglFunctional(name),
2524  begin_(0), end_(1)
2525  {}
2526 
2527  void setRange(double begin, double end)
2528  {
2529  begin_ = begin/360;
2530  end_ = end/360;
2531  }
2532 
2533  void create(int tessel = 8, bool color = false)
2534  {
2535  clear();
2536  addTo(this, tessel, color);
2537  }
2538 
2539  void addTo(lglVBO *vbo, int tessel = 8, bool color = false)
2540  {
2541  int i, j;
2542 
2543  double u, v, w;
2544  vec3 p, n;
2545 
2546  int alpha_steps = 4*tessel;
2547  int beta_steps = (int)ceil(tessel*(end_-begin_));
2548 
2549  vec4 col = vbo->lglGetColor();
2550 
2551  for (j=-beta_steps; j<beta_steps; j++)
2552  {
2553  vbo->lglBegin(LGL_QUAD_STRIP);
2554 
2555  if (color) vbo->lglColor(col);
2556 
2557  for (i=0; i<=alpha_steps; i++)
2558  {
2559  u = (double)i/alpha_steps;
2560  v = (double)j/beta_steps;
2561 
2562  w = (1-v)*begin_ + v*end_;
2563 
2564  p = point(u, w);
2565  n = normal(u, w);
2566 
2567  vbo->lglNormal(p);
2568  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
2569  vbo->lglVertex(p);
2570 
2571  v = (double)(j+1)/beta_steps;
2572 
2573  w = (1-v)*begin_ + v*end_;
2574 
2575  p = point(u, w);
2576  n = normal(u, w);
2577 
2578  vbo->lglNormal(n);
2579  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
2580  vbo->lglVertex(p);
2581  }
2582 
2583  vbo->lglEnd();
2584  }
2585  }
2586 
2587 protected:
2588 
2589  double begin_, end_;
2590 
2591  virtual vec3 point(double u, double v)
2592  {
2593  double alpha = u*2*PI;
2594 
2595  vec2 p = vec2(sin(alpha),
2596  cos(alpha));
2597 
2598  double f = evaluate(u, v);
2599 
2600  return(vec3(f*p, v));
2601  }
2602 
2603  virtual vec3 normal(double u, double v, double d = 0.001)
2604  {
2605  if (v==-1 || v==1)
2606  if (vec2(point(u,v)).norm() == 0)
2607  {
2608  if (v==-1)
2609  return(-lglFunctional::normal(u, v, d, true, false));
2610  else
2611  return(lglFunctional::normal(u, v, d, true, false));
2612  }
2613 
2614  return(lglFunctional::normal(u, v, d));
2615  }
2616 
2617  virtual double evaluate(double u, double v) = 0;
2618 };
2619 
2627 {
2628 public:
2629 
2630  lglSpherical(const std::string &name = "spherical")
2631  : lglFunctional(name),
2632  begin_(0), end_(1)
2633  {}
2634 
2635  void setRange(double begin, double end)
2636  {
2637  begin_ = begin/360;
2638  end_ = end/360;
2639  }
2640 
2641  void create(int tessel = 8, bool color = false)
2642  {
2643  clear();
2644  addTo(this, tessel, color);
2645  }
2646 
2647  void addTo(lglVBO *vbo, int tessel = 8, bool color = false)
2648  {
2649  int i, j;
2650 
2651  double u, v, w;
2652  vec3 p, n;
2653 
2654  int alpha_steps = 4*tessel;
2655  int beta_steps = (int)ceil(tessel*(end_-begin_));
2656 
2657  vec4 col = vbo->lglGetColor();
2658 
2659  for (j=-beta_steps; j<beta_steps; j++)
2660  {
2661  vbo->lglBegin(LGL_QUAD_STRIP);
2662 
2663  if (color) vbo->lglColor(col);
2664 
2665  for (i=0; i<=alpha_steps; i++)
2666  {
2667  u = (double)i/alpha_steps;
2668  v = (double)j/beta_steps;
2669 
2670  w = (1-v)*begin_ + v*end_;
2671 
2672  p = point(u, w);
2673  n = normal(u, w);
2674 
2675  vbo->lglNormal(n);
2676  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
2677  vbo->lglVertex(p);
2678 
2679  v = (double)(j+1)/beta_steps;
2680 
2681  w = (1-v)*begin_ + v*end_;
2682 
2683  p = point(u, w);
2684  n = normal(u, w);
2685 
2686  vbo->lglNormal(n);
2687  vbo->lglTexCoord(1.0f-(float)u,0.5f-(float)v/2);
2688  vbo->lglVertex(p);
2689  }
2690 
2691  vbo->lglEnd();
2692  }
2693  }
2694 
2695 protected:
2696 
2697  double begin_, end_;
2698 
2699  virtual vec3 point(double u, double v)
2700  {
2701  double alpha = u*2*PI;
2702  double beta = v*PI/2;
2703 
2704  vec3 p = vec3(sin(alpha)*cos(beta),
2705  cos(alpha)*cos(beta),
2706  sin(beta));
2707 
2708  double f = evaluate(u, v);
2709 
2710  return(f*p);
2711  }
2712 
2713  virtual vec3 normal(double u, double v, double d = 0.001)
2714  {
2715  if (v==-1 || v==1)
2716  if (vec2(point(u,v)).norm() == 0)
2717  {
2718  if (v==-1)
2719  return(-lglFunctional::normal(u, v, d, true, false));
2720  else
2721  return(lglFunctional::normal(u, v, d, true, false));
2722  }
2723 
2724  return(lglFunctional::normal(u, v, d));
2725  }
2726 
2727  virtual double evaluate(double u, double v) = 0;
2728 };
2729 
2737 {
2738 public:
2739 
2740  lglToroidal(const std::string &name = "toroidal")
2741  : lglFunctional(name),
2742  begin_(0), end_(1),
2743  diameter_(1)
2744  {}
2745 
2746  void setRange(double begin, double end)
2747  {
2748  begin_ = begin/360;
2749  end_ = end/360;
2750  }
2751 
2752  void setDiameter(double diameter)
2753  {
2754  diameter_ = diameter;
2755  }
2756 
2757  void create(int tessel = 8, bool color = false)
2758  {
2759  clear();
2760  addTo(this, tessel, color);
2761  }
2762 
2763  void addTo(lglVBO *vbo, int tessel = 8, bool color = false)
2764  {
2765  int i, j;
2766 
2767  double u, v, w;
2768  vec3 p, n;
2769 
2770  int alpha_steps = 4*tessel;
2771  int beta_steps = (int)ceil(8*tessel*(end_-begin_));
2772 
2773  vec4 col = vbo->lglGetColor();
2774 
2775  for (j=0; j<=beta_steps; j++)
2776  {
2777  vbo->lglBegin(LGL_QUAD_STRIP);
2778 
2779  if (color) vbo->lglColor(col);
2780 
2781  for (i=0; i<=alpha_steps; i++)
2782  {
2783  u = (double)i/alpha_steps;
2784  v = (double)j/beta_steps;
2785 
2786  w = (1-v)*begin_ + v*end_;
2787 
2788  p = point(u, w);
2789  n = normal(u, w);
2790 
2791  vbo->lglNormal(n);
2792  vbo->lglTexCoord((float)u,(float)v);
2793  vbo->lglVertex(p);
2794 
2795  v = (double)(j+1)/beta_steps;
2796 
2797  w = (1-v)*begin_ + v*end_;
2798 
2799  p = point(u, w);
2800  n = normal(u, w);
2801 
2802  vbo->lglNormal(n);
2803  vbo->lglTexCoord((float)u,(float)v);
2804  vbo->lglVertex(p);
2805  }
2806 
2807  lglEnd();
2808  }
2809  }
2810 
2811 protected:
2812 
2813  double begin_, end_;
2814  double diameter_;
2815 
2816  virtual vec3 point(double u, double v)
2817  {
2818  double alpha = u*2*PI;
2819  double beta = v*360;
2820 
2821  double f = evaluate(u, v)/2;
2822 
2823  vec2 p = vec2(sin(alpha),
2824  cos(alpha));
2825 
2826  vec4 p4 = vec4(p.x*f-diameter_/2, p.y*f, 0);
2827 
2828  mat4 R = mat4::rotate(beta, vec3(0,1,0));
2829 
2830  return(R * p4);
2831  }
2832 
2833  virtual double evaluate(double u, double v) = 0;
2834 };
2835 
2841 class lglTorus: public lglToroidal
2842 {
2843 public:
2844 
2845  lglTorus(double diameter, double radius)
2846  : lglToroidal("torus"),
2847  radius_(radius)
2848  {
2849  setDiameter(diameter);
2850  create();
2851  }
2852 
2853 protected:
2854 
2855  double radius_;
2856 
2857  virtual double evaluate(double u, double v)
2858  {
2859  return(radius_);
2860  }
2861 
2862 };
2863 
2869 {
2870 public:
2871 
2872  lglHemiTorus(double diameter, double radius,
2873  double begin = 0, double end = 180)
2874  : lglToroidal("hemi_torus"),
2875  radius_(radius)
2876  {
2877  setRange(begin, end);
2878  setDiameter(diameter);
2879  create();
2880  }
2881 
2882 protected:
2883 
2884  double radius_;
2885 
2886  virtual double evaluate(double u, double v)
2887  {
2888  return(radius_);
2889  }
2890 
2891 };
2892 
2895 {
2896 public:
2897 
2898  lglExtrusion(const std::string &name = "extrusion")
2899  : lglFunctional(name)
2900  {}
2901 
2902  void create(int tessel = 8, bool color = false)
2903  {
2904  clear();
2905  addTo(this, tessel, color);
2906  }
2907 
2908  void addTo(lglVBO *vbo, int tessel = 8, bool color = false)
2909  {
2910  int i, j;
2911 
2912  double u, v;
2913  vec3 p, n;
2914 
2915  int alpha_steps = tessel * tessel_u();
2916  int beta_steps = tessel * tessel_v();
2917 
2918  vec4 col = vbo->lglGetColor();
2919 
2920  for (j=0; j<beta_steps; j++)
2921  {
2922  vbo->lglBegin(LGL_QUAD_STRIP);
2923 
2924  if (color) vbo->lglColor(col);
2925 
2926  for (i=0; i<=alpha_steps; i++)
2927  {
2928  u = (double)i/alpha_steps;
2929  v = (double)(j+1)/beta_steps;
2930 
2931  p = point(u, v);
2932  n = normal(u, v);
2933 
2934  vbo->lglNormal(n);
2935  vbo->lglTexCoord((float)u,1.0f-(float)v);
2936  vbo->lglVertex(p);
2937 
2938  v = (double)j/beta_steps;
2939 
2940  p = point(u, v);
2941  n = normal(u, v);
2942 
2943  vbo->lglNormal(n);
2944  vbo->lglTexCoord((float)u,1.0f-(float)v);
2945  vbo->lglVertex(p);
2946  }
2947 
2948  vbo->lglEnd();
2949  }
2950  }
2951 
2952 protected:
2953 
2954  virtual vec3 point(double u, double v)
2955  {
2956  vec2 p = evaluate(u, v);
2957  return(extrude(p, v));
2958  }
2959 
2960  virtual vec3 normal(double u, double v, double d = 0.001)
2961  {
2962  int i = tessel_u();
2963  int j = tessel_v();
2964 
2965  double maxdu = 1;
2966  if (i > 0) maxdu = 0.01/i;
2967  if (maxdu < d) d = maxdu;
2968 
2969  double maxdv = 1;
2970  if (j > 0) maxdv = 0.01/j;
2971  if (maxdv < d) d = maxdv;
2972 
2973  return(-lglFunctional::normal(u, v, d));
2974  }
2975 
2976  virtual int tessel_u() {return(1);}
2977  virtual int tessel_v() {return(1);}
2978 
2979  virtual vec2 evaluate(double u, double v) = 0;
2980  virtual vec3 extrude(vec2 p, double v) = 0;
2981 };
2982 
2989 {
2990 public:
2991 
2992  lglExtrusionBezier(vec2 a, vec2 b, vec2 c, vec2 d,
2993  const lgl_BezierPath3D &extrusion)
2994  : lglExtrusion("extrusion_bezier"),
2995  path_(a, b, c, d),
2996  extrusion_(extrusion)
2997  {}
2998 
3000  const lgl_BezierPath3D &extrusion)
3001  : lglExtrusion("extrusion_bezier"),
3002  path_(a, b),
3003  extrusion_(extrusion)
3004  {}
3005 
3007  const lgl_BezierPath3D &extrusion)
3008  : lglExtrusion("extrusion_bezier"),
3009  path_(path),
3010  extrusion_(extrusion)
3011  {}
3012 
3014  const lgl_BezierPath3D &extrusion)
3015  : lglExtrusion("extrusion_bezier"),
3016  path_(path),
3017  extrusion_(extrusion)
3018  {}
3019 
3020  void release()
3021  {
3022  path_.clear();
3023  extrusion_.clear();
3024  }
3025 
3026 protected:
3027 
3028  lgl_BezierMultiPath2D path_;
3029  lgl_BezierPath3D extrusion_;
3030 
3031  virtual vec2 evaluate(double u, double v)
3032  {
3033  return(path_.evaluate(v, u));
3034  }
3035 
3036  virtual vec3 extrude(vec2 p, double v)
3037  {
3038  static const int steps = 2*tessel_v();
3039 
3040  int n = (int)ceil(v*steps);
3041 
3042  quat q = quat::rotate(vec3(0,0,-1), extrusion_.gradient(0));
3043 
3044  for (int i=0; i<n; i++)
3045  {
3046  double w1 = (double)i/n*v;
3047  double w2 = (double)(i+1)/n*v;
3048 
3049  q *= quat::rotate(extrusion_.gradient(w1), extrusion_.gradient(w2));
3050  }
3051 
3052  vec3 r = q*vec3(p,0);
3053  vec3 o = extrusion_.evaluate(v);
3054 
3055  return(o+r);
3056  }
3057 
3058  virtual int tessel_u() {return(path_.getMaxCurves());}
3059  virtual int tessel_v() {return(extrusion_.size());}
3060 };
3061 
3066 {
3067 public:
3068 
3069  lglReplicatedGeometry(const lglVBO *vbo, const lgl_BezierPath3D &path, int n)
3070  : lglVBO("replicated_geometry")
3071  {
3072  lglMatrixMode(LGL_PREMODEL);
3073  lglPushMatrix();
3074 
3075  quat q = quat::rotate(vec3(0,0,-1), path.gradient(0));
3076  q *= quat::rotate(path.gradient(0), path.gradient(0.5/n));
3077 
3078  for (int i=0; i<n; i++)
3079  {
3080  double w = (double)(i+0.5)/n;
3081 
3082  lglLoadMatrix(mat4::transform(q, path.evaluate(w)));
3083  vbo->lglAppendVerticesTo(this);
3084 
3085  q *= quat::rotate(path.gradient(w), path.gradient(w+1.0/n));
3086  }
3087 
3088  lglPopMatrix();
3089  lglMatrixMode(LGL_MODELVIEW);
3090  }
3091 
3092 };
3093 
3096 {
3097 public:
3098 
3099  lglPlanar(const std::string &name = "planar")
3100  : lglFunctional(name)
3101  {}
3102 
3103  void create(int tessel = 8, bool color = false)
3104  {
3105  clear();
3106  addTo(this, tessel, color);
3107  }
3108 
3109  void addTo(lglVBO *vbo, int tessel = 8, bool color = false)
3110  {
3111  int i, j;
3112 
3113  double u, v;
3114  vec3 p, n;
3115 
3116  int alpha_steps = tessel * tessel_u();
3117  int beta_steps = tessel * tessel_v();
3118 
3119  vec4 col = vbo->lglGetColor();
3120 
3121  for (j=0; j<beta_steps; j++)
3122  {
3123  vbo->lglBegin(LGL_QUAD_STRIP);
3124 
3125  if (color) vbo->lglColor(col);
3126 
3127  for (i=0; i<=alpha_steps; i++)
3128  {
3129  u = (double)i/alpha_steps;
3130  v = (double)(j+1)/beta_steps;
3131 
3132  p = point(u, v);
3133  n = normal(u, v);
3134 
3135  vbo->lglNormal(n);
3136  vbo->lglTexCoord((float)u,1.0f-(float)v);
3137  vbo->lglVertex(p);
3138 
3139  v = (double)j/beta_steps;
3140 
3141  p = point(u, v);
3142  n = normal(u, v);
3143 
3144  vbo->lglNormal(n);
3145  vbo->lglTexCoord((float)u,1.0f-(float)v);
3146  vbo->lglVertex(p);
3147  }
3148 
3149  lglEnd();
3150  }
3151  }
3152 
3153 protected:
3154 
3155  virtual vec3 point(double u, double v)
3156  {
3157  return(evaluate(u, v));
3158  }
3159 
3160  virtual vec3 normal(double u, double v, double d = 0.001)
3161  {
3162  int i = tessel_u();
3163  int j = tessel_v();
3164 
3165  double maxdu = 1;
3166  if (i > 0) maxdu = 0.01/i;
3167  if (maxdu < d) d = maxdu;
3168 
3169  double maxdv = 1;
3170  if (j > 0) maxdv = 0.01/j;
3171  if (maxdv < d) d = maxdv;
3172 
3173  return(-lglFunctional::normal(u, v, d));
3174  }
3175 
3176  virtual vec3 evaluate(double u, double v) = 0;
3177 
3178  virtual int tessel_u() {return(1);}
3179  virtual int tessel_v() {return(1);}
3180 };
3181 
3188 {
3189 public:
3190 
3191  lglPlanarBezier(const lgl_BezierMesh &mesh)
3192  : lglPlanar("planar_bezier"),
3193  mesh_(mesh)
3194  {}
3195 
3196  void release()
3197  {
3198  mesh_.clear();
3199  }
3200 
3201 protected:
3202 
3203  lgl_BezierMesh mesh_;
3204 
3205  virtual vec3 evaluate(double u, double v)
3206  {
3207  return(mesh_.evaluate(u, v));
3208  }
3209 
3210  virtual int tessel_u() {return(mesh_.getCols()-1);}
3211  virtual int tessel_v() {return(mesh_.getRows()-1);}
3212 };
3213 
3220 class lglWireCube: public lglVBO
3221 {
3222 public:
3223 
3224  lglWireCube()
3225  : lglVBO("wireframe_cube")
3226  {
3227  addLines(this);
3228  }
3229 
3230  static void addLines(lglVBO *vbo)
3231  {
3232  vbo->lglBegin(LGL_LINES);
3233 
3234  // vertical edges
3235  vbo->lglVertex(-0.5,-0.5,0.5);
3236  vbo->lglVertex(-0.5,0.5,0.5);
3237  vbo->lglVertex(0.5,-0.5,0.5);
3238  vbo->lglVertex(0.5,0.5,0.5);
3239  vbo->lglVertex(0.5,-0.5,-0.5);
3240  vbo->lglVertex(0.5,0.5,-0.5);
3241  vbo->lglVertex(-0.5,-0.5,-0.5);
3242  vbo->lglVertex(-0.5,0.5,-0.5);
3243 
3244  // bottom edges
3245  vbo->lglVertex(-0.5,-0.5,0.5);
3246  vbo->lglVertex(0.5,-0.5,0.5);
3247  vbo->lglVertex(0.5,-0.5,0.5);
3248  vbo->lglVertex(0.5,-0.5,-0.5);
3249  vbo->lglVertex(0.5,-0.5,-0.5);
3250  vbo->lglVertex(-0.5,-0.5,-0.5);
3251  vbo->lglVertex(-0.5,-0.5,-0.5);
3252  vbo->lglVertex(-0.5,-0.5,0.5);
3253 
3254  // top edges
3255  vbo->lglVertex(-0.5,0.5,0.5);
3256  vbo->lglVertex(0.5,0.5,0.5);
3257  vbo->lglVertex(0.5,0.5,0.5);
3258  vbo->lglVertex(0.5,0.5,-0.5);
3259  vbo->lglVertex(0.5,0.5,-0.5);
3260  vbo->lglVertex(-0.5,0.5,-0.5);
3261  vbo->lglVertex(-0.5,0.5,-0.5);
3262  vbo->lglVertex(-0.5,0.5,0.5);
3263 
3264  vbo->lglEnd();
3265  }
3266 
3267 };
3268 
3276 class lglCoordSys: public lglVBO
3277 {
3278 public:
3279 
3280  lglCoordSys()
3281  : lglVBO("coordinate_system_axis")
3282  {
3283  addLines(this);
3284  }
3285 
3286  static void addLines(lglVBO *vbo)
3287  {
3288  static const double a = 0.1;
3289  static const double b = 0.3*a;
3290 
3291  vbo->lglBegin(LGL_LINES);
3292 
3293  // x-axis
3294  vbo->lglColor(1,0,0);
3295  vbo->lglVertex(0,0,0);
3296  vbo->lglVertex(1,0,0);
3297  vbo->lglVertex(1-a,-b,0);
3298  vbo->lglVertex(1,0,0);
3299  vbo->lglVertex(1-a,b,0);
3300  vbo->lglVertex(1,0,0);
3301 
3302  // y-axis
3303  vbo->lglColor(0,1,0);
3304  vbo->lglVertex(0,0,0);
3305  vbo->lglVertex(0,1,0);
3306  vbo->lglVertex(-b,1-a,0);
3307  vbo->lglVertex(0,1,0);
3308  vbo->lglVertex(b,1-a,0);
3309  vbo->lglVertex(0,1,0);
3310 
3311  // z-axis
3312  vbo->lglColor(0,0,1);
3313  vbo->lglVertex(0,0,0);
3314  vbo->lglVertex(0,0,1);
3315  vbo->lglVertex(0,-b,1-a);
3316  vbo->lglVertex(0,0,1);
3317  vbo->lglVertex(0,b,1-a);
3318  vbo->lglVertex(0,0,1);
3319 
3320  vbo->lglEnd();
3321 
3322  // X
3323  vbo->lglBegin(LGL_LINES);
3324  vbo->lglColor(1,0,0);
3325  vbo->lglEnd();
3326  vbo->lglMatrixMode(LGL_PREMODEL);
3327  vbo->lglPushMatrix();
3328  vbo->lglTranslate(0.7f,0.1f,0);
3329  vbo->lglMatrixMode(LGL_MODELVIEW);
3330  lglDrawString(0.25f, "X", false, vbo);
3331  vbo->lglMatrixMode(LGL_PREMODEL);
3332  vbo->lglPopMatrix();
3333  vbo->lglMatrixMode(LGL_MODELVIEW);
3334 
3335  // Y
3336  vbo->lglBegin(LGL_LINES);
3337  vbo->lglColor(0,1,0);
3338  vbo->lglEnd();
3339  vbo->lglMatrixMode(LGL_PREMODEL);
3340  vbo->lglPushMatrix();
3341  vbo->lglTranslate(0.1f,0.65f,0);
3342  vbo->lglMatrixMode(LGL_MODELVIEW);
3343  lglDrawString(0.25f, "Y", false, vbo);
3344  vbo->lglMatrixMode(LGL_PREMODEL);
3345  vbo->lglPopMatrix();
3346  vbo->lglMatrixMode(LGL_MODELVIEW);
3347 
3348  // Z
3349  vbo->lglBegin(LGL_LINES);
3350  vbo->lglColor(0,0,1);
3351  vbo->lglEnd();
3352  vbo->lglMatrixMode(LGL_PREMODEL);
3353  vbo->lglPushMatrix();
3354  vbo->lglTranslate(0,0.1f,0.9f);
3355  vbo->lglRotate(90, 0,1,0);
3356  vbo->lglMatrixMode(LGL_MODELVIEW);
3357  lglDrawString(0.25f, "Z", false, vbo);
3358  vbo->lglMatrixMode(LGL_PREMODEL);
3359  vbo->lglPopMatrix();
3360  vbo->lglMatrixMode(LGL_MODELVIEW);
3361  }
3362 
3363 };
3364 
3369 class lglText: public lglVBO
3370 {
3371 public:
3372 
3373  lglText(std::string text)
3374  : lglVBO("text")
3375  {
3376  addLines(this, text);
3377  }
3378 
3379  static void addLines(lglVBO *vbo, std::string text)
3380  {
3381  lglDrawString(1, text.c_str(), false, vbo);
3382  }
3383 
3384 };
3385 
3387 class lglSharedVBO: public std::vector<mat4>
3388 {
3389 public:
3390 
3391  lglSharedVBO(lglVBO *vbo = NULL)
3392  : vbo_(vbo)
3393  {}
3394 
3396  void push_back()
3397  {
3398  lgl_matrixmode_enum mode = vbo_->lglGetMatrixMode();
3399  vbo_->lglMatrixMode(LGL_PREMODEL);
3400  push_back(vbo_->lglGetMatrix());
3401  vbo_->lglMatrixMode(mode);
3402  }
3403 
3405  void push_back(const mat4 &m)
3406  {
3407  std::vector<mat4>::push_back(m);
3408  }
3409 
3411  void lglSetVBO(lglVBO *vbo)
3412  {
3413  vbo_ = vbo;
3414  }
3415 
3417  void lglRender(lglVBO *vbo = NULL)
3418  {
3419  if (vbo_)
3420  {
3421  mat4 m = vbo_->lglGetModelMatrix();
3422  for (size_t i=0; i<size(); i++)
3423  {
3424  vbo_->lglModel(at(i));
3425  vbo_->lglRender(vbo);
3426  }
3427  vbo_->lglModel(m);
3428  }
3429  }
3430 
3431 protected:
3432 
3433  lglVBO *vbo_;
3434 };
3435 
3436 #endif
lglSharedVBO::lglSetVBO
void lglSetVBO(lglVBO *vbo)
set shared vbo
Definition: glvertex_geometry.h:3411
lgl_BezierMesh::evaluate
vec3 evaluate(double u, double v)
evaluate the bezier mesh
Definition: glvertex_bezier.h:2024
vec2::norm
double norm() const
get squared vector length
Definition: glslmath.h:136
lglToroidal
toroidal geometry (base class)
Definition: glvertex_geometry.h:2736
lgl::lglGetMatrixMode
lgl_matrixmode_enum lglGetMatrixMode() const
get the actual matrix mode
Definition: glvertex_core.h:1987
lglSharedVBO::lglRender
void lglRender(lglVBO *vbo=NULL)
render shared instances
Definition: glvertex_geometry.h:3417
lgl_BezierPath2D::straighten
void straighten()
disable alignment for the last added point
Definition: glvertex_bezier.h:544
lgl_BezierPath3D::evaluate
vec3 evaluate(double w) const
evaluate the 3D bezier path
Definition: glvertex_bezier.h:940
lgl::lglMatrixMode
void lglMatrixMode(lgl_matrixmode_enum mode=LGL_MODELVIEW)
determine the actual matrix mode
Definition: glvertex_core.h:1981
glvertex_bezier.h
lglTorus
torus geometry
Definition: glvertex_geometry.h:2841
lglCoordSys
unit coordinate system axis vbo
Definition: glvertex_geometry.h:3276
lglBox
rectangular box vbo
Definition: glvertex_geometry.h:222
vec3::normalize
vec3 normalize() const
normalize vector to unit length
Definition: glslmath.h:528
vec2
2D double vector
Definition: glslmath.h:108
lgl::lglPopMatrix
void lglPopMatrix()
pop the top entry of the matrix stack
Definition: glvertex_core.h:2095
vec4
4D double vector
Definition: glslmath.h:713
mat4::rotate
static mat4 rotate(double angle, double vx, double vy, double vz)
create rotation matrix
Definition: glslmath.h:2446
lgl_BezierMesh
bezier mesh consisting of multiple bezier surface patches
Definition: glvertex_bezier.h:1973
lglHemiRing
hemi-ring vbo
Definition: glvertex_geometry.h:1343
norm
double norm(const vec2 &v)
get squared vector length
Definition: glslmath.h:225
lglObj
unit obj vbo
Definition: glvertex_geometry.h:1457
glvertex.h
lgl_BezierPath2D::evaluate
vec2 evaluate(double w) const
evaluate the 2D bezier path
Definition: glvertex_bezier.h:593
lgl_matrixmode_enum
lgl_matrixmode_enum
matrix mode enum
Definition: glvertex_core.h:46
lgl::lglEnd
void lglEnd()
end a series of vertices
Definition: glvertex_core.h:981
lglTeapot
unit teapot vbo
Definition: glvertex_geometry.h:1518
lgl_BezierPath3D
3D bezier path consisting of multiple bezier curves
Definition: glvertex_bezier.h:828
lglRing
ring vbo
Definition: glvertex_geometry.h:1280
lgl::lglGetMatrix
mat4 lglGetMatrix() const
get the top entry of the matrix stack
Definition: glvertex_core.h:2123
lgl::clear
void clear()
clear all buffers
Definition: glvertex_core.h:737
length
double length(const vec2 &v)
get vector length
Definition: glslmath.h:221
lglHemiCylinder
unit hemi-cylinder vbo
Definition: glvertex_geometry.h:895
lgl_BezierPath2D::alignCurves
void alignCurves(double factor=(sqrt(2.0) -1) *4/3)
auto-align the curves of the 2D bezier path
Definition: glvertex_bezier.h:694
vec2::normalize
vec2 normalize() const
normalize vector to unit length
Definition: glslmath.h:229
lglPrism
unit prism vbo
Definition: glvertex_geometry.h:549
lglCone
unit cone vbo
Definition: glvertex_geometry.h:1114
lgl::lglRotate
void lglRotate(double angle, const vec3 &v)
rotate in immediate mode fashion
Definition: glvertex_core.h:2234
glvertex_vectortext.h
lglSharedVBO::push_back
void push_back(const mat4 &m)
add shared instance /w transformation matrix
Definition: glvertex_geometry.h:3405
lglSheetDisc
rotational disc sheet geometry
Definition: glvertex_geometry.h:1896
lgl::lglScale
void lglScale(const vec4 &c)
scale in immediate mode fashion
Definition: glvertex_core.h:2202
lglHemiDisc
unit hemi-disc vbo
Definition: glvertex_geometry.h:1053
lglExtrusionBezier
extrusion bezier geometry
Definition: glvertex_geometry.h:2988
vec3
3D double vector
Definition: glslmath.h:372
lglSpherical
rotational spherical geometry (base class)
Definition: glvertex_geometry.h:2626
glvertex_objformat.h
lgl_BezierMultiPath2D
container for linear interpolation of 2D bezier paths
Definition: glvertex_bezier.h:1165
mat2
2x2 double matrix
Definition: glslmath.h:1130
vec2::length
double length() const
get vector length
Definition: glslmath.h:133
lglLoadObj
bool lglLoadObj(lglVBO *vbo, const char *path, bool silent=false, lgl_texgenmode_enum texgen=LGL_TEXGEN_NONE, bool flip_v=true)
load OBJ into vbo from file path (and from default installation paths)
Definition: glvertex_objformat.h:313
mat4
4x4 double matrix
Definition: glslmath.h:2116
lglFunctional
functional geometry (base class)
Definition: glvertex_geometry.h:2321
lglSheetBezier
rotational bezier sheet geometry
Definition: glvertex_geometry.h:1775
lglHemiTorus
hemi-torus geometry
Definition: glvertex_geometry.h:2868
lgl_BezierPath2D::addPoint
unsigned int addPoint(vec2 p, bool align=true)
add a point to the 2D bezier path
Definition: glvertex_bezier.h:509
lglHemisphere
unit hemisphere vbo
Definition: glvertex_geometry.h:720
lglReplicatedGeometry
replicated geometry
Definition: glvertex_geometry.h:3065
lgl_BezierMultiPath2D::evaluate
vec2 evaluate(double v, double w) const
evaluate the 2D bezier multi-path
Definition: glvertex_bezier.h:1206
lgl
LGL core.
Definition: glvertex_core.h:156
lglGear
rotational gear geometry
Definition: glvertex_geometry.h:2112
lgl::lglTranslate
void lglTranslate(const vec4 &v)
translate in immediate mode fashion
Definition: glvertex_core.h:2221
vec3::cross
vec3 cross(const vec3 &v) const
cross product (0,0,-1)/(-1,0,0)=(0,1,0)
Definition: glslmath.h:433
lgl_BezierMultiPath2D::getMaxCurves
unsigned int getMaxCurves() const
get the maximum number of curves in the multi-path
Definition: glvertex_bezier.h:1192
lglCube
unit cube vbo
Definition: glvertex_geometry.h:19
lglShim
rotational shim geometry
Definition: glvertex_geometry.h:1934
lglDisc
unit disc vbo
Definition: glvertex_geometry.h:1002
lglSharedVBO::push_back
void push_back()
add shared instance in immediate mode fashion
Definition: glvertex_geometry.h:3396
lglSphere
unit sphere vbo
Definition: glvertex_geometry.h:653
quat::rotate
static quat rotate(double angle, const vec3 &v)
create rotating quaternion
Definition: glslmath.h:3036
lgl::lglRender
virtual void lglRender(const lgl *vbo=NULL)
render the series of vertices contained in vbo
Definition: glvertex_core.h:1079
quat
quaternion
Definition: glslmath.h:2972
lglExtrusion
extrusion geometry (base class)
Definition: glvertex_geometry.h:2894
lglPyramid
unit pyramid vbo
Definition: glvertex_geometry.h:336
lglRotationalBezier
rotational bezier geometry
Definition: glvertex_geometry.h:2471
lgl::lglRotateZ
void lglRotateZ(double angle)
rotate about z-axis in immediate mode fashion
Definition: glvertex_core.h:2259
lglText
unit text vbo
Definition: glvertex_geometry.h:3369
lgl_BezierPath3D::gradient
vec3 gradient(double w, int mode=0, double d=0.001) const
evaluate the gradient of the 3D bezier path
Definition: glvertex_bezier.h:972
lglCylinder
unit cylinder vbo
Definition: glvertex_geometry.h:789
lglVBO
LGL API: vbo class definition.
Definition: glvertex_core.h:5827
lgl::lglPushMatrix
void lglPushMatrix()
push the top entry of the matrix stack
Definition: glvertex_core.h:2069
lglSharedVBO
shared vbo container
Definition: glvertex_geometry.h:3387
cross
vec3 cross(const vec3 &a, const vec3 &b)
cross product
Definition: glslmath.h:544
lgl_texgenmode_enum
lgl_texgenmode_enum
texgen mode enum
Definition: glvertex_core.h:56
normalize
vec2 normalize(const vec2 &v)
normalization to unit length
Definition: glslmath.h:237
lgl::lglGetMaxAbsCoord
double lglGetMaxAbsCoord() const
get the maximum absolute value of the coordinates in vbo
Definition: glvertex_core.h:1874
lgl::lglGetColor
vec4 lglGetColor() const
get the actual color attribute
Definition: glvertex_core.h:844
lgl::lglBegin
void lglBegin(lgl_primitive_enum primitive)
begin a series of vertices for a particular graphics primitive
Definition: glvertex_core.h:917
lglCylindrical
rotational cylindrical geometry (base class)
Definition: glvertex_geometry.h:2518
lglTet
unit tetrahedron vbo
Definition: glvertex_geometry.h:258
lglArc
arc vbo
Definition: glvertex_geometry.h:1406
lglConeBase
cone base vbo
Definition: glvertex_geometry.h:1167
lglPlanarBezier
planar bezier geometry
Definition: glvertex_geometry.h:3187
lgl::lglModel
void lglModel()
reset the vbo modeling matrix
Definition: glvertex_core.h:2525
lgl::lglGetModelMatrix
mat4 lglGetModelMatrix() const
get the vbo modeling matrix
Definition: glvertex_core.h:2539
lglWireCube
unit wireframe cube vbo
Definition: glvertex_geometry.h:3220
lglPyramidBase
pyramid base vbo
Definition: glvertex_geometry.h:426
lgl::lglLoadMatrix
void lglLoadMatrix(const mat4 &matrix)
load a specific matrix in immediate mode fashion
Definition: glvertex_core.h:2019
lgl::lglAppendVerticesTo
void lglAppendVerticesTo(lgl *vbo) const
append a copy of the vertices and attributes in vbo to another vbo
Definition: glvertex_core.h:1928
lglHemiShim
rotational hemi-shim geometry
Definition: glvertex_geometry.h:1982
mat2::rotate
static mat2 rotate(double angle)
create rotation matrix
Definition: glslmath.h:1295
lglSpiral
rotational spiral geometry
Definition: glvertex_geometry.h:2037
lgl_BezierPath2D
2D bezier path consisting of multiple bezier curves
Definition: glvertex_bezier.h:481
lgl_BezierPath2D::close
void close()
close the 2D bezier path by reduplicating the first point
Definition: glvertex_bezier.h:553
lgl::setName
void setName(std::string name="")
set the vbo name
Definition: glvertex_core.h:209
lglPlanar
planar geometry (base class)
Definition: glvertex_geometry.h:3095
lglSheet
rotational sheet geometry (base class)
Definition: glvertex_geometry.h:1529
lglRotational
rotational geometry (base class)
Definition: glvertex_geometry.h:2365
mat4::transform
static mat4 transform(const mat3 &m, const vec3 &v)
create affine (resp.
Definition: glslmath.h:2647
lglDrawString
void lglDrawString(float width, const char *str, bool centered=true, lglVBO *vbo=NULL)
draw text string using vector graphics
Definition: glvertex_vectortext.h:143