~ubuntu-branches/ubuntu/trusty/3depict/trusty

« back to all changes in this revision

Viewing changes to src/drawables.cpp

  • Committer: Package Import Robot
  • Author(s): D Haley
  • Date: 2013-05-17 00:52:39 UTC
  • mfrom: (3.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20130517005239-7bl4mnhkvrhc2ba6
Tags: 0.0.13-1
Upload to unstable 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *      drawables.cpp - opengl drawable objects cpp file
3
 
 *      Copyright (C) 2011, D Haley 
4
 
 
5
 
 *      This program is free software: you can redistribute it and/or modify
6
 
 *      it under the terms of the GNU General Public License as published by
7
 
 *      the Free Software Foundation, either version 3 of the License, or
8
 
 *      (at your option) any later version.
9
 
 
10
 
 *      This program is distributed in the hope that it will be useful,
11
 
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *      GNU General Public License for more details.
14
 
 
15
 
 *      You should have received a copy of the GNU General Public License
16
 
 *      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
*/
18
 
 
19
 
#include "drawables.h"
20
 
 
21
 
#include "colourmap.h"
22
 
 
23
 
#include "isoSurface.h"
24
 
 
25
 
#include <limits>
26
 
#include "mathfuncs.h"
27
 
 
28
 
//OpenGL debugging macro
29
 
#if DEBUG
30
 
#include <iostream>
31
 
#include <cstdlib>
32
 
#define glError() { \
33
 
                GLenum err = glGetError(); \
34
 
                while (err != GL_NO_ERROR) { \
35
 
                                        fprintf(stderr, "glError: %s caught at %s:%u\n", (char *)gluErrorString(err), __FILE__, __LINE__); \
36
 
                                        err = glGetError(); \
37
 
                                } \
38
 
                std::cerr << "glErr Clean " << __FILE__ << ":" << __LINE__ << std::endl; \
39
 
}
40
 
#else
41
 
#define glError()
42
 
#endif
43
 
 
44
 
const float DEPTH_SORT_REORDER_EPSILON = 1e-2;
45
 
 
46
 
//Static class variables
47
 
//====
48
 
const Camera *DrawableObj::curCamera = 0;
49
 
//==
50
 
 
51
 
 
52
 
//Common functions
53
 
//
54
 
void drawBox(Point3D pMin, Point3D pMax, float r,float g, float b, float a)
55
 
{
56
 
        //TODO: Could speedup with LINE_STRIP/LOOP. This is 
57
 
        //not a bottleneck atm though.
58
 
        glBegin(GL_LINES);
59
 
                glColor4f(r,g,b,a);
60
 
                //Bottom corner out (three lines from corner)
61
 
                glVertex3f(pMin[0],pMin[1],pMin[2]);
62
 
                glVertex3f(pMax[0],pMin[1],pMin[2]);
63
 
                
64
 
                glVertex3f(pMin[0],pMin[1],pMin[2]);
65
 
                glVertex3f(pMin[0],pMax[1],pMin[2]);
66
 
 
67
 
                glVertex3f(pMin[0],pMin[1],pMin[2]);
68
 
                glVertex3f(pMin[0],pMin[1],pMax[2]);
69
 
                
70
 
                //Top Corner out (three lines from corner)
71
 
                glVertex3f(pMax[0],pMax[1],pMax[2]);
72
 
                glVertex3f(pMin[0],pMax[1],pMax[2]);
73
 
        
74
 
                glVertex3f(pMax[0],pMax[1],pMax[2]);
75
 
                glVertex3f(pMax[0],pMin[1],pMax[2]);
76
 
                
77
 
                glVertex3f(pMax[0],pMax[1],pMax[2]);
78
 
                glVertex3f(pMax[0],pMax[1],pMin[2]);
79
 
 
80
 
                //Missing pieces - in an "across-down-across" shape
81
 
                glVertex3f(pMin[0],pMax[1],pMin[2]);
82
 
                glVertex3f(pMax[0],pMax[1],pMin[2]);
83
 
                
84
 
                glVertex3f(pMax[0],pMax[1],pMin[2]);
85
 
                glVertex3f(pMax[0],pMin[1],pMin[2]);
86
 
 
87
 
                glVertex3f(pMax[0],pMin[1],pMin[2]);
88
 
                glVertex3f(pMax[0],pMin[1],pMax[2]);
89
 
                
90
 
                glVertex3f(pMax[0],pMin[1],pMax[2]);
91
 
                glVertex3f(pMin[0],pMin[1],pMax[2]);
92
 
                
93
 
                glVertex3f(pMin[0],pMin[1],pMax[2]);
94
 
                glVertex3f(pMin[0],pMax[1],pMax[2]);
95
 
 
96
 
                glVertex3f(pMin[0],pMax[1],pMax[2]);
97
 
                glVertex3f(pMin[0],pMax[1],pMin[2]);
98
 
        glEnd();
99
 
}
100
 
 
101
 
 
102
 
using std::vector;
103
 
 
104
 
DrawableObj::DrawableObj() : active(true), haveChanged(true), canSelect(false), wantsLight(false)
105
 
{
106
 
}
107
 
 
108
 
DrawableObj::~DrawableObj()
109
 
{
110
 
}
111
 
 
112
 
//=====
113
 
 
114
 
DrawPoint::DrawPoint() : origin(0.0f,0.0f,0.0f), r(1.0f), g(1.0f), b(1.0f), a(1.0f)
115
 
{
116
 
}
117
 
 
118
 
DrawPoint::DrawPoint(float x, float y, float z) : origin(x,y,z), r(1.0f), g(1.0f), b(1.0f)
119
 
{
120
 
}
121
 
 
122
 
DrawPoint::~DrawPoint()
123
 
{
124
 
}
125
 
 
126
 
 
127
 
 
128
 
 
129
 
void DrawPoint::setColour(float rnew, float gnew, float bnew, float anew)
130
 
{
131
 
        r=rnew;
132
 
        g=gnew;
133
 
        b=bnew;
134
 
        a=anew;
135
 
}
136
 
 
137
 
 
138
 
 
139
 
void DrawPoint::setOrigin(const Point3D &pt)
140
 
{
141
 
        origin = pt;
142
 
}
143
 
 
144
 
 
145
 
void DrawPoint::draw() const
146
 
{
147
 
        glColor4f(r,g,b,a);
148
 
        glBegin(GL_POINT);
149
 
        glVertex3f(origin[0],origin[1],origin[2]);
150
 
        glEnd();
151
 
}
152
 
 
153
 
DrawVector::DrawVector() : origin(0.0f,0.0f,0.0f), vector(0.0f,0.0f,1.0f),arrowSize(1.0f),scaleArrow(true),
154
 
                        r(1.0f), g(1.0f), b(1.0f), a(1.0f)
155
 
{
156
 
}
157
 
 
158
 
DrawVector::~DrawVector()
159
 
{
160
 
}
161
 
 
162
 
 
163
 
void DrawVector::getBoundingBox(BoundCube &b) const 
164
 
{
165
 
        b.setBounds(origin,vector+origin);
166
 
}
167
 
 
168
 
void DrawVector::setColour(float rnew, float gnew, float bnew, float anew)
169
 
{
170
 
        r=rnew;
171
 
        g=gnew;
172
 
        b=bnew;
173
 
        a=anew;
174
 
}
175
 
 
176
 
void DrawVector::setOrigin(const Point3D &pt)
177
 
{
178
 
        origin = pt;
179
 
}
180
 
 
181
 
void DrawVector::setVector(const Point3D &pt)
182
 
{
183
 
        vector= pt;
184
 
}
185
 
 
186
 
void DrawVector::draw() const
187
 
{
188
 
        glColor3f(r,g,b);
189
 
        //FIXME: Arrow head calculations?
190
 
        glBegin(GL_LINES);
191
 
                glVertex3f(origin[0],origin[1],origin[2]);
192
 
                glVertex3f(vector[0]+origin[0],vector[1]+origin[1],vector[2]+origin[2]);
193
 
        glEnd();
194
 
}
195
 
 
196
 
void DrawVector::recomputeParams(const std::vector<Point3D> &vecs, 
197
 
                        const std::vector<float> &scalars, unsigned int mode)
198
 
{
199
 
        switch(mode)
200
 
        {
201
 
                case DRAW_VECTOR_BIND_ORIENTATION:
202
 
                        ASSERT(vecs.size() ==1 && scalars.size() ==0);
203
 
                        vector=vecs[0];
204
 
                        break;
205
 
                case DRAW_VECTOR_BIND_ORIGIN:
206
 
                        ASSERT(vecs.size() == 1 && scalars.size()==0);
207
 
                        origin=vecs[0];
208
 
                        break;
209
 
                case DRAW_VECTOR_BIND_ORIGIN_ONLY:
210
 
                {
211
 
                        ASSERT(vecs.size() == 1 && scalars.size()==0);
212
 
 
213
 
                        Point3D dv;
214
 
                        dv=vector-origin;
215
 
                        origin=vecs[0];
216
 
                        vector=origin+dv;
217
 
                        break;
218
 
                }
219
 
                case DRAW_VECTOR_BIND_TARGET:
220
 
                        ASSERT(vecs.size() == 1 && scalars.size()==0);
221
 
                        vector=vecs[0]-origin;
222
 
                        break;
223
 
                default:
224
 
                        ASSERT(false);
225
 
        }
226
 
}
227
 
DrawTriangle::DrawTriangle() : r(1.0f), g(1.0f),b(1.0f),a(1.0f)
228
 
{
229
 
}
230
 
 
231
 
DrawTriangle::~DrawTriangle()
232
 
{
233
 
}
234
 
 
235
 
void DrawTriangle::setVertex(unsigned int ui, const Point3D &pt)
236
 
{
237
 
        ASSERT(ui < 3);
238
 
        vertices[ui] = pt;
239
 
}
240
 
 
241
 
void DrawTriangle::setColour(float rnew, float gnew, float bnew, float anew)
242
 
{
243
 
        r=rnew;
244
 
        g=gnew;
245
 
        b=bnew;
246
 
        a=anew;
247
 
}
248
 
 
249
 
void DrawTriangle::draw() const
250
 
{
251
 
        glColor4f(r,g,b,a);
252
 
        glBegin(GL_TRIANGLES);
253
 
                glVertex3f((vertices[0])[0],
254
 
                        (vertices[0])[1], (vertices[0])[2]);
255
 
                glVertex3f((vertices[1])[0],
256
 
                        (vertices[1])[1], (vertices[1])[2]);
257
 
                glVertex3f((vertices[2])[0],
258
 
                        (vertices[2])[1], (vertices[2])[2]);
259
 
        glEnd();
260
 
}
261
 
 
262
 
 
263
 
DrawSphere::DrawSphere() : radius(1.0f), latSegments(8),longSegments(8)
264
 
{
265
 
        q=gluNewQuadric();
266
 
}
267
 
 
268
 
DrawSphere::~DrawSphere()
269
 
{
270
 
        if(q)
271
 
                gluDeleteQuadric(q);
272
 
}
273
 
 
274
 
 
275
 
 
276
 
void DrawSphere::getBoundingBox(BoundCube &b) const
277
 
{
278
 
        for(unsigned int ui=0;ui<3;ui++)
279
 
        {
280
 
                b.setBound(ui,0,origin[ui] - radius);
281
 
                b.setBound(ui,1,origin[ui] + radius);
282
 
        }
283
 
}
284
 
 
285
 
void DrawSphere::setOrigin(const Point3D &p)
286
 
{
287
 
        origin = p;
288
 
}
289
 
 
290
 
void DrawSphere::setLatSegments(unsigned int ui)
291
 
{
292
 
        latSegments = ui;
293
 
}
294
 
 
295
 
void DrawSphere::setLongSegments(unsigned int ui)
296
 
{
297
 
        longSegments = ui;
298
 
}
299
 
 
300
 
void DrawSphere::setRadius(float rad)
301
 
{
302
 
        radius=rad;
303
 
}
304
 
 
305
 
void DrawSphere::setColour(float rnew, float gnew, float bnew, float anew)
306
 
{
307
 
        r=rnew;
308
 
        g=gnew;
309
 
        b=bnew;
310
 
        a=anew;
311
 
}
312
 
 
313
 
void DrawSphere::draw() const 
314
 
{
315
 
        if(!q)
316
 
                return;
317
 
 
318
 
        glPushMatrix();
319
 
                glTranslatef(origin[0],origin[1],origin[2]);
320
 
                glColor4f(r,g,b,a);
321
 
                gluSphere(q,radius,latSegments,longSegments);
322
 
        glPopMatrix();
323
 
}
324
 
 
325
 
 
326
 
void DrawSphere::recomputeParams(const vector<Point3D> &vecs, 
327
 
                        const vector<float> &scalars, unsigned int mode)
328
 
{
329
 
        switch(mode)
330
 
        {
331
 
                case DRAW_SPHERE_BIND_ORIGIN:
332
 
                        ASSERT(vecs.size() ==1 && scalars.size() ==0);
333
 
                        origin=vecs[0];
334
 
                        break;
335
 
                case DRAW_SPHERE_BIND_RADIUS:
336
 
                        ASSERT(scalars.size() == 1 && vecs.size()==0);
337
 
                        radius=scalars[0];
338
 
                        break;
339
 
                default:
340
 
                        ASSERT(false);
341
 
        }
342
 
}
343
 
//===========
344
 
 
345
 
DrawCylinder::DrawCylinder() : radius(1.0f), 
346
 
                origin(0.0f,0.0f,0.0f), direction(0.0f,0.0f,1.0f), slices(4),stacks(4)
347
 
{
348
 
        q= gluNewQuadric();
349
 
        qCap[0]= gluNewQuadric();
350
 
        if(qCap[0])
351
 
                gluQuadricOrientation(qCap[0],GLU_INSIDE);      
352
 
        qCap[1]= gluNewQuadric();
353
 
        if(qCap[1])
354
 
                gluQuadricOrientation(qCap[1],GLU_OUTSIDE);     
355
 
        radiiLocked=false;
356
 
}
357
 
 
358
 
bool DrawCylinder::needsDepthSorting()  const
359
 
{
360
 
        return a< 1 && a > std::numeric_limits<float>::epsilon();
361
 
}
362
 
 
363
 
DrawCylinder::~DrawCylinder()
364
 
{
365
 
        if(q)
366
 
                gluDeleteQuadric(q);
367
 
        if(qCap[0])
368
 
                gluDeleteQuadric(qCap[0]);
369
 
        if(qCap[1])
370
 
                gluDeleteQuadric(qCap[1]);
371
 
}
372
 
 
373
 
 
374
 
void DrawCylinder::setOrigin(const Point3D& pt)
375
 
{
376
 
        origin=pt;
377
 
}
378
 
 
379
 
 
380
 
void DrawCylinder::setDirection(const Point3D &p)
381
 
{
382
 
        direction=p;
383
 
}
384
 
 
385
 
 
386
 
void DrawCylinder::draw() const
387
 
{
388
 
        if(!q || !qCap[0] || !qCap[1])
389
 
                return;
390
 
 
391
 
        //Cross product desired drection with default
392
 
        //direction to produce rotation vector
393
 
        Point3D dir(0.0f,0.0f,1.0f);
394
 
 
395
 
        glPushMatrix();
396
 
        glTranslatef(origin[0],origin[1],origin[2]);
397
 
 
398
 
        Point3D dirNormal(direction);
399
 
        dirNormal.normalise();
400
 
 
401
 
        float length=sqrtf(direction.sqrMag());
402
 
        float angle = dir.angle(dirNormal);
403
 
        if(angle < M_PI - sqrt(std::numeric_limits<float>::epsilon()) &&
404
 
                angle > sqrt(std::numeric_limits<float>::epsilon()))
405
 
        {
406
 
                //we need to rotate
407
 
                dir = dir.crossProd(dirNormal);
408
 
 
409
 
                glRotatef(angle*180.0f/M_PI,dir[0],dir[1],dir[2]);
410
 
        }
411
 
 
412
 
        //OpenGL defined cylinder starting at 0 and going to lenght. I want it starting at 0 and going to+-l/2
413
 
        glTranslatef(0,0,-length/2.0f);
414
 
        glColor4f(r,g,b,a);
415
 
        
416
 
        //Draw the end cap at z=0
417
 
        if(radiiLocked)
418
 
        {
419
 
                gluDisk(qCap[0],0,radius,slices,1);
420
 
                gluCylinder(q,radius,radius, length,slices,stacks);
421
 
 
422
 
                //Draw the start cap at z=l     
423
 
                glTranslatef(0,0,length);
424
 
                gluDisk(qCap[1],0,radius,slices,1);
425
 
        }
426
 
        else
427
 
        {
428
 
                ASSERT(false);
429
 
        }
430
 
 
431
 
        glPopMatrix();
432
 
}
433
 
 
434
 
void DrawCylinder::setSlices(unsigned int i)
435
 
{
436
 
        slices=i;
437
 
}
438
 
 
439
 
void DrawCylinder::setStacks(unsigned int i)
440
 
{
441
 
        stacks=i;
442
 
}
443
 
 
444
 
void DrawCylinder::setRadius(float rad)
445
 
{
446
 
        radius=rad;
447
 
}
448
 
 
449
 
void DrawCylinder::recomputeParams(const vector<Point3D> &vecs, 
450
 
                        const vector<float> &scalars, unsigned int mode)
451
 
{
452
 
        switch(mode)
453
 
        {
454
 
                case DRAW_CYLINDER_BIND_ORIGIN:
455
 
                        ASSERT(vecs.size() ==1 && scalars.size() ==0);
456
 
                        origin=vecs[0];
457
 
                        break;
458
 
 
459
 
                case DRAW_CYLINDER_BIND_DIRECTION:
460
 
                        ASSERT(vecs.size() ==1 && scalars.size() ==0);
461
 
                        direction=vecs[0];
462
 
                        break;
463
 
                case DRAW_CYLINDER_BIND_RADIUS:
464
 
                        ASSERT(scalars.size() == 1 && vecs.size()==0);
465
 
                        radius=scalars[0];
466
 
                        break;
467
 
                default:
468
 
                        ASSERT(false);
469
 
        }
470
 
}
471
 
 
472
 
 
473
 
void DrawCylinder::setLength(float len)
474
 
{
475
 
        ASSERT(direction.sqrMag());
476
 
        direction=direction.normalise()*len;
477
 
}
478
 
 
479
 
void DrawCylinder::setColour(float rnew, float gnew, float bnew, float anew)
480
 
{
481
 
        r=rnew;
482
 
        g=gnew;
483
 
        b=bnew;
484
 
        a=anew;
485
 
}
486
 
 
487
 
void DrawCylinder::getBoundingBox(BoundCube &b) const
488
 
{
489
 
 
490
 
        float tmp;
491
 
 
492
 
        Point3D normAxis(direction);
493
 
        normAxis.normalise();
494
 
        
495
 
        //Height offset for ending circles. 
496
 
        //The joint bounding box of these two is the 
497
 
        //overall bounding box
498
 
        Point3D offset;
499
 
 
500
 
 
501
 
 
502
 
        //X component
503
 
        tmp=sin(acos(normAxis.dotProd(Point3D(1,0,0))));
504
 
        offset[0] = radius*tmp;
505
 
 
506
 
        //Y component
507
 
        tmp=sin(acos(normAxis.dotProd(Point3D(0,1,0))));
508
 
        offset[1] = radius*tmp;
509
 
 
510
 
        //Z component
511
 
        tmp=sin(acos(normAxis.dotProd(Point3D(0,0,1))));
512
 
        offset[2] = radius*tmp;
513
 
 
514
 
        vector<Point3D> p;
515
 
        p.resize(4);
516
 
        p[0]= offset+(direction*0.5+origin);
517
 
        p[1]= -offset+(direction*0.5+origin);
518
 
        p[2]= offset+(-direction*0.5+origin);
519
 
        p[3]= -offset+(-direction*0.5+origin);
520
 
 
521
 
        b.setBounds(p);
522
 
}
523
 
 
524
 
 
525
 
//======
526
 
 
527
 
DrawManyPoints::DrawManyPoints() : r(1.0f),g(1.0f),b(1.0f),a(1.0f), size(1.0f)
528
 
{
529
 
        wantsLight=false;
530
 
}
531
 
 
532
 
DrawManyPoints::~DrawManyPoints() 
533
 
{
534
 
        wantsLight=false;
535
 
        haveCachedBounds=false;
536
 
}
537
 
 
538
 
void DrawManyPoints::getBoundingBox(BoundCube &b) const
539
 
{
540
 
 
541
 
        //Update the cache as needed
542
 
        if(!haveCachedBounds)
543
 
        {
544
 
                haveCachedBounds=true;
545
 
                cachedBounds.setBounds(pts);
546
 
        }
547
 
 
548
 
        b=cachedBounds;
549
 
        return;
550
 
}
551
 
 
552
 
void DrawManyPoints::explode(vector<DrawableObj *> &simpleObjects)
553
 
{
554
 
        simpleObjects.resize(pts.size());
555
 
 
556
 
        for(size_t ui=0;ui<simpleObjects.size();ui++)
557
 
        {
558
 
        }
559
 
}
560
 
 
561
 
void DrawManyPoints::clear()
562
 
{
563
 
        pts.clear();
564
 
}
565
 
 
566
 
void DrawManyPoints::addPoints(const vector<Point3D> &vp)
567
 
{
568
 
        pts.reserve(pts.size()+vp.size());
569
 
        std::copy(vp.begin(),vp.end(),pts.begin());
570
 
}
571
 
 
572
 
/*
573
 
void DrawManyPoints::addPoints(const vector<IonHit> &vp)
574
 
{
575
 
        pts.reserve(pts.size()+vp.size());
576
 
        for(size_t ui=0; ui<vp.size(); ui++)
577
 
                pts.push_back(vp[ui].getPos());
578
 
        haveCachedBounds=false;
579
 
}
580
 
*/
581
 
void DrawManyPoints::shuffle()
582
 
{
583
 
        std::random_shuffle(pts.begin(),pts.end());
584
 
}
585
 
 
586
 
 
587
 
void DrawManyPoints::addPoint(const Point3D &p)
588
 
{
589
 
        pts.push_back(p);
590
 
        haveCachedBounds=false;
591
 
}
592
 
 
593
 
void DrawManyPoints::setColour(float rnew, float gnew, float bnew, float anew)
594
 
{
595
 
        r=rnew;
596
 
        g=gnew;
597
 
        b=bnew;
598
 
        a=anew;
599
 
}
600
 
 
601
 
void DrawManyPoints::setSize(float f)
602
 
{
603
 
        size=f;
604
 
}
605
 
 
606
 
void DrawManyPoints::draw() const
607
 
{
608
 
        const Point3D *p;
609
 
        glPointSize(size); 
610
 
        glBegin(GL_POINTS);
611
 
                glColor4f(r,g,b,a);
612
 
                //TODO: Consider Vertex buffer objects. would be faster, but less portable.
613
 
                for(unsigned int ui=0; ui<pts.size(); ui++)
614
 
                {
615
 
                        p=&(pts[ui]);
616
 
                        glVertex3fv(p->getValueArr());
617
 
                }
618
 
        glEnd();
619
 
}
620
 
 
621
 
//======
622
 
 
623
 
DrawDispList::DrawDispList() : listNum(0),listActive(false)
624
 
{
625
 
}
626
 
 
627
 
DrawDispList::~DrawDispList()
628
 
{
629
 
        if(listNum)
630
 
        {
631
 
                ASSERT(!listActive);
632
 
                ASSERT(glIsList(listNum));
633
 
                glDeleteLists(listNum,1);
634
 
        }
635
 
 
636
 
}
637
 
 
638
 
bool DrawDispList::startList(bool execute)
639
 
{
640
 
        //Ensure that the user has appropriately closed the list
641
 
        ASSERT(!listActive);
642
 
        boundBox.setInverseLimits();
643
 
        
644
 
        //If the list is already genned, clear it
645
 
        if(listNum)
646
 
                glDeleteLists(listNum,1);
647
 
 
648
 
        //Create the display list (ask for one)
649
 
        listNum=glGenLists(1);
650
 
 
651
 
        if(listNum)
652
 
        {
653
 
                if(execute)
654
 
                        glNewList(listNum,GL_COMPILE_AND_EXECUTE);
655
 
                else
656
 
                        glNewList(listNum,GL_COMPILE);
657
 
                listActive=true;
658
 
        }
659
 
        return (listNum!=0);
660
 
}
661
 
 
662
 
void DrawDispList::addDrawable(const DrawableObj *d)
663
 
{
664
 
        ASSERT(listActive);
665
 
        BoundCube b;
666
 
        d->getBoundingBox(b);
667
 
        boundBox.expand(b);
668
 
        d->draw();
669
 
}
670
 
 
671
 
bool DrawDispList::endList()
672
 
{
673
 
        glEndList();
674
 
 
675
 
        ASSERT(boundBox.isValid());
676
 
        listActive=false;       
677
 
        return (glGetError() ==0);
678
 
}
679
 
 
680
 
void DrawDispList::draw() const
681
 
{
682
 
        ASSERT(!listActive);
683
 
 
684
 
        //Cannot select display list objects,
685
 
        //as we cannot modify them without a "do-over".
686
 
        ASSERT(!canSelect);
687
 
 
688
 
        ASSERT(glIsList(listNum));
689
 
        //Execute the list      
690
 
        glPushMatrix();
691
 
        glCallList(listNum);
692
 
        glPopMatrix();
693
 
}
694
 
 
695
 
//========
696
 
 
697
 
 
698
 
DrawGLText::DrawGLText(std::string fontFile, unsigned int mode) : curFontMode(mode), origin(0.0f,0.0f,0.0f), r(0.0),g(0.0),b(0.0),a(1.0), up(0.0f,1.0f,0.0f),  textDir(1.0f,0.0f,0.0f), readDir(0.0f,0.0f,1.0f), isOK(true),ensureReadFromNorm(true) 
699
 
{
700
 
        fontString = fontFile;
701
 
 
702
 
        font=0;
703
 
        switch(mode)
704
 
        {
705
 
                case FTGL_BITMAP:
706
 
                        font = new FTGLBitmapFont(fontFile.c_str());
707
 
                        break;
708
 
                case FTGL_PIXMAP:
709
 
                        font = new FTGLPixmapFont(fontFile.c_str());
710
 
                        break;
711
 
                case FTGL_OUTLINE:
712
 
                        font = new FTGLOutlineFont(fontFile.c_str());
713
 
                        break;
714
 
                case FTGL_POLYGON:
715
 
                        font = new FTGLPolygonFont(fontFile.c_str());
716
 
                        break;
717
 
                case FTGL_EXTRUDE:
718
 
                        font = new FTGLExtrdFont(fontFile.c_str());
719
 
                        break;
720
 
                case FTGL_TEXTURE:
721
 
                        font = new FTGLTextureFont(fontFile.c_str());
722
 
                        break;
723
 
                default:
724
 
                        //Don't do this. Use valid font numbers
725
 
                        ASSERT(false);
726
 
                        font=0; 
727
 
        }
728
 
 
729
 
        //In case of allocation failure or invalid font num
730
 
        if(!font || font->Error())
731
 
        {
732
 
                isOK=false;
733
 
                return;
734
 
        }
735
 
 
736
 
        //Try to make it 100 point
737
 
        font->FaceSize(5);
738
 
        font->Depth(20);
739
 
 
740
 
        //Use unicode
741
 
        font->CharMap(ft_encoding_unicode);
742
 
 
743
 
        alignMode = DRAWTEXT_ALIGN_LEFT;
744
 
}
745
 
 
746
 
void DrawGLText::draw() const
747
 
{
748
 
        if(!isOK)
749
 
                return;
750
 
 
751
 
        //Translate the drawing position to the origin
752
 
        Point3D offsetVec=textDir;
753
 
        float advance;
754
 
        float halfHeight;
755
 
        
756
 
        FTBBox box;
757
 
        box=font->BBox(strText.c_str());
758
 
        advance=box.Upper().X()-box.Lower().X();
759
 
        
760
 
        halfHeight=box.Upper().Y()-box.Lower().Y();
761
 
        halfHeight/=2.0f;
762
 
 
763
 
        switch(alignMode)
764
 
        {
765
 
                case DRAWTEXT_ALIGN_LEFT:
766
 
                        break;
767
 
                case DRAWTEXT_ALIGN_CENTRE:
768
 
                        offsetVec=offsetVec*advance/2.0f;
769
 
                        break;
770
 
                case DRAWTEXT_ALIGN_RIGHT:
771
 
                        offsetVec=offsetVec*advance;
772
 
                        break;
773
 
                default:
774
 
                        ASSERT(false);
775
 
        }
776
 
        
777
 
 
778
 
        glPushMatrix();
779
 
 
780
 
 
781
 
        glPushAttrib(GL_CULL_FACE);
782
 
 
783
 
        glDisable(GL_CULL_FACE);
784
 
        if(curFontMode !=FTGL_BITMAP)
785
 
        {
786
 
                offsetVec=origin-offsetVec;
787
 
                glTranslatef(offsetVec[0],offsetVec[1],offsetVec[2]);
788
 
 
789
 
                //Rotate such that the new X-Y plane is set to the
790
 
                //desired text orientation. (ie. we want to draw the text in the 
791
 
                //specified combination of updir-textdir, rather than in the X-y plane)
792
 
 
793
 
                //---   
794
 
                //Textdir and updir MUST be normal to one another
795
 
                ASSERT(textDir.dotProd(up) < sqrtf(std::numeric_limits<float>::epsilon()));
796
 
 
797
 
                //rotate around textdir cross X, if the two are not the same
798
 
                Point3D rotateAxis;
799
 
                Point3D newUp=up;
800
 
                float angle=textDir.angle(Point3D(1,0,0) );
801
 
                if(angle > sqrtf(std::numeric_limits<float>::epsilon()))
802
 
                {
803
 
                        rotateAxis = textDir.crossProd(Point3D(-1,0,0));
804
 
                        rotateAxis.normalise();
805
 
                        
806
 
                        Point3f tmp,axis;
807
 
                        tmp.fx=up[0];
808
 
                        tmp.fy=up[1];
809
 
                        tmp.fz=up[2];
810
 
 
811
 
                        axis.fx=rotateAxis[0];
812
 
                        axis.fy=rotateAxis[1];
813
 
                        axis.fz=rotateAxis[2];
814
 
 
815
 
 
816
 
                        glRotatef(angle*180.0f/M_PI,rotateAxis[0],rotateAxis[1],rotateAxis[2]);
817
 
                        quat_rot(&tmp,&axis,angle); //angle is in radiians
818
 
 
819
 
                        newUp[0]=tmp.fx;
820
 
                        newUp[1]=tmp.fy;
821
 
                        newUp[2]=tmp.fz;
822
 
                }
823
 
 
824
 
                //rotate new up direction into y around x axis
825
 
                angle = newUp.angle(Point3D(0,1,0));
826
 
                if(angle > sqrtf(std::numeric_limits<float>::epsilon()) &&
827
 
                        fabs(angle - M_PI) > sqrtf(std::numeric_limits<float>::epsilon())) 
828
 
                {
829
 
                        rotateAxis = newUp.crossProd(Point3D(0,-1,0));
830
 
                        rotateAxis.normalise();
831
 
                        glRotatef(angle*180.0f/M_PI,rotateAxis[0],rotateAxis[1],rotateAxis[2]);
832
 
                }
833
 
 
834
 
                //Ensure that the text is not back-culled (i.e. if the
835
 
                //text normal is pointing away from the camera, it does not
836
 
                //get drawn). Here we have to flip the normal, by spinning the 
837
 
                //text by 180 around its up direction (which has been modified
838
 
                //by above code to coincide with the y axis.
839
 
                if(curCamera)
840
 
                {
841
 
                        //This is not *quite* right in perspective mode
842
 
                        //but is right in orthogonal
843
 
 
844
 
                        Point3D textNormal,camVec;
845
 
                        textNormal = up.crossProd(textDir);
846
 
                        textNormal.normalise();
847
 
 
848
 
                        camVec = origin - curCamera->getOrigin();
849
 
 
850
 
                        //ensure the camera is not sitting on top of the text.                  
851
 
                        if(camVec.sqrMag() > std::numeric_limits<float>::epsilon())
852
 
                        {
853
 
 
854
 
                                camVec.normalise();
855
 
 
856
 
                                if(camVec.dotProd(textNormal) < 0)
857
 
                                {
858
 
                                        //move halfway along text, noting that 
859
 
                                        //the text direction is now the x-axis
860
 
                                        glTranslatef(advance/2.0f,halfHeight,0);
861
 
                                        //spin text around its up direction 180 degrees
862
 
                                        glRotatef(180,0,1,0);
863
 
                                        //restore back to original position
864
 
                                        glTranslatef(-advance/2.0f,-halfHeight,0);
865
 
                                }
866
 
                        
867
 
                                camVec=curCamera->getUpDirection();     
868
 
                                if(camVec.dotProd(up) < 0)
869
 
                                {
870
 
                                        //move halfway along text, noting that 
871
 
                                        //the text direction is now the x-axis
872
 
                                        glTranslatef(advance/2.0f,halfHeight,0);
873
 
                                        //spin text around its front direction 180 degrees
874
 
                                        //no need to trnaslate as text sits at its baseline
875
 
                                        glRotatef(180,0,0,1);
876
 
                                        //move halfway along text, noting that 
877
 
                                        //the text direction is now the x-axis
878
 
                                        glTranslatef(-advance/2.0f,-halfHeight,0);
879
 
                                }
880
 
 
881
 
                        }
882
 
 
883
 
 
884
 
                }
885
 
 
886
 
        }
887
 
        else
888
 
        {
889
 
                //FIXME: The text ends up in a wierd location
890
 
                //2D coordinate storage for bitmap text
891
 
                double xWin,yWin,zWin;
892
 
                //Compute the 2D coordinates
893
 
                double model_view[16];
894
 
                glGetDoublev(GL_MODELVIEW_MATRIX, model_view);
895
 
 
896
 
                double projection[16];
897
 
                glGetDoublev(GL_PROJECTION_MATRIX, projection);
898
 
 
899
 
                int viewport[4];
900
 
                glGetIntegerv(GL_VIEWPORT, viewport);
901
 
 
902
 
                //Apply the openGL coordinate transformation pipleine to the
903
 
                //specified coords
904
 
                gluProject(offsetVec[0],offsetVec[1],offsetVec[2]
905
 
                                ,model_view,projection,viewport,
906
 
                                        &xWin,&yWin,&zWin);
907
 
 
908
 
                glRasterPos3f(xWin,yWin,zWin);
909
 
 
910
 
        }
911
 
        //---
912
 
 
913
 
 
914
 
        glColor4f(r,g,b,a);
915
 
 
916
 
        //Draw text
917
 
        if(curFontMode == FTGL_TEXTURE)
918
 
        {
919
 
                glPushAttrib(GL_ENABLE_BIT);
920
 
                glEnable(GL_TEXTURE_2D);
921
 
        
922
 
                font->Render(strText.c_str());
923
 
                glPopAttrib();
924
 
        }
925
 
        else
926
 
                font->Render(strText.c_str());
927
 
 
928
 
        glPopAttrib();
929
 
        
930
 
        glPopMatrix();
931
 
}
932
 
 
933
 
DrawGLText::~DrawGLText()
934
 
{
935
 
        if(font)
936
 
                delete font;
937
 
}
938
 
 
939
 
void DrawGLText::setColour(float rnew, float gnew, float bnew, float anew)
940
 
{
941
 
        r=rnew;
942
 
        g=gnew;
943
 
        b=bnew;
944
 
        a=anew;
945
 
}
946
 
 
947
 
void DrawGLText::getBoundingBox(BoundCube &b) const
948
 
{
949
 
 
950
 
        if(isOK)
951
 
        {
952
 
                float minX,minY,minZ;
953
 
                float maxX,maxY,maxZ;
954
 
                font->BBox(strText.c_str(),minX,minY,minZ,maxX,maxY,maxZ);
955
 
                b.setBounds(minX+origin[0],minY+origin[1],minZ+origin[2],
956
 
                                maxX+origin[0],maxY+origin[1],maxZ+origin[2]);
957
 
        }
958
 
        else
959
 
                b.setInverseLimits();   
960
 
        
961
 
}
962
 
 
963
 
void DrawGLText::setAlignment(unsigned int newMode)
964
 
{
965
 
        ASSERT(newMode < DRAWTEXT_ALIGN_ENUM_END);
966
 
        alignMode=newMode;
967
 
}
968
 
 
969
 
void DrawGLText::recomputeParams(const vector<Point3D> &vecs, 
970
 
                        const vector<float> &scalars, unsigned int mode)
971
 
{
972
 
        switch(mode)
973
 
        {
974
 
                case DRAW_TEXT_BIND_ORIGIN:
975
 
                        ASSERT(vecs.size() ==1 && scalars.size() ==0);
976
 
                        origin=vecs[0];
977
 
                        break;
978
 
                default:
979
 
                        ASSERT(false);
980
 
        }
981
 
}
982
 
 
983
 
DrawRectPrism::DrawRectPrism()
984
 
{
985
 
        r=g=b=a=1.0f;
986
 
        drawMode=DRAW_WIREFRAME;
987
 
        lineWidth=1.0f;
988
 
}
989
 
DrawRectPrism::~DrawRectPrism()
990
 
{
991
 
}
992
 
 
993
 
void DrawRectPrism::getBoundingBox(BoundCube &b) const
994
 
{
995
 
        b.setBounds(pMin[0],pMin[1],pMin[2],
996
 
                        pMax[0],pMax[1],pMax[2]);
997
 
}
998
 
 
999
 
void DrawRectPrism::draw() const
1000
 
{
1001
 
        ASSERT(r <=1.0f && g<=1.0f && b <=1.0f && a <=1.0f);
1002
 
        ASSERT(r >=0.0f && g>=0.0f && b >=0.0f && a >=0.0f);
1003
 
 
1004
 
        if(!active)
1005
 
                return;
1006
 
 
1007
 
        switch(drawMode)
1008
 
        {
1009
 
                case DRAW_WIREFRAME:
1010
 
                {
1011
 
                        glLineWidth(lineWidth); 
1012
 
                        drawBox(pMin,pMax,r,g,b,a);
1013
 
                        break;
1014
 
                }
1015
 
                case DRAW_FLAT:
1016
 
                {
1017
 
                        glBegin(GL_QUADS);
1018
 
                                glColor4f(r,g,b,a);
1019
 
                        
1020
 
                                glNormal3f(0,0,-1);
1021
 
                                //Along the bottom
1022
 
                                glVertex3f(pMin[0],pMin[1],pMin[2]);
1023
 
                                glVertex3f(pMin[0],pMax[1],pMin[2]);
1024
 
                                glVertex3f(pMax[0],pMax[1],pMin[2]);
1025
 
                                glVertex3f(pMax[0],pMin[1],pMin[2]);
1026
 
                                //Up the side
1027
 
                                glNormal3f(1,0,0);
1028
 
                                glVertex3f(pMax[0],pMax[1],pMax[2]);
1029
 
                                glVertex3f(pMax[0],pMin[1],pMax[2]);
1030
 
                                glVertex3f(pMax[0],pMin[1],pMin[2]);
1031
 
                                glVertex3f(pMax[0],pMax[1],pMin[2]);
1032
 
                                //Over the top
1033
 
                                glNormal3f(0,0,1);
1034
 
                                glVertex3f(pMax[0],pMin[1],pMax[2]);
1035
 
                                glVertex3f(pMax[0],pMax[1],pMax[2]);
1036
 
                                glVertex3f(pMin[0],pMax[1],pMax[2]);
1037
 
                                glVertex3f(pMin[0],pMin[1],pMax[2]);
1038
 
 
1039
 
                                //and back down
1040
 
                                glNormal3f(-1,0,0);
1041
 
                                glVertex3f(pMin[0],pMax[1],pMin[2]);
1042
 
                                glVertex3f(pMin[0],pMin[1],pMin[2]);
1043
 
                                glVertex3f(pMin[0],pMin[1],pMax[2]);
1044
 
                                glVertex3f(pMin[0],pMax[1],pMax[2]);
1045
 
 
1046
 
                                //Now the other two sides
1047
 
                                glNormal3f(0,-1,0);
1048
 
                                glVertex3f(pMax[0],pMin[1],pMax[2]);
1049
 
                                glVertex3f(pMin[0],pMin[1],pMax[2]);
1050
 
                                glVertex3f(pMin[0],pMin[1],pMin[2]);
1051
 
                                glVertex3f(pMax[0],pMin[1],pMin[2]);
1052
 
                                
1053
 
                                glNormal3f(0,1,0);
1054
 
                                glVertex3f(pMax[0],pMax[1],pMax[2]);
1055
 
                                glVertex3f(pMax[0],pMax[1],pMin[2]);
1056
 
                                glVertex3f(pMin[0],pMax[1],pMin[2]);
1057
 
                                glVertex3f(pMin[0],pMax[1],pMax[2]);
1058
 
 
1059
 
                        glEnd();
1060
 
 
1061
 
                        break;
1062
 
 
1063
 
                }
1064
 
                default:
1065
 
                        ASSERT(false);
1066
 
        }               
1067
 
 
1068
 
 
1069
 
}
1070
 
 
1071
 
void DrawRectPrism::setAxisAligned( const Point3D &p1, const Point3D &p2)
1072
 
{
1073
 
        for(unsigned int ui=0; ui<3; ui++)
1074
 
        {
1075
 
                pMin[ui]=std::min(p1[ui],p2[ui]);
1076
 
                pMax[ui]=std::max(p1[ui],p2[ui]);
1077
 
        }
1078
 
 
1079
 
}
1080
 
 
1081
 
void DrawRectPrism::setAxisAligned( const BoundCube &b)
1082
 
{
1083
 
        b.getBounds(pMin,pMax);
1084
 
}
1085
 
 
1086
 
void DrawRectPrism::setColour(float rnew, float gnew, float bnew, float anew)
1087
 
{
1088
 
        r=rnew;
1089
 
        g=gnew;
1090
 
        b=bnew;
1091
 
        a=anew;
1092
 
}
1093
 
 
1094
 
void DrawRectPrism::setLineWidth(float newLineWidth)
1095
 
{
1096
 
        ASSERT(newLineWidth > 0.0f);
1097
 
        lineWidth=newLineWidth;
1098
 
}
1099
 
 
1100
 
void DrawRectPrism::recomputeParams(const vector<Point3D> &vecs, 
1101
 
                        const vector<float> &scalars, unsigned int mode)
1102
 
{
1103
 
        switch(mode)
1104
 
        {
1105
 
                case DRAW_RECT_BIND_TRANSLATE:
1106
 
                {
1107
 
                        ASSERT(vecs.size() ==1);
1108
 
                        Point3D delta;
1109
 
                        delta = (pMax - pMin)*0.5;
1110
 
                        //Object has been translated
1111
 
                        pMin = vecs[0]-delta;
1112
 
                        pMax = vecs[0]+delta;
1113
 
                        break;
1114
 
                }
1115
 
                case DRAW_RECT_BIND_CORNER_MOVE:
1116
 
                {
1117
 
                        ASSERT(vecs.size() ==1);
1118
 
                        //Delta has changed, but origin shoudl stay the same
1119
 
                        Point3D mean, corner;
1120
 
                        mean  = (pMin + pMax)*0.5;
1121
 
 
1122
 
                        //Prevent negative offset values, otherwise we can
1123
 
                        //get inside out boxes
1124
 
                        corner=vecs[0];
1125
 
                        for(unsigned int ui=0;ui<3;ui++)
1126
 
                                corner[ui]= fabs(corner[ui]);
1127
 
 
1128
 
                        pMin = mean-corner;
1129
 
                        pMax = mean+corner;
1130
 
                        break;
1131
 
                }
1132
 
                default:
1133
 
                        ASSERT(false);
1134
 
        }
1135
 
}
1136
 
 
1137
 
DrawTexturedQuadOverlay::DrawTexturedQuadOverlay()
1138
 
{
1139
 
        texPool=0;
1140
 
}
1141
 
 
1142
 
DrawTexturedQuadOverlay::~DrawTexturedQuadOverlay()
1143
 
{
1144
 
        textureOK=false;
1145
 
}
1146
 
 
1147
 
void DrawTexturedQuadOverlay::setSize(float s)
1148
 
{
1149
 
        length=s;
1150
 
}
1151
 
 
1152
 
 
1153
 
void DrawTexturedQuadOverlay::draw() const
1154
 
{
1155
 
        if(!textureOK)
1156
 
                return;
1157
 
 
1158
 
        ASSERT(glIsTexture(textureId));
1159
 
        
1160
 
        glMatrixMode(GL_PROJECTION);    
1161
 
        glPushMatrix();
1162
 
        glLoadIdentity();
1163
 
        gluOrtho2D(0, winX, winY, 0);
1164
 
 
1165
 
        glMatrixMode(GL_MODELVIEW);
1166
 
        glPushMatrix();
1167
 
        glLoadIdentity();
1168
 
 
1169
 
        glEnable(GL_TEXTURE_2D);
1170
 
        glBindTexture(GL_TEXTURE_2D,textureId);
1171
 
        
1172
 
        // Draw overlay quad 
1173
 
        glColor3f(1.0f,1.0f,1.0f);
1174
 
        glBegin(GL_QUADS);
1175
 
                glTexCoord2f(0.0f,0.0f);
1176
 
                glVertex3f(position[0]-length/2.0,position[1]-length/2.0,0.0);
1177
 
                glTexCoord2f(0.0f,1.0f);
1178
 
                glVertex3f(position[0]-length/2.0,position[1]+length/2.0,0.0);
1179
 
                glTexCoord2f(1.0f,1.0f);
1180
 
                glVertex3f(position[0]+length/2.0,position[1]+length/2.0,0.0);
1181
 
                glTexCoord2f(1.0f,0.0f);
1182
 
                glVertex3f(position[0]+length/2.0,position[1]-length/2.0,0.0);
1183
 
        glEnd();
1184
 
 
1185
 
        glDisable(GL_TEXTURE_2D);       
1186
 
        /* draw stuff */
1187
 
 
1188
 
        glPopMatrix(); //Pop modelview matrix
1189
 
 
1190
 
        glMatrixMode(GL_PROJECTION);
1191
 
        glPopMatrix();
1192
 
 
1193
 
        glMatrixMode(GL_MODELVIEW);
1194
 
}
1195
 
 
1196
 
 
1197
 
bool DrawTexturedQuadOverlay::setTexture(const char *textureFile)
1198
 
{
1199
 
        ASSERT(texPool);        
1200
 
        unsigned int dummy;
1201
 
 
1202
 
        textureOK= texPool->openTexture(textureFile,textureId,dummy);
1203
 
        return textureOK;
1204
 
}
1205
 
 
1206
 
void DrawTexturedQuadOverlay::getBoundingBox(BoundCube &b) const
1207
 
{
1208
 
        b.setInvalid();
1209
 
}
1210
 
 
1211
 
 
1212
 
DrawColourBarOverlay::DrawColourBarOverlay() 
1213
 
{
1214
 
        a=1.0;
1215
 
        string f;
1216
 
        f=getDefaultFontFile();
1217
 
        font = new FTGLPolygonFont(f.c_str());
1218
 
};
1219
 
 
1220
 
 
1221
 
void DrawColourBarOverlay::draw() const
1222
 
{
1223
 
        //Draw quads
1224
 
        float elemHeight;
1225
 
        //80% of bar width is for the actual colour bar itself.
1226
 
        float barWidth=0.8*width;
1227
 
        elemHeight=height/(float)rgb.size();
1228
 
        glBegin(GL_QUADS);
1229
 
        for(unsigned int ui=0;ui<rgb.size();ui++)
1230
 
        {
1231
 
                //Set the quad colour for bar element
1232
 
                glColor4f(rgb[rgb.size()-(ui+1)].v[0],
1233
 
                                rgb[rgb.size()-(ui+1)].v[1],
1234
 
                                rgb[rgb.size()-(ui+1)].v[2],1.0);
1235
 
 
1236
 
                //draw this quad (bar element)
1237
 
                glVertex3f(tlX,tlY+(float)ui*elemHeight,0);
1238
 
                glVertex3f(tlX,tlY+(float)(ui+1)*elemHeight,0);
1239
 
                glVertex3f(tlX+barWidth,tlY+(float)(ui+1)*elemHeight,0);
1240
 
                glVertex3f(tlX+barWidth,tlY+(float)(ui)*elemHeight,0);
1241
 
        }
1242
 
 
1243
 
        glEnd();
1244
 
 
1245
 
        //Draw ticks on colour bar
1246
 
        glBegin(GL_LINES);
1247
 
                glColor4f(1.0,1.0,1.0f,1.0f);
1248
 
                //Top tick
1249
 
                glVertex3f(tlX,tlY,0);
1250
 
                glVertex3f(tlX+width,tlY,0);
1251
 
                //Bottom tick
1252
 
                glVertex3f(tlX,tlY+height,0);
1253
 
                glVertex3f(tlX+width,tlY+height,0);
1254
 
        glEnd();
1255
 
 
1256
 
 
1257
 
 
1258
 
 
1259
 
        if(!font || font->Error())
1260
 
        {
1261
 
#ifdef DEBUG
1262
 
                std::cerr << "Ah bugger. No font!" << std::endl;
1263
 
#endif
1264
 
                return;
1265
 
        }
1266
 
 
1267
 
 
1268
 
 
1269
 
        //FTGL units are a pain; The devs could not decide
1270
 
        //whether to implement them in opengl coords or real coords
1271
 
        //so they did neither, and implemented them in "points".
1272
 
        //here we assume that we can transform 1 ftgl unit
1273
 
        //to 1 opengl unit by inversion 
1274
 
        const float FTGL_DEFAULT_UNIT_SCALE=1.0/72.0;
1275
 
 
1276
 
        glColor3f(1.0f,1.0f,1.0f);      
1277
 
        font->FaceSize(3);
1278
 
        glDisable(GL_CULL_FACE);
1279
 
        glPushMatrix();
1280
 
        glTranslatef(tlX+width,tlY,0);
1281
 
        string s;
1282
 
        stream_cast(s,max);
1283
 
        //Note negative sign to flip from y-down screen (opengl) to text dir
1284
 
        //(y up)
1285
 
        glScaled(FTGL_DEFAULT_UNIT_SCALE,
1286
 
                        -FTGL_DEFAULT_UNIT_SCALE,FTGL_DEFAULT_UNIT_SCALE);
1287
 
        font->Render(s.c_str());
1288
 
        glPopMatrix();
1289
 
 
1290
 
        glPushMatrix();
1291
 
        glTranslatef(tlX+width,tlY+height,0);
1292
 
        stream_cast(s,min);
1293
 
        //Note negative sign to flip from y-down screen (opengl) to text dir
1294
 
        //(y up)
1295
 
        glScaled(FTGL_DEFAULT_UNIT_SCALE,
1296
 
                        -FTGL_DEFAULT_UNIT_SCALE,FTGL_DEFAULT_UNIT_SCALE);
1297
 
        font->Render(s.c_str());
1298
 
        glPopMatrix();
1299
 
        glEnable(GL_CULL_FACE);
1300
 
 
1301
 
 
1302
 
 
1303
 
}
1304
 
 
1305
 
void DrawColourBarOverlay::setColourVec(const vector<float> &r,
1306
 
                                        const vector<float> &g,
1307
 
                                        const vector<float> &b)
1308
 
{
1309
 
        ASSERT(r.size() == g.size());
1310
 
        ASSERT(g.size() == b.size());
1311
 
        rgb.resize(r.size());
1312
 
        for(unsigned int ui=0;ui<r.size();ui++)
1313
 
        {
1314
 
                rgb[ui].v[0]=r[ui];
1315
 
                rgb[ui].v[1]=g[ui];
1316
 
                rgb[ui].v[2]=b[ui];
1317
 
        }
1318
 
 
1319
 
 
1320
 
}
1321
 
 
1322
 
void DrawColourBarOverlay::getBoundingBox(BoundCube &b) const
1323
 
{
1324
 
        b.setInvalid();
1325
 
}
1326
 
 
1327
 
 
1328
 
DrawField3D::DrawField3D() : alphaVal(0.2f), pointSize(1.0f), drawBoundBox(true),volumeGrid(false), volumeRenderMode(0), field(0) 
1329
 
{
1330
 
        boxColourR = boxColourG = boxColourB = boxColourA = 1.0f;
1331
 
        ptsCacheOK=false;
1332
 
}
1333
 
 
1334
 
DrawField3D::~DrawField3D()
1335
 
{
1336
 
        if(field)
1337
 
                delete field;
1338
 
}
1339
 
 
1340
 
 
1341
 
void DrawField3D::getBoundingBox(BoundCube &b) const
1342
 
{
1343
 
        ASSERT(field)
1344
 
        b.setBounds(field->getMinBounds(),field->getMaxBounds());
1345
 
}
1346
 
 
1347
 
 
1348
 
void DrawField3D::setField(const Voxels<float> *newField)
1349
 
{
1350
 
        field=newField;
1351
 
}
1352
 
 
1353
 
void DrawField3D::setRenderMode(unsigned int mode)
1354
 
{
1355
 
        volumeRenderMode=mode;
1356
 
}
1357
 
 
1358
 
void DrawField3D::setColourMinMax()
1359
 
{
1360
 
        colourMapBound[0]=field->min();
1361
 
        colourMapBound[1]=field->max();
1362
 
 
1363
 
        ASSERT(colourMapBound[0] <=colourMapBound[1]);
1364
 
}
1365
 
 
1366
 
                        
1367
 
void DrawField3D::draw() const
1368
 
{
1369
 
        if(alphaVal < sqrt(std::numeric_limits<float>::epsilon()))
1370
 
                return;
1371
 
 
1372
 
        ASSERT(field);
1373
 
 
1374
 
        //Depend upon the render mode
1375
 
        switch(volumeRenderMode)
1376
 
        {
1377
 
                case VOLUME_POINTS:
1378
 
                {
1379
 
                        size_t fieldSizeX,fieldSizeY,fieldSizeZ;
1380
 
                        Point3D p;
1381
 
 
1382
 
                        field->getSize(fieldSizeX,fieldSizeY, fieldSizeZ);
1383
 
 
1384
 
                        Point3D delta;
1385
 
                        delta = field->getPitch();
1386
 
                        delta*=0.5;
1387
 
                        if(!ptsCacheOK)
1388
 
                        {
1389
 
                                ptsCache.clear();
1390
 
                                for(unsigned int uiX=0; uiX<fieldSizeX; uiX++)
1391
 
                                {
1392
 
                                        for(unsigned int uiY=0; uiY<fieldSizeY; uiY++)
1393
 
                                        {
1394
 
                                                for(unsigned int uiZ=0; uiZ<fieldSizeZ; uiZ++)
1395
 
                                                {
1396
 
                                                        float v;
1397
 
                                                        v=field->getData(uiX,uiY,uiZ);
1398
 
                                                        if(v > std::numeric_limits<float>::epsilon())
1399
 
                                                        {
1400
 
                                                                RGBThis rgb;
1401
 
                                                                //Set colour and point loc
1402
 
                                                                colourMapWrap(colourMapID,rgb.v,
1403
 
                                                                                field->getData(uiX,uiY,uiZ), 
1404
 
                                                                                colourMapBound[0],colourMapBound[1]);
1405
 
                                                                
1406
 
                                                                ptsCache.push_back(make_pair(field->getPoint(uiX,uiY,uiZ)+delta,rgb));
1407
 
                                                        }
1408
 
                                                }
1409
 
                                        }
1410
 
                                }
1411
 
                                        
1412
 
 
1413
 
                                ptsCacheOK=true;
1414
 
                        }
1415
 
 
1416
 
                        if(alphaVal < 1.0f)
1417
 
                        {
1418
 
                                //We need to generate some points, then sort them by distance
1419
 
                                //from eye (back to front), otherwise they will not blend properly
1420
 
                                std::vector<std::pair<float,unsigned int >  > eyeDists;
1421
 
 
1422
 
                                Point3D camOrigin = curCamera->getOrigin();
1423
 
 
1424
 
                                eyeDists.resize(ptsCache.size());
1425
 
                                
1426
 
                                //Set up an original index for the eye distances
1427
 
                                #pragma omp parallel for
1428
 
                                for(unsigned int ui=0;ui<ptsCache.size();ui++)
1429
 
                                {
1430
 
                                        eyeDists[ui].first=ptsCache[ui].first.sqrDist(camOrigin);
1431
 
                                        eyeDists[ui].second=ui;
1432
 
                                }
1433
 
 
1434
 
                                ComparePairFirstReverse cmp;
1435
 
                                std::sort(eyeDists.begin(),eyeDists.end(),cmp); 
1436
 
 
1437
 
                                //render each element in the field as a point
1438
 
                                //the colour of the point is determined by its scalar value
1439
 
                                glDepthMask(GL_FALSE);
1440
 
                                glPointSize(pointSize);
1441
 
                                glBegin(GL_POINTS);
1442
 
                                for(unsigned int ui=0;ui<ptsCache.size();ui++)
1443
 
                                {
1444
 
                                        unsigned int idx;
1445
 
                                        idx=eyeDists[ui].second;
1446
 
                                        //Tell openGL about it
1447
 
                                        glColor4f(((float)(ptsCache[idx].second.v[0]))/255.0f, 
1448
 
                                                        ((float)(ptsCache[idx].second.v[1]))/255.0f,
1449
 
                                                        ((float)(ptsCache[idx].second.v[2]))/255.0f, 
1450
 
                                                        alphaVal);
1451
 
                                        glVertex3f(ptsCache[idx].first[0],ptsCache[idx].first[1],ptsCache[idx].first[2]);
1452
 
                                }
1453
 
                                glEnd();
1454
 
                                glDepthMask(GL_TRUE);
1455
 
                        }
1456
 
                        else
1457
 
                        {
1458
 
                                for(unsigned int ui=0;ui<ptsCache.size();ui++)
1459
 
                                {
1460
 
                                        //Tell openGL about it
1461
 
                                        glColor4f(((float)(ptsCache[ui].second.v[0]))/255.0f, 
1462
 
                                                        ((float)(ptsCache[ui].second.v[1]))/255.0f,
1463
 
                                                        ((float)(ptsCache[ui].second.v[2]))/255.0f, 
1464
 
                                                        1.0f);
1465
 
                                        glVertex3f(ptsCache[ui].first[0],ptsCache[ui].first[1],ptsCache[ui].first[2]);
1466
 
                                }
1467
 
                        }
1468
 
                        break;
1469
 
                }
1470
 
 
1471
 
                default:
1472
 
                        //Not implemented
1473
 
                        ASSERT(false); 
1474
 
        }
1475
 
 
1476
 
        //Draw the bounding box as required
1477
 
        if(drawBoundBox)
1478
 
        {
1479
 
                drawBox(field->getMinBounds(),field->getMaxBounds(),
1480
 
                        boxColourR, boxColourG,boxColourB,boxColourA);
1481
 
        }
1482
 
        //Draw the projections
1483
 
}
1484
 
 
1485
 
void DrawField3D::setAlpha(float newAlpha)
1486
 
{
1487
 
        alphaVal=newAlpha;
1488
 
}
1489
 
 
1490
 
void DrawField3D::setPointSize(float size)
1491
 
{
1492
 
        pointSize=size;
1493
 
}
1494
 
 
1495
 
void DrawField3D::setMapColours(unsigned int mapID)
1496
 
{
1497
 
        ASSERT(mapID < NUM_COLOURMAPS);
1498
 
        colourMapID= mapID;
1499
 
}
1500
 
 
1501
 
void DrawField3D::setBoxColours(float rNew, float gNew, float bNew, float aNew)
1502
 
{
1503
 
        boxColourR = rNew;
1504
 
        boxColourG = gNew;
1505
 
        boxColourB = bNew;
1506
 
        boxColourA = aNew;
1507
 
 
1508
 
}
1509
 
 
1510
 
 
1511
 
DrawIsoSurface::DrawIsoSurface()
1512
 
{
1513
 
        cacheOK=false;
1514
 
        drawMode=DRAW_SMOOTH;
1515
 
        threshold=0.5;
1516
 
        voxels=0;
1517
 
        
1518
 
        r=0.5;
1519
 
        g=0.5;
1520
 
        b=0.5;
1521
 
        a=1.0;  
1522
 
}
1523
 
 
1524
 
DrawIsoSurface::~DrawIsoSurface()
1525
 
{
1526
 
        if(voxels)
1527
 
                delete voxels;
1528
 
}
1529
 
 
1530
 
 
1531
 
bool DrawIsoSurface::needsDepthSorting()  const
1532
 
{
1533
 
        return a< 1 && a > std::numeric_limits<float>::epsilon();
1534
 
}
1535
 
 
1536
 
void DrawIsoSurface::swapVoxels(Voxels<float> *f)
1537
 
{
1538
 
        std::swap(f,voxels);
1539
 
        cacheOK=false;
1540
 
        mesh.clear();
1541
 
}
1542
 
 
1543
 
 
1544
 
void DrawIsoSurface::updateMesh() const
1545
 
{
1546
 
 
1547
 
        mesh.clear();
1548
 
        marchingCubes(*voxels, threshold,mesh);
1549
 
 
1550
 
        cacheOK=true;
1551
 
 
1552
 
}
1553
 
 
1554
 
void DrawIsoSurface::getBoundingBox(BoundCube &b) const
1555
 
{
1556
 
        if(voxels)
1557
 
        {
1558
 
                b.setBounds(voxels->getMinBounds(),
1559
 
                                voxels->getMaxBounds());
1560
 
        }
1561
 
        else
1562
 
                b.setInverseLimits();
1563
 
}
1564
 
 
1565
 
 
1566
 
void DrawIsoSurface::draw() const
1567
 
{
1568
 
        if(a< sqrt(std::numeric_limits<float>::epsilon()))
1569
 
                return;
1570
 
 
1571
 
        if(!cacheOK)
1572
 
        {
1573
 
                //Hmm, we don't have a cached copy of the isosurface mesh.
1574
 
                //we will need to compute one, it would seem.
1575
 
                updateMesh();
1576
 
        }
1577
 
 
1578
 
 
1579
 
        //This could be optimised by using triangle strips
1580
 
        //rather than direct triangles.
1581
 
        if(a < 1.0f)
1582
 
        {
1583
 
                //We need to sort them by distance
1584
 
                //from eye (back to front), otherwise they will not blend properly
1585
 
                std::vector<std::pair<float,unsigned int >  > eyeDists;
1586
 
 
1587
 
                Point3D camOrigin = curCamera->getOrigin();
1588
 
                eyeDists.resize(mesh.size());
1589
 
                
1590
 
                //Set up an original index for the eye distances
1591
 
                #pragma omp parallel for shared(camOrigin)
1592
 
                for(unsigned int ui=0;ui<mesh.size();ui++)
1593
 
                {
1594
 
                        Point3D centroid;
1595
 
                        mesh[ui].getCentroid(centroid);
1596
 
 
1597
 
                        eyeDists[ui].first=centroid.sqrDist(camOrigin);
1598
 
                        eyeDists[ui].second=ui;
1599
 
                }
1600
 
 
1601
 
                ComparePairFirstReverse cmp;
1602
 
                std::sort(eyeDists.begin(),eyeDists.end(),cmp); 
1603
 
                                        
1604
 
 
1605
 
                glDepthMask(GL_FALSE);
1606
 
                glColor4f(r,g,b,a);
1607
 
                glPushAttrib(GL_CULL_FACE);
1608
 
                glDisable(GL_CULL_FACE);
1609
 
 
1610
 
                glBegin(GL_TRIANGLES);  
1611
 
                for(unsigned int ui=0;ui<mesh.size();ui++)
1612
 
                {
1613
 
                        unsigned int idx;
1614
 
                        idx=eyeDists[ui].second;
1615
 
                        glNormal3fv(mesh[idx].normal[0].getValueArr());
1616
 
                        glVertex3fv(mesh[idx].p[0].getValueArr());
1617
 
                        glNormal3fv(mesh[idx].normal[1].getValueArr());
1618
 
                        glVertex3fv(mesh[idx].p[1].getValueArr()),
1619
 
                        glNormal3fv(mesh[idx].normal[2].getValueArr());
1620
 
                        glVertex3fv(mesh[idx].p[2].getValueArr());
1621
 
                }
1622
 
                glEnd();
1623
 
 
1624
 
 
1625
 
                glPopAttrib();
1626
 
                glDepthMask(GL_TRUE);
1627
 
 
1628
 
        }
1629
 
        else
1630
 
        {
1631
 
                glColor4f(r,g,b,a);
1632
 
                glPushAttrib(GL_CULL_FACE);
1633
 
                glDisable(GL_CULL_FACE);        
1634
 
                glBegin(GL_TRIANGLES);  
1635
 
                for(unsigned int ui=0;ui<mesh.size();ui++)
1636
 
                {
1637
 
                        glNormal3fv(mesh[ui].normal[0].getValueArr());
1638
 
                        glVertex3fv(mesh[ui].p[0].getValueArr());
1639
 
                        glNormal3fv(mesh[ui].normal[1].getValueArr());
1640
 
                        glVertex3fv(mesh[ui].p[1].getValueArr()),
1641
 
                        glNormal3fv(mesh[ui].normal[2].getValueArr());
1642
 
                        glVertex3fv(mesh[ui].p[2].getValueArr());
1643
 
                }
1644
 
                glEnd();
1645
 
                glPopAttrib();
1646
 
        }
1647
 
}
1648
 
 
1649
 
 
1650
 
 
1651
 
DrawAxis::DrawAxis()
1652
 
{
1653
 
}
1654
 
 
1655
 
DrawAxis::~DrawAxis()
1656
 
{
1657
 
}
1658
 
 
1659
 
void DrawAxis::setStyle(unsigned int s)
1660
 
{
1661
 
        style=s;
1662
 
}
1663
 
 
1664
 
void DrawAxis::setSize(float s)
1665
 
{
1666
 
        size=s;
1667
 
}
1668
 
 
1669
 
void DrawAxis::setPosition(const Point3D &p)
1670
 
{
1671
 
        position=p;
1672
 
}
1673
 
 
1674
 
void DrawAxis::draw() const
1675
 
 
1676
 
{
1677
 
        float halfSize=size/2.0f;
1678
 
        glPushAttrib(GL_LIGHTING_BIT);
1679
 
        glDisable(GL_LIGHTING);
1680
 
        glBegin(GL_LINES);
1681
 
        //Draw lines
1682
 
        glColor3f(1.0f,0.0f,0.0f);
1683
 
        glVertex3f(position[0]-halfSize,
1684
 
                   position[1],position[2]);
1685
 
        glVertex3f(position[0]+halfSize,
1686
 
                   position[1],position[2]);
1687
 
 
1688
 
        glColor3f(0.0f,1.0f,0.0f);
1689
 
        glVertex3f(position[0],
1690
 
                   position[1]-halfSize,position[2]);
1691
 
        glVertex3f(position[0],
1692
 
                   position[1]+halfSize,position[2]);
1693
 
 
1694
 
        glColor3f(0.0f,0.0f,1.0f);
1695
 
        glVertex3f(position[0],
1696
 
                   position[1],position[2]-halfSize);
1697
 
        glVertex3f(position[0],
1698
 
                   position[1],position[2]+halfSize);
1699
 
        glEnd();
1700
 
        glPopAttrib();
1701
 
 
1702
 
 
1703
 
 
1704
 
        float numSections=20.0f;
1705
 
        float twoPi = 2.0f *M_PI;
1706
 
        float radius = 0.1*halfSize;
1707
 
        //Draw axis cones
1708
 
 
1709
 
        //+x
1710
 
        glPushMatrix();
1711
 
        glTranslatef(position[0]+halfSize,position[1],position[2]);
1712
 
 
1713
 
        glColor3f(1.0f,0.0f,0.0f);
1714
 
        glBegin(GL_TRIANGLE_FAN);
1715
 
        glVertex3f(radius,0,0);
1716
 
        glNormal3f(1,0,0);
1717
 
        for (unsigned int i = 0; i<=numSections; i++)
1718
 
        {
1719
 
                glVertex3f(0,radius * cos(i *  twoPi / numSections),
1720
 
                           radius* sin(i * twoPi / numSections));
1721
 
                glNormal3f(0,cos(i*twoPi/numSections),sin(i*twoPi/numSections));
1722
 
        }
1723
 
        glEnd();
1724
 
        glBegin(GL_TRIANGLE_FAN);
1725
 
        glVertex3f(0,0,0);
1726
 
        glNormal3f(-1,0,0);
1727
 
        for (unsigned int i = 0; i<=numSections; i++)
1728
 
        {
1729
 
                glVertex3f(0,-radius * cos(i *  twoPi / numSections),
1730
 
                           radius* sin(i * twoPi / numSections));
1731
 
                glNormal3f(-1,0,0);
1732
 
        }
1733
 
        glEnd();
1734
 
        glPopMatrix();
1735
 
 
1736
 
        //+y
1737
 
        glColor3f(0.0f,1.0f,0.0f);
1738
 
        glPushMatrix();
1739
 
        glTranslatef(position[0],position[1]+halfSize,position[2]);
1740
 
        glBegin(GL_TRIANGLE_FAN);
1741
 
        glVertex3f(0,radius,0);
1742
 
        glNormal3f(0,1,0);
1743
 
        for (unsigned int i = 0; i<=numSections; i++)
1744
 
        {
1745
 
                glVertex3f(radius * sin(i *  twoPi / numSections),0,
1746
 
                           radius* cos(i * twoPi / numSections));
1747
 
                glNormal3f(sin(i*twoPi/numSections),0,cos(i*twoPi/numSections));
1748
 
        }
1749
 
        glEnd();
1750
 
 
1751
 
        glBegin(GL_TRIANGLE_FAN);
1752
 
        glVertex3f(0,0,0);
1753
 
        glNormal3f(0,-1,0);
1754
 
        for (unsigned int i = 0; i<=numSections; i++)
1755
 
        {
1756
 
                glVertex3f(radius * cos(i *  twoPi / numSections),0,
1757
 
                           radius* sin(i * twoPi / numSections));
1758
 
                glNormal3f(0,-1,0);
1759
 
        }
1760
 
        glEnd();
1761
 
 
1762
 
        glPopMatrix();
1763
 
 
1764
 
 
1765
 
 
1766
 
        //+z
1767
 
        glColor3f(0.0f,0.0f,1.0f);
1768
 
        glPushMatrix();
1769
 
        glTranslatef(position[0],position[1],position[2]+halfSize);
1770
 
        glBegin(GL_TRIANGLE_FAN);
1771
 
        glVertex3f(0,0,radius);
1772
 
        glNormal3f(0,0,1);
1773
 
        for (unsigned int i = 0; i<=numSections; i++)
1774
 
        {
1775
 
                glVertex3f(radius * cos(i *  twoPi / numSections),
1776
 
                           radius* sin(i * twoPi / numSections),0);
1777
 
                glNormal3f(cos(i*twoPi/numSections),sin(i*twoPi/numSections),0);
1778
 
        }
1779
 
        glEnd();
1780
 
 
1781
 
        glBegin(GL_TRIANGLE_FAN);
1782
 
        glVertex3f(0,0,0);
1783
 
        glNormal3f(0,0,-1);
1784
 
        for (unsigned int i = 0; i<=numSections; i++)
1785
 
        {
1786
 
                glVertex3f(-radius * cos(i *  twoPi / numSections),
1787
 
                           radius* sin(i * twoPi / numSections),0);
1788
 
                glNormal3f(0,0,-1);
1789
 
        }
1790
 
        glEnd();
1791
 
        glPopMatrix();
1792
 
}
1793
 
 
1794
 
void DrawAxis::getBoundingBox(BoundCube &b) const
1795
 
{
1796
 
        b.setInvalid();
1797
 
}
1798
 
 
1799
 
 
1800
 
void DrawDepthSorted::draw()  const
1801
 
{
1802
 
        bool needResort;
1803
 
        //Check to see if we need to re-sort the data
1804
 
        needResort=(!haveLastDist ||
1805
 
                        lastCamLoc.sqrDist(curCamera->getOrigin()) >DEPTH_SORT_REORDER_EPSILON);
1806
 
 
1807
 
        if(needResort)
1808
 
        {
1809
 
                //Rebuild the depthJump key data
1810
 
                std::vector<pair<std::pair<size_t,size_t> , float> > dists;
1811
 
 
1812
 
                size_t size;
1813
 
                size=0;
1814
 
                for(size_t ui=0;ui<depthObjects.size(); ui++)
1815
 
                        size+=dists.size();
1816
 
 
1817
 
                dists.resize(size);
1818
 
                depthJumpKeys.resize(size);
1819
 
 
1820
 
                //Generate the to-camera distances (negative because we want
1821
 
                //further away objects to be first)
1822
 
                #pragma omp parallel for
1823
 
                for(size_t ui=0;ui<depthObjects.size(); ui++)
1824
 
                {
1825
 
                        Point3D centroid;
1826
 
                        for(size_t uj=0; uj<depthObjects[ui].second.size(); uj++)
1827
 
                        {
1828
 
                                centroid=depthObjects[ui].second[uj]->getCentroid();
1829
 
                                dists[ui+uj]=std::make_pair(std::make_pair(ui,uj),-centroid.sqrDist(curCamera->getOrigin()));
1830
 
                        }
1831
 
                }
1832
 
 
1833
 
                //Now we have the distance data, sort it
1834
 
                ComparePairSecond cmp;
1835
 
                std::sort(dists.begin(),dists.end(),cmp);       
1836
 
 
1837
 
                //Now set the depth Jump Keys using the sorted distances
1838
 
                #pragma omp parallel for
1839
 
                for(size_t ui=0;ui<dists.size();ui++)
1840
 
                        depthJumpKeys[ui]=dists[ui].first;
1841
 
 
1842
 
                lastCamLoc=curCamera->getOrigin();
1843
 
        }
1844
 
 
1845
 
 
1846
 
        //OK, so we have to now draw our objects from back->front order
1847
 
        //as set by depthJumpKeys
1848
 
        for(size_t ui=0;ui<depthObjects.size();ui++)
1849
 
        {
1850
 
                const DrawableObj *d;
1851
 
                d=(depthObjects[depthJumpKeys[ui].first].second[depthJumpKeys[ui].second]);
1852
 
                d->draw();
1853
 
        }
1854
 
}
1855
 
 
1856
 
 
1857
 
void DrawDepthSorted::addObjectsAsNeeded(const DrawableObj *obj) 
1858
 
{
1859
 
        size_t off=std::numeric_limits<size_t>::max();
1860
 
        for(size_t ui=0;ui<depthObjects.size();ui++)
1861
 
        {
1862
 
                if(depthObjects[ui].first == obj)
1863
 
                {
1864
 
                        if(depthObjects[ui].first->hasChanged())
1865
 
                                off=ui;
1866
 
                        else 
1867
 
                                off=depthObjects.size();
1868
 
                        
1869
 
                        break;
1870
 
                }
1871
 
        }
1872
 
 
1873
 
 
1874
 
        if(off==depthObjects.size())
1875
 
                return; // Object exists and is up to date.
1876
 
        else if(off==std::numeric_limits<size_t>::max())
1877
 
        {
1878
 
                //Ok, so we have no object, and we need
1879
 
                //to create a new set of data
1880
 
        
1881
 
        }
1882
 
        else
1883
 
        {
1884
 
                ASSERT(off < depthObjects.size());
1885
 
                //we need to update the object
1886
 
        }
1887
 
 
1888
 
 
1889
 
}
1890
 
 
1891
 
 
1892