source: GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlRenderer.cpp @ 2669

Revision 2669, 61.9 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "glInterface.h"
2#include "QtGlRenderer.h"
3#include "Mesh.h"
4#include "OcclusionQuery.h"
5#include "ViewCellsManager.h"
6#include "SceneGraph.h"
7#include "Pvs.h"
8#include "Viewcell.h"
9#include "Beam.h"
10#include "KdTree.h"
11#include "Environment.h"
12#include "RssPreprocessor.h"
13#include "RssTree.h"
14#include "Trackball.h"
15#include "QtPreprocessorThread.h"
16#include "Material.h"
17#include "IntersectableWrapper.h"
18#include "LogWriter.h"
19#include "RayCaster.h"
20
21
22#define USE_CG 1
23
24#define TEST_PVS_RENDERING 0
25
26#if USE_CG
27#include <Cg/cg.h>
28#include <Cg/cgGL.h>
29#endif
30
31#include <QVBoxLayout>
32
33namespace GtpVisibilityPreprocessor
34{
35
36 
37class ViewCellsManager;
38
39static CGcontext sCgContext = NULL;
40static CGprogram sCgFragmentProgram = NULL;
41static CGprofile sCgFragmentProfile;
42
43
44QtGlRendererWidget *rendererWidget = NULL;
45QtGlDebuggerWidget *debuggerWidget = NULL;
46
47const static int SAMPLES_INCR = 2000000;
48
49
50
51static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
52{
53        return obj1->mId < obj2->mId;
54}
55
56
57inline static bool nearerThan(ViewCell *vc1, ViewCell *vc2)
58{
59        return vc1->GetDistance() > vc2->GetDistance();
60}
61
62
63#if USE_CG
64static void handleCgError()
65{
66    Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl;
67    exit(1);
68}
69#endif
70
71void
72QtGlRendererBuffer::MakeCurrent()
73{
74        makeCurrent();
75}
76
77void
78QtGlRendererBuffer::DoneCurrent()
79{
80        doneCurrent();
81}
82 
83
84QtGlRendererBuffer::QtGlRendererBuffer(int w, int h,
85                                                                           SceneGraph *sceneGraph,
86                                                                           ViewCellsManager *viewcells,
87                                                                           KdTree *tree):
88QGLPixelBuffer(QSize(w, h),
89                           QGLFormat(QGL::StencilBuffer |
90                                                 QGL::DepthBuffer |
91                                                 QGL::DoubleBuffer |
92                                                 QGL::Rgba
93                                                 )),
94GlRendererBuffer(sceneGraph, viewcells, tree)
95{
96        mUseVbos = true;
97        //mUseVbos = false;
98       
99        MakeCurrent();
100        glViewport(0, 0, w, h);
101    glMatrixMode(GL_PROJECTION);
102    glLoadIdentity();
103    glOrtho(-1, 1, -1, 1, -99, 99);
104    //glTranslatef(-0.5f, -0.5f, 0.0f);
105    glMatrixMode(GL_MODELVIEW);
106    glLoadIdentity();
107
108        InitGL();
109        DoneCurrent();
110}
111
112
113void QtGlRendererBuffer::RenderPvs(const ObjectPvs &pvs)
114{
115        PreparePvs(pvs);
116
117        int offset = (int)mObjects.size() * 3;
118        char *arrayPtr = mUseVbos ? NULL : (char *)mData;
119
120        glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr);
121        glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3));
122        glDrawElements(GL_TRIANGLES, mIndexBufferSize, GL_UNSIGNED_INT, mIndices);
123}
124
125// reimplemented here so that we can snap the error windows
126float QtGlRendererBuffer::GetPixelError(int &pvsSize)
127{
128        MakeCurrent();
129       
130        cout << "stencil: " << format().stencil() << endl;
131        cout << "depth: " << format().depth() << endl;
132        cout << "rgba: " << format().rgba() << endl;
133        cout << "double: " << format().doubleBuffer() << endl;
134
135        float pErrorPixels = -1.0f;
136
137        mUseFalseColors = false;
138        unsigned int pixelCount = 0;
139
140       
141        ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
142
143        if (viewcell == NULL)
144                return -1.0f;
145
146        KdNode::NewMail2();
147        Intersectable::NewMail();
148
149        ObjectPvs pvs;
150
151        bool evaluateFilter;
152        Environment::GetSingleton()->GetBoolValue("Preprocessor.evaluateFilter", evaluateFilter);
153
154        if (!evaluateFilter)
155                pvs = viewcell->GetPvs();
156        else
157                mViewCellsManager->ApplyFilter2(viewcell, false, mViewCellsManager->GetFilterWidth(), pvs);
158
159        pvsSize = pvs.GetSize();
160       
161        if (pvsSize == 0)
162                return 0.0f;
163
164        mUseForcedColors = true;
165
166        SetupCamera();
167
168        // use shading
169        if (mSnapErrorFrames)
170        {
171
172                GLfloat light_ambient[] = {0.3, 0.3, 0.3, 1.0};
173                GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0};
174                GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
175
176                GLfloat light_position[] =  //{278.0f, 548.8f,279.0f, 1.0f};
177                {0.f,0.f,0.f, 1.0f};
178
179                glEnable(GL_LIGHT0);
180
181                // a light
182                glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
183                glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
184                glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
185
186                glEnable(GL_LIGHTING);
187                glLightfv (GL_LIGHT0, GL_POSITION, light_position);
188
189                glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
190                glEnable(GL_COLOR_MATERIAL);
191
192                glShadeModel(GL_SMOOTH);
193        }
194
195        glDisable(GL_ALPHA_TEST);
196               
197        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
198        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
199
200        //glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
201        glColor3f(0, 1, 0);
202
203        glDepthFunc(GL_LESS);
204        glDepthMask(GL_TRUE);
205        glEnable(GL_DEPTH_TEST);
206
207        glStencilFunc(GL_EQUAL, 0x0, 0x1);
208        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
209
210       
211        // render pvs once
212        RenderPvs(pvs);
213
214        //glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
215        //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
216        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
217
218        glEnable(GL_STENCIL_TEST);
219        glColor3f(1,0,0);
220
221
222        // render scene, record differences
223        OcclusionQuery *query = mOcclusionQueries[0];
224
225        KdNode::NewMail2();
226        Intersectable::NewMail();
227
228        query->BeginQuery();
229
230        RenderScene();
231
232        query->EndQuery();
233        glDisable(GL_STENCIL_TEST);
234
235
236        // reenable other state
237        int wait = 0;
238        while (0 && !query->ResultAvailable())
239                wait ++;
240       
241        pixelCount = query->GetQueryResult();
242
243        if (pixelCount > 0)
244        {
245                cout << "vc id: " << viewcell->GetId() << " pvs: " << pvsSize << " pc: " << pixelCount << endl;
246        }
247
248        pErrorPixels = ((float)pixelCount) / (GetWidth() * GetHeight());
249
250
251        if (mSnapErrorFrames && (pixelCount > 0))
252        {
253                glReadBuffer(GL_BACK);
254                //glReadBuffer(GL_FRONT);
255
256                char filename[256];
257                sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels);
258                QImage im = toImage();
259                string str = mSnapPrefix + filename;
260                QString qstr(str.c_str());
261
262                im.save(qstr, "PNG");
263                if (0) { //0 && mFrame == 1543) {
264                        int x,y;
265                        int lastIndex = -1;
266                        for (y=0; y < im.height(); y++)
267                                for (x=0; x < im.width(); x++) {
268                                        QRgb p = im.pixel(x,y);
269                                        int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16);
270                                        if (qGreen(p) != 255 && index!=0) {
271                                                if (index != lastIndex) {
272                                                        //                              Debug<<"ei="<<index<<" ";
273                                                        lastIndex = index;
274                                                }
275                                        }
276                                }
277                }
278               
279
280#if 0
281                mUseFalseColors = false;
282
283                glPushAttrib(GL_CURRENT_BIT);
284                glColor3f(0, 1, 0);
285               
286                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
287                //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
288                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
289
290                KdNode::NewMail2();
291                Intersectable::NewMail();
292
293                RenderPvs(pvs);
294
295                glFinish();
296
297                mUseForcedColors = false;
298
299                im = toImage();
300                sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels);
301                str = mSnapPrefix + filename;
302                qstr = str.c_str();
303                im.save(qstr, "PNG");
304               
305                glPopAttrib();
306#endif
307        }
308
309        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
310
311        DoneCurrent();
312
313        return pErrorPixels;
314}
315
316int
317QtGlRendererBuffer::ComputePvs(ObjectContainer &objects,
318                                                           ObjectContainer &pvs) const
319{
320        int pvsSize = 0;
321        QImage image = toImage();
322        Intersectable::NewMail();
323
324        std::stable_sort(objects.begin(), objects.end(), ilt);
325
326        MeshInstance dummy(NULL);
327
328        Intersectable *obj = NULL;
329
330        for (int x = 0; x < image.width(); ++ x)
331        {
332                for (int y = 0; y < image.height(); ++ y)
333                {
334                        QRgb pix = image.pixel(x, y);
335                        const int id = GetId(qRed(pix), qGreen(pix), qBlue(pix));
336
337                        dummy.SetId(id);
338
339                        ObjectContainer::iterator oit =
340                                lower_bound(objects.begin(), objects.end(), &dummy, ilt);
341
342
343                        if (//(oit != oit.end()) &&
344                                ((*oit)->GetId() == id) &&
345                                !obj->Mailed())
346                        {
347                                obj = *oit;
348                                obj->Mail();
349                                ++ pvsSize;
350                                pvs.push_back(obj);
351                        }
352                }
353        }
354
355        return pvsSize;
356}
357
358
359void QtGlRendererWidget::InitGL()
360{
361        GlRenderer::InitGL();
362
363        //glEnable(GL_FOG);
364        //glFogi(GL_FOG_MODE, GL_EXP);
365        glFogi(GL_FOG_MODE, GL_LINEAR);
366
367//      glFogf(GL_FOG_DENSITY, .2f);
368        glFogf(GL_FOG_START, 50.f);
369        glFogf(GL_FOG_END, 500.f);
370
371        GLfloat light_ambient[] = {0.3, 0.3, 0.3, 1.0};
372    GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0};
373    GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
374    GLfloat light_position[] =  //{278.0f, 548.8f,279.0f, 1.0f };
375    { 0.f,0.f,0.f,1.0f };
376
377    /*glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
378    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
379    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
380    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
381*/
382    glEnable(GL_LIGHT0);
383
384        GLfloat mat_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
385       
386        // mat_specular and mat_shininess are NOT default values
387        GLfloat mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
388        GLfloat mat_specular[] = {0.3f, 0.3f, 0.3f, 1.0f};
389        GLfloat mat_shininess[] = {1.0f};
390
391/*      GLfloat light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
392        GLfloat light_diffuse[] = {0.4f, 0.4f, 0.4f, 1.0f};
393        GLfloat light_specular[] = {0.3f, 0.3f, 0.3f, 1.0f};
394
395        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
396*/
397
398        // default Material
399        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
400        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
401        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
402        glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
403
404        // a light
405        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
406        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
407        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
408
409        /*glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
410        glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
411        glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
412*/
413        //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
414
415        glEnable(GL_LIGHTING);
416        glEnable(GL_LIGHT0);
417//      glEnable(GL_LIGHT1);
418
419        // set position of the light
420        /*GLfloat infinite_light[] = {  1.0, 0.8, 1.0, 0.0  };
421        glLightfv (GL_LIGHT0, GL_POSITION, infinite_light);
422
423        // set position of the light2
424        GLfloat infinite_light2[] = {  -0.3, 1.5, 1.0, 0.0  };
425        glLightfv (GL_LIGHT1, GL_POSITION, infinite_light2);
426*/
427        glLightfv (GL_LIGHT0, GL_POSITION, light_position);
428
429        glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
430        // glColorMaterial( GL_FRONT_AND_BACK, GL_SPECULAR);
431        glEnable(GL_COLOR_MATERIAL);
432
433        glShadeModel(GL_SMOOTH);
434}
435
436
437void
438QtGlRendererWidget::SetupCameraProjection(const int w, const int h, const float angle)
439{
440        if (!mTopView) {
441                int ww = w;
442                int hh = h;
443                glViewport(0, 0, ww, hh);
444                glMatrixMode(GL_PROJECTION);
445                glLoadIdentity();
446                gluPerspective(angle, ww/(float)hh, 0.1, 2.0 * Magnitude(mSceneGraph->GetBox().Diagonal()));
447                glMatrixMode(GL_MODELVIEW);
448        } else {
449                int ww = w;
450                int hh = h;
451                glViewport(0, 0, ww, hh);
452                glMatrixMode(GL_PROJECTION);
453                glLoadIdentity();
454                gluPerspective(50.0, ww / (float)hh, 0.1, 20.0 * Magnitude(mSceneGraph->GetBox().Diagonal()));
455                glMatrixMode(GL_MODELVIEW);
456        }
457}
458
459
460bool QtGlRendererWidget::PvsChanged(ViewCell *viewCell) const
461{
462        if (viewCell != mPvsCache.mViewCell)
463                return true;
464
465        if (viewCell->GetPvs().GetSize() != mPvsCache.mUnfilteredPvsSize)
466                return true;
467
468        return false;
469}
470
471
472void QtGlRendererWidget::_RenderPvs()
473{
474        mUseFalseColors = false;
475
476        int offset = (int)mObjects.size() * 3;
477        char *arrayPtr = mUseVbos ? NULL : (char *)mData;
478
479        glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr);
480        glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3));
481        glDrawElements(GL_TRIANGLES, mIndexBufferSize, GL_UNSIGNED_INT, mIndices);
482
483#if DYNAMIC_OBJECTS_HACK
484        // handle dynamic objects
485        DynamicObjectsContainer::const_iterator dit, dit_end = mDynamicObjects.end();
486
487        for (dit = mDynamicObjects.begin(); dit != dit_end; ++ dit)
488        {
489#if USE_TRANSFORMED_MESH_INSTANCE_HACK
490                RenderIntersectable(*dit);
491#else
492                _RenderDynamicObject(*dit);
493#endif
494        }
495#endif
496}
497
498
499void QtGlRendererWidget::PreparePvs2(const ObjectPvs &pvs)
500{
501        int indexBufferSize = 0;
502       
503        // super hack: mal not working with multiple threads
504        KdNode::NewMail2();
505        //Intersectable::NewMail();
506
507        mPvsSize = pvs.GetSize();
508
509#if DYNAMIC_OBJECTS_HACK
510        mDynamicObjects.clear();
511#endif
512
513        ObjectPvsIterator it = pvs.GetIterator();
514
515        while (it.HasMoreEntries())
516        {
517                Intersectable *obj = it.Next();
518                switch (obj->Type())
519                {
520                case Intersectable::KD_INTERSECTABLE:
521                        {
522                                KdNode *node = static_cast<KdIntersectable *>(obj)->GetItem();
523                                _UpdatePvsIndices(node, indexBufferSize);
524                        }
525                        break;
526#if DYNAMIC_OBJECTS_HACK
527#if USE_TRANSFORMED_MESH_INSTANCE_HACK
528
529                case Intersectable::TRANSFORMED_MESH_INSTANCE:
530                        mDynamicObjects.push_back(static_cast<TransformedMeshInstance *>(obj));
531                        break;
532
533#else
534                case Intersectable::SCENEGRAPHLEAF_INTERSECTABLE:
535                        mDynamicObjects.push_back(static_cast<SceneGraphLeafIntersectable *>(obj)->GetItem());
536                        break;
537#endif
538#endif
539                default:
540                        cerr << "PreparePvs: type " << Intersectable::GetTypeName(obj) << " not handled yet" << endl;
541                }
542        }
543
544        mIndexBufferSize = indexBufferSize;
545}
546
547
548
549
550void QtGlRendererWidget::RenderPvs()
551{
552        if (mUseVbos)
553                glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId);
554
555        ++ mCurrentFrame;
556
557        EnableDrawArrays();
558               
559        if (mDetectEmptyViewSpace)
560                glEnable(GL_CULL_FACE);
561        else
562                glDisable(GL_CULL_FACE);
563
564        ViewCell *viewcell = NULL;
565        viewcell = mViewCellsManager->GetViewCell(mViewPoint, true);
566
567        if (viewcell)
568        {
569#if 0
570                // copy the pvs so that it can be filtered ...
571                if (PvsChanged(viewcell))
572                {
573                        mPvsCache.Reset();
574                        mPvsCache.mViewCell = viewcell;
575                        mPvsCache.mUnfilteredPvsSize = viewcell->GetPvs().GetSize();
576
577                        if (mUseSpatialFilter)
578                        {
579                                //mMutex.lock();
580                                // mSpatialFilter size is in range 0.001 - 0.1
581                                mViewCellsManager->ApplyFilter2(viewcell,
582                                        mUseFilter,
583                                        100.0f * mSpatialFilterSize,
584                                        mPvsCache.mPvs,         
585                                        &mPvsCache.filteredBoxes);
586                                //mPvsCache.mPvs = pvs;
587                                //mMutex.unlock();
588                                //cout << "pvs size: " << mPvsCache.mPvs.GetSize() << endl;
589                        }
590                        else
591                        {
592                                mPvsCache.mPvs = viewcell->GetPvs();
593                        }
594                       
595                        // update the indices for rendering
596                        PreparePvs2(mPvsCache.mPvs);
597                        emit PvsUpdated();
598                        mCurrentPvsCost = mPvsCache.mPvs.EvalPvsCost();
599                }
600#else
601       
602                PreparePvs2(viewcell->GetPvs());
603                emit PvsUpdated();
604
605#endif
606
607
608                // Render PVS
609                if (mUseSpatialFilter && mRenderBoxes)
610                {
611                        for (size_t i=0; i < mPvsCache.filteredBoxes.size(); ++ i)
612                        {
613                                RenderBox(mPvsCache.filteredBoxes[i]);
614                        }
615                }
616                else
617                {
618                        if (!mRenderVisibilityEstimates && !mUseRandomColorPerPvsObject)
619                                _RenderPvs();
620                        else
621                                _RenderColoredPvs();
622                }
623
624                if (mRenderFilter)
625                {
626                        mWireFrame = true;
627                        RenderIntersectable(viewcell);
628                       
629                        mWireFrame = false;
630                }
631                mCurrentPvsCost = viewcell->GetPvs().EvalPvsCost();
632        }
633        else
634        {
635                //OcclusionQuery *query = mOcclusionQueries[0];
636                //query->BeginQuery();
637               
638                RenderScene();
639
640                //query->EndQuery();
641                //int pixels = query->GetQueryResult();
642                //cout << " pixels: " << pixels;
643        }
644
645        //cout << "vp: " << mViewPoint << " vd: " << mViewDirection << endl;
646}
647
648float
649QtGlRendererWidget::RenderErrors()
650{
651        float pErrorPixels = -1.0f;
652
653        SetupCamera();
654        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
655
656        glPushAttrib(GL_ENABLE_BIT);
657
658        glStencilFunc(GL_EQUAL, 0x0, 0x1);
659        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
660
661        glColor3f(0.6f, 0.6f, 0.6f);
662
663        // Render PVS
664        RenderPvs();
665
666        glEnable(GL_STENCIL_TEST);
667
668        glDisable(GL_LIGHTING);
669
670        SetupCamera();
671
672        mUseForcedColors = true;
673
674        glColor3f(1.0f, 0.0f, 0.0f);
675
676        OcclusionQuery *query = mOcclusionQueries[0];
677        query->BeginQuery();
678
679        RenderScene();
680
681        mUseForcedColors = false;
682
683        query->EndQuery();
684
685        glDisable(GL_STENCIL_TEST);
686        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
687
688        glPopAttrib();
689
690        // reenable other state
691        //  int wait=0;
692        //  while (!query.ResultAvailable()) {
693        //      wait++;
694        //  }
695
696        int pixelCount = query->GetQueryResult();
697        pErrorPixels = ((float)pixelCount) / (GetWidth() * GetHeight());
698        if (0) cout << "error pixels=" << pixelCount << endl;
699
700        mRenderError = pErrorPixels;
701
702        return pErrorPixels;
703}
704
705
706void QtGlRendererWidget::timerEvent(QTimerEvent *event)
707{
708        //std::cout << "Timer ID:" << event->timerId();
709        update();
710}
711
712
713void QtGlRendererWidget::mousePressEvent(QMouseEvent *e)
714{
715        int x = e->pos().x();
716        int y = e->pos().y();
717
718        mousePoint.x = x;
719        mousePoint.y = y;
720
721}
722
723void QtGlRendererWidget::mouseReleaseEvent(QMouseEvent *e)
724{
725
726  if (e->modifiers() & Qt::AltModifier)
727        if (mCurrentDynamicObjectIdx >= 0) {
728          //      preprocessor->ScheduleUpdateDynamicObjects();
729        }
730}
731
732void
733QtGlRendererWidget::mouseMoveEvent(QMouseEvent *e)
734{
735        float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
736        float TURN_SENSITIVITY = 0.1f;
737        float TILT_SENSITIVITY = 32.0 ;
738        float TURN_ANGLE= M_PI  /36.0 ;
739
740        int x = e->pos().x();
741        int y = e->pos().y();
742
743        int diffx = -(mousePoint.x - x);
744        int diffy = -(mousePoint.y - y);
745
746        const float t = 1.0f;
747
748        if (e->modifiers() & Qt::ControlModifier)
749        {
750                mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY / 2.0;
751                mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY / 2.0;
752        }
753#if DYNAMIC_OBJECTS_HACK
754        else if (e->modifiers() & Qt::AltModifier)
755        {
756                if (mCurrentDynamicObjectIdx >= 0)
757                {
758                        Matrix4x4 tm;
759
760                        switch (mTrafoType)
761                        {
762                        case 0:
763                                {
764                                  if (e->modifiers() & Qt::ShiftModifier) {
765                                        const Vector3 transl(0, diffy, 0);
766                                        tm = TranslationMatrix(transl);
767                                 
768                                  } else {
769                                        const Vector3 transl(diffx, 0, diffy);
770                                        tm = TranslationMatrix(transl);
771                                  }
772                                }
773                                break;
774                        case 1:
775                                {
776                                        float scalef = 1.0f + 0.01f * (diffx + diffy);
777                                        if (scalef < 0.9) scalef = 0.9f;
778                                        else if (scalef > 1.1f) scalef = 1.1f;
779                                        tm = ScaleMatrix(scalef, scalef, scalef);
780                                }
781                                break;
782                        case 2:
783                                {
784                                  //                                    tm = RotationXMatrix(diffx) * RotationYMatrix(diffy);
785                                  tm = RotationYMatrix(diffx);
786                                }
787                                break;
788                        default:
789                                cerr << "not implemented" << endl;
790                        }
791
792#if USE_TRANSFORMED_MESH_INSTANCE_HACK
793                        TransformedMeshInstance *tmi = mViewCellsManager->GetPreprocessor()->mDynamicObjects[mCurrentDynamicObjectIdx];
794                        tmi->ApplyWorldTransform(tm);
795#else
796                        SceneGraphLeaf *l =
797                          mViewCellsManager->GetPreprocessor()->mDynamicObjects[mCurrentDynamicObjectIdx];
798                        l->ApplyTransform(tm);
799                       
800#endif
801                        updateGL();
802                }
803        }
804#endif
805        else
806        {
807                mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
808                float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
809                float angle = atan2(mViewDirection.x, mViewDirection.z);
810                mViewDirection.x = sin(angle + adiff);
811                mViewDirection.z = cos(angle + adiff);
812        }
813
814        mousePoint.x = x;
815        mousePoint.y = y;
816
817        updateGL();
818}
819
820
821void
822QtGlRendererWidget::resizeGL(int w, int h)
823{
824        SetupCameraProjection(w, h);
825        updateGL();
826}
827
828void
829QtGlRendererWidget::paintGL()
830{
831        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
832
833        if (1)
834        {
835                SetupCameraProjection(width(), height());
836                SetupCamera();
837
838                if (mRenderErrors)
839                {
840                        RenderErrors();
841                }
842                else
843                {
844                        glColor3f(0.6f, 0.6f, 0.6f);
845                        RenderPvs();
846                }
847
848                if (mShowRays)
849                {
850                        RenderRays(mViewCellsManager->mVizBuffer.GetRays(), mRayVisualizationMethod, mShowDistribution, 1);
851                }
852        }
853
854        RenderInfo();
855        mFrame ++;
856        //      cout<<"vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
857}
858
859
860void
861QtGlRendererWidget::SetupCamera()
862{
863        if (!mTopView)
864                GlRenderer::SetupCamera();
865        else
866        {
867                if (0)
868                {
869                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05;
870                        Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x,
871                                -1,
872                                mViewDirection.y);
873
874                        Vector3 target = mViewPoint + dist*mViewDirection;
875                        Vector3 up(0,1,0);
876
877                        glLoadIdentity();
878                        gluLookAt(pos.x, pos.y, pos.z,
879                                target.x, target.y, target.z,
880                                up.x, up.y, up.z);
881                }
882                else
883                {
884                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal()) * mTopDistance;
885                        Vector3 pos = mViewPoint  + dist * Vector3(0,   1, 0);
886
887                        Vector3 target = mViewPoint;
888                        Vector3 up(mViewDirection.x, 0, mViewDirection.z);
889
890                        glLoadIdentity();
891                        gluLookAt(pos.x, pos.y, pos.z,
892                                target.x, target.y, target.z,
893                                up.x, up.y, up.z);
894
895                }
896        }
897
898}
899
900
901void
902QtGlRendererWidget::keyPressEvent ( QKeyEvent * e )
903{
904        switch (e->key())
905        {
906case Qt::Key_E:
907        mRenderErrors = !mRenderErrors;
908        updateGL();
909        break;
910case Qt::Key_R:
911        mUseRandomColorPerPvsObject = !mUseRandomColorPerPvsObject;;
912        updateGL();
913        break;
914case Qt::Key_T:
915        mTopView = !mTopView;
916        SetupCameraProjection(width(), height());
917        updateGL();
918        break;
919case Qt::Key_V:
920        mRenderViewCells = !mRenderViewCells;
921        updateGL();
922        break;
923case Qt::Key_P:
924        // set random viewpoint
925        mViewCellsManager->GetViewPoint(mViewPoint);
926        updateGL();
927        break;
928case Qt::Key_S: {
929        // set view poitn and direction
930        QString text;
931        bool ok;
932        text.sprintf("%f %f %f", mViewPoint.x, mViewPoint.y, mViewPoint.z);
933        text = QInputDialog::getText(this,
934                "Enter a view point",
935                "",
936                QLineEdit::Normal,
937                text,
938                &ok);
939        if (!ok)
940                break;
941
942        if (sscanf(text.toAscii(), "%f %f %f", &mViewPoint.x, &mViewPoint.y, &mViewPoint.z) == 3) {
943                text.sprintf("%f %f %f", mViewDirection.x, mViewDirection.y, mViewDirection.z);
944                text = QInputDialog::getText(this,
945                        "Enter a direction",
946                        "",
947                        QLineEdit::Normal,
948                        text,
949                        &ok);
950                if (!ok)
951                        break;
952                if (sscanf(text.toAscii(), "%f %f %f", &mViewDirection.x,
953                        &mViewDirection.y, &mViewDirection.z) == 3) {
954                                updateGL();
955                        }
956                        break;
957        }
958                                }
959default:
960        cerr << "unknown key" << endl;
961        e->ignore();
962        break;
963        }
964}
965
966
967
968QtGlRendererWidget::QtGlRendererWidget(
969                                                                           SceneGraph *sceneGraph,
970                                                                           ViewCellsManager *viewcells,
971                                                                           KdTree *tree,
972                                                                           QWidget * parent,
973                                                                           const QGLWidget * shareWidget,
974                                                                           Qt::WFlags f
975                                                                           )
976                                                                           :
977GlRendererWidget(sceneGraph, viewcells, tree), QGLWidget(QGLFormat(QGL::SampleBuffers), parent, shareWidget, f)
978{
979        mPreprocessorThread = NULL;
980        mTopView = false;
981        mRenderViewCells = false;
982        mTopDistance = 1.0f;
983        mCutViewCells = false;
984        mCutScene = false;
985        mRenderErrors = false;
986        mRenderBoxes = false;
987        mRenderFilter = true;
988        mRenderVisibilityEstimates = false;
989        //mRenderVisibilityEstimates = true;
990
991        mComputeGVS = false;
992        mUseRandomColorPerPvsObject = false;
993
994        mHideByCost = false;
995        mUseTransparency = false;
996
997        mTransferFunction = 1.0f;
998        mIndexBufferSize = 0;
999
1000        const int delay = 250; // in milliseconds
1001        timerId = startTimer(delay);
1002
1003        bool tmp;
1004
1005        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
1006        mUseFilter = tmp;
1007
1008        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp );
1009        mUseSpatialFilter = tmp;
1010
1011        //mLogWriter = new LogWriter("myfile.out");
1012
1013        mShowRenderCost = false;
1014        mShowPvsSizes = false;
1015        mShowComparison = false;
1016        mShowPiercingRays = false;
1017        mShowWeightedRays = false;
1018        mUseStandardColors = false;
1019        mShowWeightedCost = true;
1020
1021        mShowDistanceWeightedPvs = true;
1022        mShowDistanceWeightedTriangles = false;
1023        mShowWeightedTriangles = false;
1024        mShowDistribution = 15;
1025        mCurrentDynamicObjectIdx = -1;
1026
1027        mSpatialFilterSize = 0.01;
1028        mPvsSize = 0;
1029        mRayVisualizationMethod = 0;
1030        mTrafoType = 0;
1031
1032        mRenderError = 0.0f;
1033        mShowRays = false;
1034
1035        SetSceneCut(1000);
1036        mControlWidget = new QtRendererControlWidget(NULL);
1037
1038        connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int)));
1039        connect(mControlWidget, SIGNAL(SetTransferFunction(int)), this, SLOT(SetTransferFunction(int)));
1040
1041        connect(mControlWidget, SIGNAL(UpdateAllPvs()), this, SLOT(UpdateAllPvs()));
1042        connect(mControlWidget, SIGNAL(ComputeVisibility()), this, SLOT(ComputeVisibility()));
1043        connect(mControlWidget, SIGNAL(StopComputation()), this, SLOT(StopComputation()));
1044        connect(mControlWidget, SIGNAL(SetRandomViewPoint()), this,     SLOT(SetRandomViewPoint()));
1045        connect(mControlWidget, SIGNAL(StoreStatistics(void)), this, SLOT(StoreStatistics(void)));
1046        connect(mControlWidget, SIGNAL(ComputeGVS(void)), this, SLOT(ComputeGVS(void)));
1047        connect(mControlWidget, SIGNAL(LoadObject(void)), this, SLOT(LoadObject(void)));
1048
1049        connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int)));
1050        connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int)));
1051        connect(mControlWidget, SIGNAL(SetTransparency(int)), this, SLOT(SetTransparency(int)));
1052
1053        connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int)));
1054        connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int)));
1055        connect(mControlWidget, SIGNAL(SetHidingCost(int)), this, SLOT(SetHidingCost(int)));
1056
1057        connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool)));
1058        connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool)));
1059        connect(mControlWidget, SIGNAL(SetUseTransparency(bool)), this, SLOT(SetUseTransparency(bool)));
1060        connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool)));
1061        connect(mControlWidget, SIGNAL(SetShowComparison(bool)), this, SLOT(SetShowComparison(bool)));
1062        connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool)));
1063        connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool)));
1064        connect(mControlWidget, SIGNAL(SetHideByCost(bool)), this, SLOT(SetHideByCost(bool)));
1065        connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool)));
1066        connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool)));
1067        connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool)));
1068        connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool)));
1069        connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)), this, SLOT(SetRenderVisibilityEstimates(bool)));
1070        connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool)));
1071        connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)), this, SLOT(SetUseSpatialFilter(bool)));
1072        connect(mControlWidget, SIGNAL(SetShowPiercingRays(bool)), this, SLOT(SetShowPiercingRays(bool)));
1073        connect(mControlWidget, SIGNAL(SetShowWireFrame(bool)), this, SLOT(SetShowWireFrame(bool)));
1074        connect(mControlWidget, SIGNAL(SetShowWeightedRays(bool)), this, SLOT(SetShowWeightedRays(bool)));
1075        connect(mControlWidget, SIGNAL(SetShowWeightedCost(bool)), this, SLOT(SetShowWeightedCost(bool)));
1076
1077        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedTriangles(bool)), this, SLOT(SetShowDistanceWeightedTriangles(bool)));
1078        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedPvs(bool)), this, SLOT(SetShowDistanceWeightedPvs(bool)));
1079        connect(mControlWidget, SIGNAL(SetShowWeightedTriangles(bool)), this, SLOT(SetShowWeightedTriangles(bool)));
1080
1081        connect(mControlWidget, SIGNAL(UseConstColorForRayViz(bool)), this, SLOT(UseConstColorForRayViz(bool)));
1082        connect(mControlWidget, SIGNAL(UseRayLengthForRayViz(bool)), this, SLOT(UseRayLengthForRayViz(bool)));
1083        connect(mControlWidget, SIGNAL(SetShowContribution(bool)), this, SLOT(SetShowContribution(bool)));
1084        connect(mControlWidget, SIGNAL(SetShowDistribution(bool)), this, SLOT(SetShowDistribution(bool)));
1085
1086        connect(mControlWidget, SIGNAL(SetShowDistribution1(bool)), this, SLOT(SetShowDistribution1(bool)));
1087        connect(mControlWidget, SIGNAL(SetShowDistribution2(bool)), this, SLOT(SetShowDistribution2(bool)));
1088        connect(mControlWidget, SIGNAL(SetShowDistribution3(bool)), this, SLOT(SetShowDistribution3(bool)));
1089        connect(mControlWidget, SIGNAL(SetShowDistribution4(bool)), this, SLOT(SetShowDistribution4(bool)));
1090
1091        connect(mControlWidget, SIGNAL(SetShowRays(bool)), this, SLOT(SetShowRays(bool)));
1092
1093        connect(mControlWidget, SIGNAL(SetTranslation(bool)), this, SLOT(SetTranslation(bool)));
1094        connect(mControlWidget, SIGNAL(SetRotation(bool)), this, SLOT(SetRotation(bool)));
1095        connect(mControlWidget, SIGNAL(SetScale(bool)), this, SLOT(SetScale(bool)));
1096
1097        connect(mControlWidget, SIGNAL(UpdateDynamicObjects()), this, SLOT(UpdateDynamicObjects()));
1098
1099        setWindowTitle("PVS Visualization");
1100
1101        // setting the main window size here
1102        resize(800, 600);
1103        //resize(640, 400);
1104       
1105        mControlWidget->show();
1106}
1107
1108void
1109QtGlRendererWidget::UpdateAllPvs()
1110{
1111        // $$ does not work so far:(
1112        mViewCellsManager->UpdatePvsForEvaluation();
1113        //      mViewCellsManager->FinalizeViewCells(false);
1114}
1115
1116void
1117QtGlRendererWidget::ComputeVisibility()
1118{
1119        cerr<<"Compute Visibility called!\n"<<endl;
1120        if (!mPreprocessorThread->isRunning())
1121                mPreprocessorThread->RunThread();
1122}
1123
1124void
1125QtGlRendererWidget::StopComputation()
1126{
1127        cerr<<"stop computation called!\n"<<endl;
1128        mViewCellsManager->GetPreprocessor()->mStopComputation = true;
1129}
1130
1131void
1132QtGlRendererWidget::SetRandomViewPoint()
1133{
1134        cerr<<"setting random view point!\n"<<endl;
1135        mViewCellsManager->GetViewPoint(mViewPoint);
1136        updateGL();
1137}
1138
1139
1140void QtGlRendererWidget::StoreStatistics()
1141{
1142        cerr<<"storing statistics!\n"<<endl;
1143        const int currentSamples = mViewCellsManager->GetPreprocessor()->mCurrentSamples;
1144
1145        cout<<"**********************************************" << endl;
1146        cout << "reached " << currentSamples << " samples " << " => writing file" << endl;
1147               
1148        LogWriter writer;
1149        writer.SetFilename("compare.log");
1150        writer.Write(currentSamples, mViewCellsManager->GetViewCells());
1151        cout << "finished writing file" << endl;
1152        mCompareInfo.clear();
1153        updateGL();
1154}
1155
1156
1157void QtGlRendererWidget::LoadObject()
1158{
1159        string filename("../data/teapot.bn");
1160        //string filename("../data/cube.obj");
1161       
1162        cout << "Loading model << " << filename << endl;
1163
1164        ++ mCurrentDynamicObjectIdx;
1165
1166        if (mViewCellsManager->GetPreprocessor()->LoadDynamicGeometry(filename)) {
1167         
1168          cout << "Loading finished" << endl;
1169        } else
1170          cerr << "Loading failed" << endl;
1171       
1172    updateGL();
1173}
1174
1175void
1176QtGlRendererWidget::RenderRenderCost()
1177{
1178        static vector<float> costFunction;
1179        static float maxCost = -1;
1180        if (costFunction.size()==0) {
1181                ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree();
1182                if (tree) {
1183                        tree->GetCostFunction(costFunction);
1184                        maxCost = -1;
1185                        for (int i=0;  i < costFunction.size(); i++) {
1186                                //                cout<<i<<":"<<costFunction[i]<<" ";
1187                                // update cost function to an absolute value based on the total geometry count
1188                                costFunction[i] *= mSceneGraph->GetSize();
1189                                if (costFunction[i] > maxCost)
1190                                        maxCost = costFunction[i];
1191                        }
1192                }
1193        }
1194
1195
1196        int currentPos = (int)mViewCellsManager->GetViewCells().size();
1197        float currentCost= -1;
1198
1199        if (currentPos < costFunction.size())
1200                currentCost = costFunction[currentPos];
1201#if 1   
1202        cout<<"costFunction.size()="<<(int)costFunction.size()<<endl;
1203        cout<<"CP="<<currentPos<<endl;
1204        cout<<"MC="<<maxCost<<endl;
1205        cout<<"CC="<<currentCost<<endl;
1206#endif
1207        if (costFunction.size()) {
1208                float scaley = 1.0f/log10(maxCost);
1209                float scalex = 1.0f/(float)costFunction.size();
1210
1211                glDisable(GL_DEPTH_TEST);
1212                // init ortographic projection
1213                glMatrixMode(GL_PROJECTION);
1214
1215                glPushMatrix();
1216
1217                glLoadIdentity();
1218                gluOrtho2D(0, 1.0f, 0, 1.0f);
1219
1220                glTranslatef(0.1f, 0.1f, 0.0f);
1221                glScalef(0.8f, 0.8f, 1.0f);
1222                glMatrixMode(GL_MODELVIEW);
1223                glLoadIdentity();
1224
1225                glColor3f(1.0f,0,0);
1226                glBegin(GL_LINE_STRIP);
1227                //        glVertex3f(0,0,0);
1228
1229                for (int i=0;  i < costFunction.size(); i++) {
1230                        float x =  i*scalex;
1231                        float y = log10(costFunction[i])*scaley;
1232                        glVertex3f(x,y,0.0f);
1233                }
1234                glEnd();
1235
1236                glColor3f(1.0f,0,0);
1237                glBegin(GL_LINES);
1238                float x =  currentPos*scalex;
1239                glVertex3f(x,0.0,0.0f);
1240                glVertex3f(x,1.0f,0.0f);
1241                glEnd();
1242
1243                glColor3f(0.0f,0,0);
1244                // show a grid
1245                glBegin(GL_LINE_LOOP);
1246                glVertex3f(0,0,0.0f);
1247                glVertex3f(1,0,0.0f);
1248                glVertex3f(1,1,0.0f);
1249                glVertex3f(0,1,0.0f);
1250                glEnd();
1251
1252                glBegin(GL_LINES);
1253                for (int i=0;  i < costFunction.size(); i += 1000) {
1254                        float x =  i*scalex;
1255                        glVertex3f(x,0.0,0.0f);
1256                        glVertex3f(x,1.0f,0.0f);
1257                }
1258
1259                for (int i=0;  pow(10.0f, i) < maxCost; i+=1) {
1260                        float y = i*scaley;
1261                        //              QString s;
1262                        //              s.sprintf("%d", (int)pow(10,i));
1263                        //              renderText(width()/2+5, y*height(), s);
1264                        glVertex3f(0.0f, y, 0.0f);
1265                        glVertex3f(1.0f, y, 0.0f);
1266                }
1267
1268                glEnd();
1269
1270
1271                // restore the projection matrix
1272                glMatrixMode(GL_PROJECTION);
1273                glPopMatrix();
1274                glMatrixMode(GL_MODELVIEW);
1275                glEnable(GL_DEPTH_TEST);
1276
1277        }
1278
1279
1280
1281}
1282
1283void
1284QtGlRendererWidget::RenderInfo()
1285{
1286
1287        QString s;
1288
1289        int vc = 0;
1290        if (mViewCellsManager)
1291                vc = (int)mViewCellsManager->GetViewCells().size();
1292
1293        int filter = 0;
1294        if (mViewCellsManager)
1295                filter = mViewCellsManager->GetMaxFilterSize();
1296
1297        glColor3f(0.0f, 0.0f, 1.0f);
1298
1299#if REMOVE_TEMPORARY
1300        s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f)",
1301                mFrame,
1302                mViewPoint.x,
1303                mViewPoint.y,
1304                mViewPoint.z,
1305                mViewDirection.x,
1306                mViewDirection.y,
1307                mViewDirection.z
1308                );
1309
1310        renderText(20, 20, s);
1311
1312        s.sprintf("viewcells:%04d filter:%04d pvs:%04d error:%5.5f %",
1313                vc,
1314                filter,
1315                mPvsSize,
1316                mRenderError*100.0f);
1317
1318        renderText(20, 40, s);
1319#endif
1320
1321        QFont font40; font40.setPointSize(30);
1322        //s.sprintf("PVS: %04d", mPvsSize);
1323        //renderText(20, 40, s, font40);
1324       
1325        //s.sprintf("RAW TRI: %07d", mViewCellsManager->GetPreprocessor()->mGenericStats);
1326        //renderText(290, 40, s, font40);
1327        //s.sprintf("PVS TRI: %07d", mViewCellsManager->GetPreprocessor()->mGenericStats2);
1328        //renderText(290, 70, s, font40);
1329
1330        s.sprintf("PVS TRI: %07d", (int)mCurrentPvsCost);
1331        renderText(290, 70, s, font40);
1332        //renderText(290, 70, s, font40);
1333
1334}
1335
1336
1337void
1338QtGlRendererWidget::SetViewCellGranularity(int number)
1339{
1340        if (mViewCellsManager)
1341        {
1342                //      mViewCellsManager->SetMaxFilterSize(number);
1343
1344                // $$ tmp off
1345                mViewCellsManager->CollectViewCells(number);
1346
1347                // $$ does not work so far:(
1348                //      mViewCellsManager->UpdatePvsForEvaluation();
1349                //      mViewCellsManager->FinalizeViewCells(false);
1350        }
1351        updateGL();
1352}
1353
1354void
1355QtGlRendererWidget::SetVisibilityFilterSize(int number)
1356{
1357        if (mViewCellsManager)
1358                mViewCellsManager->SetMaxFilterSize(number);
1359
1360        mPvsCache.Reset();
1361        updateGL();
1362}
1363
1364void
1365QtGlRendererWidget::SetSpatialFilterSize(int number)
1366{
1367        mSpatialFilterSize = 1e-3*number;
1368        mPvsCache.Reset();
1369        updateGL();
1370}
1371
1372void
1373QtGlRendererWidget::SetSceneCut(int number)
1374{
1375        // assume the cut plane can only be aligned with xz plane
1376        // shift it along y according to number, which is percentage of the bounding
1377        // box position
1378        if (mViewCellsManager)
1379        {
1380                const float f = number / 1000.0f;
1381                AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
1382                Vector3 p = (1.0f - f) * box.Min() + f * box.Max();
1383                mSceneCutPlane.mNormal = Vector3(0, -1, 0);
1384                mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p);
1385
1386                updateGL();
1387        }
1388}
1389
1390void
1391QtGlRendererWidget::SetHidingCost(int number)
1392{
1393        mHidingCost = (float)number / 1000.0f;
1394}
1395
1396
1397void
1398QtGlRendererWidget::SetTopDistance(int number)
1399{
1400        mTopDistance = number / 1000.0f;
1401        updateGL();
1402}
1403
1404void QtGlRendererWidget::SetTransparency(int number)
1405{
1406        mTransparency = number / 1000.0f;
1407        updateGL();
1408}
1409
1410#if 0
1411float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1412{
1413        ObjectPvs basePvs;
1414       
1415        basePvs = vc->CopyPvs();
1416        ObjectPvsIterator pit = basePvs.GetIterator();
1417
1418        float renderCost = 0;
1419
1420        //cout << "cost vis: " << mShowDistanceWeightedPvs << " " << " " << mShowDistanceWeightedTriangles << " " << mShowWeightedTriangles << endl;
1421       
1422        // first mark all objects from this pvs
1423        while (pit.HasMoreEntries())   
1424        {
1425                KdIntersectable *kdObj = static_cast<KdIntersectable *>(pit.Next());
1426
1427                if (mShowDistanceWeightedPvs)
1428                {
1429                        const AxisAlignedBox3 box = kdObj->GetBox();
1430
1431                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1432                        renderCost += 1.0f / dist;
1433                }
1434                else if (mShowDistanceWeightedTriangles)
1435                {
1436                        const AxisAlignedBox3 box = kdObj->GetBox();
1437
1438                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1439                        renderCost += kdObj->ComputeNumTriangles() / dist;
1440                }
1441                else //if (mShowWeightedTriangles)
1442                {
1443                        renderCost += kdObj->ComputeNumTriangles();
1444                }
1445                //if (pit.Next()->Mail();
1446        }
1447
1448        return renderCost;
1449}
1450#else
1451
1452float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1453{
1454        float renderCost = 0;
1455
1456#ifdef USE_VERBOSE_PVS
1457        if (mShowDistanceWeightedPvs)
1458        {
1459                return vc->GetPvs().mStats.mDistanceWeightedPvs;
1460        }
1461        else if (mShowDistanceWeightedTriangles)
1462        {
1463                return vc->GetPvs().mStats.mDistanceWeightedTriangles;
1464        }
1465        else //if (mShowWeightedTriangles)
1466        {
1467                return vc->GetPvs().mStats.mWeightedTriangles;
1468        }
1469#else
1470        return 0.0f;
1471#endif
1472}
1473#endif
1474
1475
1476
1477void QtGlRendererWidget::ComputeMaxValues(const ViewCellContainer &viewCells,
1478                                                                                  int &maxPvs,
1479                                                                                  int &maxPiercingRays,
1480                                                                                  float &maxRelativeRays,
1481                                                                                  float &maxRcCost)
1482{
1483        maxPvs = -1;
1484        maxPiercingRays = 1; // not zero for savety
1485        maxRelativeRays = Limits::Small; // not zero for savety
1486        maxRcCost = Limits::Small;
1487
1488        for (size_t i = 0; i < viewCells.size(); ++ i)
1489        {
1490                ViewCell *vc = viewCells[i];
1491
1492                if (mShowPvsSizes) // pvs size
1493                {
1494                        //const int p = vc->GetPvs().CountObjectsInPvs();
1495                        const int p = vc->GetPvs().GetSize();
1496                        if (p > maxPvs)
1497                                maxPvs = p;
1498                }
1499                else if (mShowPiercingRays) // relative number of rays
1500                {
1501                        const int piercingRays = vc->GetNumPiercingRays();
1502
1503                        if (piercingRays > maxPiercingRays)
1504                                maxPiercingRays = piercingRays;
1505                }
1506                else if (mShowWeightedRays)
1507                {
1508                        const int piercingRays = vc->GetNumPiercingRays();
1509
1510                        const float relativeArea =
1511                                vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1512
1513                        if ((float)piercingRays / relativeArea > maxRelativeRays)
1514                                maxRelativeRays = (float)piercingRays / relativeArea;
1515                }
1516                else if (mShowWeightedCost)
1517                {
1518                        const float rcCost = ComputeRenderCost(vc);
1519                        mViewCellsManager->UpdateScalarPvsCost(vc, rcCost);
1520
1521                        if (rcCost > maxRcCost)
1522                                maxRcCost = rcCost;
1523                }
1524        }
1525}
1526
1527
1528void QtGlRendererWidget::RenderViewCells()
1529{
1530        mUseFalseColors = true;
1531        //glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
1532
1533        glEnable(GL_CULL_FACE);
1534        glCullFace(GL_FRONT);
1535        //glDisable(GL_CULL_FACE);
1536
1537        if (mCutViewCells)
1538        {
1539                double eq[4];
1540                eq[0] = mSceneCutPlane.mNormal.x;
1541                eq[1] = mSceneCutPlane.mNormal.y;
1542                eq[2] = mSceneCutPlane.mNormal.z;
1543                eq[3] = mSceneCutPlane.mD;
1544
1545                glClipPlane(GL_CLIP_PLANE0, eq);
1546                glEnable(GL_CLIP_PLANE0);
1547        }
1548
1549        ViewCellContainer &viewcells = mViewCellsManager->GetViewCells();
1550       
1551        int maxPvs, maxPiercingRays;
1552        float maxRelativeRays, maxRcCost;
1553
1554        ComputeMaxValues(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1555       
1556        // matt: temp hack
1557        //maxRcCost = 5000.0f;
1558        //cout << "maxRcCost: " << maxRcCost << endl;
1559
1560        int i;
1561
1562        // transparency
1563        if (!mUseTransparency)
1564        {
1565                glEnable(GL_DEPTH_TEST);
1566                glDisable(GL_BLEND);
1567        }
1568        else
1569        {
1570                glDisable(GL_DEPTH_TEST);
1571                glEnable(GL_BLEND);
1572
1573                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1574                //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1575
1576                for (i = 0; i < viewcells.size(); ++ i)
1577                {
1578                        ViewCell *vc = viewcells[i];
1579
1580                        const float dist = SqrDistance(mDummyViewPoint, vc->GetBox().Center());
1581                        vc->SetDistance(dist);
1582                }
1583
1584                sort(viewcells.begin(), viewcells.end(), nearerThan);
1585        }
1586
1587        //mWireFrame = true;
1588               
1589        // normal rendering
1590        //if (!mShowPvsSizes && !mShowPiercingRays && !mShowWeightedRays && !mShowWeightedCost && !mShowComparison)
1591        if (mUseStandardColors)
1592        {
1593                for (i = 0; i < viewcells.size(); ++ i)
1594                {
1595                        ViewCell *vc = viewcells[i];
1596                        RgbColor c;
1597
1598                        //if (!mShowPvsSizes && !mShowPiercingRays)
1599                        c = vc->GetColor();
1600                       
1601                        glColor3f(c.r, c.g, c.b);
1602
1603                        if (!mHideByCost || (mHidingCost < (vc->GetNumPiercingRays() / (float)maxPiercingRays)))
1604                        {
1605                RenderViewCell(vc);
1606                        }
1607                }
1608        }
1609        else // using specialised colors
1610        {
1611                if (!mShowComparison)
1612                        AssignImportanceByRelativeValue(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1613                else
1614                {
1615                        if (mCompareInfo.empty())
1616                        {
1617                                LogReader reader;
1618                                reader.SetFilename("compare.log");
1619                                int samples;
1620                                reader.Read(samples, mCompareInfo);
1621                        }
1622
1623                        AssignColorByComparison(viewcells, mCompareInfo);
1624                }
1625
1626                glEnable(GL_DEPTH_TEST);       
1627        }
1628       
1629        glEnable(GL_CULL_FACE);
1630        glDisable(GL_CULL_FACE);
1631
1632        glDisable(GL_CLIP_PLANE0);
1633
1634        mUseFalseColors = false;
1635        mWireFrame = false;
1636
1637        glPopAttrib();
1638}
1639
1640
1641void QtGlRendererWidget::AssignImportanceByRelativeValue(const ViewCellContainer &viewCells,
1642                                                                                                                 int &maxPvs,
1643                                                                                                                 int &maxPiercingRays,
1644                                                                                                                 float &maxRelativeRays,
1645                                                                                                                 float &maxRcCost)
1646{
1647        for (size_t i = 0; i < viewCells.size(); ++ i)
1648        {
1649                RgbColor c;
1650                ViewCell *vc = viewCells[i];
1651
1652                float importance;
1653
1654                if (mShowPiercingRays)
1655                {
1656                        importance = mTransferFunction *
1657                                ((float)vc->GetNumPiercingRays() / (float)maxPiercingRays);
1658                }
1659                else if (mShowWeightedRays) // relative number of rays
1660                {
1661                        float relativeArea = vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1662
1663                        if (relativeArea < Limits::Small)
1664                                relativeArea = Limits::Small;
1665
1666                        importance = mTransferFunction * ((float)vc->GetNumPiercingRays() / relativeArea) / maxRelativeRays;
1667                }
1668                else if (mShowPvsSizes) // pvs size
1669                {
1670                        importance = mTransferFunction *
1671                                ((float)vc->GetPvs().GetSize() / (float)maxPvs);
1672                } // weighted render cost
1673                else if (mShowWeightedCost)
1674                {
1675                        const float rcCost = mTransferFunction * ComputeRenderCost(vc);
1676                        importance = rcCost / maxRcCost;
1677                }
1678if (importance > 1.0f) importance = 1.0f;
1679                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1680                c = RainbowColorMapping(importance);
1681
1682                glColor4f(c.r, c.g, c.b, 1.0f - mTransparency);
1683
1684                if (!mHideByCost || (mHidingCost < importance))
1685                {
1686                        RenderViewCell(vc);
1687                }
1688        }
1689}
1690
1691
1692void QtGlRendererWidget::AssignColorByComparison(const ViewCellContainer &viewcells,
1693                                                                                                 //const ViewCellInfoContainer &infos1,
1694                                                                                                 const ViewCellInfoContainer &compareInfo)
1695{
1696        if (viewcells.size() > compareInfo.size())
1697        {
1698                cerr << "loaded size (" << (int)compareInfo.size()
1699                         << ") does not fit to view cells size (" << (int)viewcells.size() << ")" << endl;
1700                return;
1701        }
1702
1703        //const float maxRatio = 1.0f;
1704        const float maxRatio = 2.0f;
1705        const float minRatio = 0.0f;
1706
1707        const float scale = 1.0f / (maxRatio - minRatio);
1708
1709        for (size_t i = 0; i < viewcells.size(); ++ i)
1710        {
1711                RgbColor c;
1712                ViewCell *vc = viewcells[i];
1713
1714                //ViewCellInfo vc1Info = infos1[i];
1715                ViewCellInfo vc2Info = compareInfo[i];
1716
1717                //const float vcRatio = vc->GetNumPiercingRays() / vc2Info.mPiercingRays + Limits::Small;
1718                float vcRatio = 1.0f;//maxRatio;
1719               
1720                if (vc2Info.mPvsSize > Limits::Small)
1721                        vcRatio = (float)vc->GetPvs().GetSize() / vc2Info.mPvsSize;
1722
1723                // truncate here
1724                if (vcRatio > maxRatio) vcRatio = 1.0f;
1725
1726                const float importance = (vcRatio - minRatio) * scale;
1727       
1728                if (0 && (i < 20))
1729                {
1730                        cout << "pvs1: " << vc->GetPvs().GetSize() << " pvs2: " << compareInfo[i].mPvsSize << " importance: " << importance << endl;
1731                }
1732
1733                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1734                c = RainbowColorMapping(importance);
1735
1736                glColor4f(c.r, c.g, c.b, 1.0f);
1737
1738                if (1)//!mHideByCost || (mHidingCost < importance))
1739                {
1740                        RenderViewCell(vc);
1741                }
1742        }
1743}
1744
1745
1746
1747/**********************************************************************/
1748/*              QtRendererControlWidget implementation                */
1749/**********************************************************************/
1750
1751
1752QGroupBox *QtRendererControlWidget::CreateVisualizationPanel(QWidget *parent)
1753{
1754        QRadioButton *rb1, *rb2, *rb3, *rb4, *rb5;
1755       
1756        rb1 = new QRadioButton("random colors", parent);
1757        rb1->setText("random");
1758        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWireFrame(bool)));
1759
1760        // Create a check box to be in the group box
1761        rb2 = new QRadioButton("piercing rays", parent);
1762        rb2->setText("piercing rays");
1763        //vl->addWidget(rb1);
1764        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowPiercingRays(bool)));
1765
1766        rb3 = new QRadioButton("pvs size", parent);
1767        rb3->setText("pvs size");
1768        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool)));
1769       
1770        rb4 = new QRadioButton("weighted rays", parent);
1771        rb4->setText("weighted rays");
1772        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedRays(bool)));
1773       
1774        rb5 = new QRadioButton("pvs cost", parent);
1775        rb5->setText("pvs cost");
1776        connect(rb5, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedCost(bool)));
1777
1778        QGroupBox *groupBox = new QGroupBox("PVS Visualization");
1779
1780        QVBoxLayout *vbox2 = new QVBoxLayout;
1781   
1782        vbox2->addWidget(rb1);
1783        vbox2->addWidget(rb2);
1784        vbox2->addWidget(rb3);
1785        vbox2->addWidget(rb4);
1786        vbox2->addWidget(rb5);
1787       
1788        rb5->setChecked(true);
1789
1790        vbox2->addStretch(1);
1791        groupBox->setLayout(vbox2);
1792
1793        return groupBox;
1794}
1795
1796
1797QGroupBox *QtRendererControlWidget::CreateTrafoPanel(QWidget *parent)
1798{
1799        QRadioButton *rb1, *rb2, *rb3;
1800       
1801        rb1 = new QRadioButton("translation", parent);
1802        rb1->setText("translation");
1803        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetTranslation(bool)));
1804
1805        // Create a check box to be in the group box
1806        rb2 = new QRadioButton("scale", parent);
1807        rb2->setText("scale");
1808        //vl->addWidget(rb1);
1809        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetScale(bool)));
1810
1811        rb3 = new QRadioButton("rotation", parent);
1812        rb3->setText("rotation");
1813        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetRotation(bool)));
1814   
1815        QVBoxLayout *vbox2 = new QVBoxLayout;
1816        QGroupBox *groupBox = new QGroupBox("Trafo types");
1817
1818        vbox2->addWidget(rb1);
1819        vbox2->addWidget(rb2);
1820        vbox2->addWidget(rb3);
1821       
1822        rb1->setChecked(true);
1823
1824        vbox2->addStretch(1);
1825
1826
1827        QPushButton *button = new QPushButton("Update", groupBox);
1828        vbox2->addWidget(button);
1829        connect(button, SIGNAL(clicked()), SIGNAL(UpdateDynamicObjects()));
1830       
1831       
1832        groupBox->setLayout(vbox2);
1833       
1834        return groupBox;
1835}
1836
1837
1838QGroupBox *QtRendererControlWidget::CreateRenderCostPanel(QWidget *parent)
1839{
1840        QRadioButton *rb1, *rb2, *rb3;
1841       
1842        // Create a check box to be in the group box
1843        rb1 = new QRadioButton("triangles", parent);
1844        rb1->setText("triangles");
1845        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedTriangles(bool)));
1846
1847        rb2 = new QRadioButton("distance weighted pvs", parent);
1848        rb2->setText("distance weighted");
1849        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedPvs(bool)));
1850
1851        rb3 = new QRadioButton("distance weighted triangles", parent);
1852        rb3->setText("distance weighted triangles");
1853        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedTriangles(bool)));
1854
1855        QGroupBox *groupBox = new QGroupBox("Render cost options");
1856        QVBoxLayout *vbox2 = new QVBoxLayout;
1857   
1858        vbox2->addWidget(rb1);
1859        vbox2->addWidget(rb2);
1860        vbox2->addWidget(rb3);
1861       
1862        rb1->setChecked(true);
1863
1864        vbox2->addStretch(1);
1865        groupBox->setLayout(vbox2);
1866
1867        return groupBox;
1868}
1869
1870
1871QGroupBox *QtRendererControlWidget::CreateRayVisualizationPanel(QWidget *parent)
1872{
1873        QRadioButton *rb1, *rb2, *rb3, *rb4;
1874       
1875        // Create a check box to be in the group box
1876        rb1 = new QRadioButton("const color", parent);
1877        rb1->setText("const color");
1878        //vl->addWidget(rb1);
1879        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(UseConstColorForRayViz(bool)));
1880
1881        rb2 = new QRadioButton("ray length", parent);
1882        rb2->setText("ray length");
1883        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(UseRayLengthForRayViz(bool)));
1884       
1885        rb3 = new QRadioButton("contribution", parent);
1886        rb3->setText("contribution");
1887        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowContribution(bool)));
1888       
1889        rb4 = new QRadioButton("distribution", parent);
1890        rb4->setText("distribution");
1891        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution(bool)));
1892
1893
1894        ///////////////////////////
1895
1896       
1897        QGroupBox *groupBox = new QGroupBox("Ray visualization");
1898        QVBoxLayout *vbox2 = new QVBoxLayout;
1899   
1900        vbox2->addWidget(rb1);
1901        vbox2->addWidget(rb2);
1902        vbox2->addWidget(rb3);
1903        vbox2->addWidget(rb4);
1904       
1905        rb1->setChecked(true);
1906
1907
1908        QCheckBox *cb = new QCheckBox("Distribution 1", parent);
1909        vbox2->addWidget(cb);
1910        cb->setChecked(true);
1911        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution1(bool)));
1912
1913        cb = new QCheckBox("Distribution 2", parent);
1914        vbox2->addWidget(cb);
1915        cb->setChecked(true);
1916        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution2(bool)));
1917
1918        cb = new QCheckBox("Distribution 3", parent);
1919        vbox2->addWidget(cb);
1920        cb->setChecked(true);
1921        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution3(bool)));
1922       
1923        cb = new QCheckBox("Distribution 4", parent);
1924        vbox2->addWidget(cb);
1925        cb->setChecked(true);
1926        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution4(bool)));
1927
1928
1929        vbox2->addStretch(1);
1930        groupBox->setLayout(vbox2);
1931
1932        return groupBox;
1933}
1934
1935
1936QtRendererControlWidget::QtRendererControlWidget(QWidget * parent, Qt::WFlags f):
1937QWidget(parent, f)
1938{
1939
1940        QVBoxLayout *vl = new QVBoxLayout;
1941        setLayout(vl);
1942       
1943        //QWidget *vbox;
1944
1945        //vbox = new QGroupBox("Render Controls", this);
1946        //layout()->addWidget(vbox);
1947        //vl = new QVBoxLayout;
1948        //vbox->setLayout(vl);
1949
1950        QLabel *label;
1951        QSlider *slider;
1952        QPushButton *button;
1953
1954#if 0//REMOVE_TEMPORARY
1955
1956        label = new QLabel("Granularity");
1957        //vbox->layout()->addWidget(label);
1958        vl->addWidget(label);
1959
1960        slider = new QSlider(Qt::Horizontal);
1961        vl->addWidget(slider);
1962        slider->show();
1963        slider->setRange(1, 10000);
1964        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1965        slider->setValue(200);
1966
1967        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int)));
1968
1969        ///////////////////////////
1970
1971        label = new QLabel("Transfer function");
1972        vl->addWidget(label);
1973
1974        slider = new QSlider(Qt::Horizontal);
1975        vl->addWidget(slider);
1976        slider->show();
1977        slider->setRange(1, 10000);
1978        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1979        slider->setValue(100);
1980
1981
1982        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransferFunction(int)));
1983
1984        ////////////////////////////////////////7
1985
1986        button = new QPushButton("Update all PVSs");
1987        vl->addWidget(button);
1988        connect(button, SIGNAL(clicked()), SLOT(UpdateAllPvs()));
1989
1990        ////////////////////////////////////////77777
1991
1992        label = new QLabel("Filter size");
1993        vl->addWidget(label);
1994
1995        slider = new QSlider(Qt::Horizontal);
1996        vl->addWidget(slider);
1997        slider->show();
1998        slider->setRange(1, 100);
1999        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2000        slider->setValue(3);
2001
2002        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int)));
2003
2004#endif
2005
2006
2007       
2008        ///////////////////////////////////
2009
2010
2011        QWidget *hbox = new QWidget();
2012        vl->addWidget(hbox);
2013        QHBoxLayout *hlayout = new QHBoxLayout;
2014        hbox->setLayout(hlayout);
2015
2016        QCheckBox *cb = new QCheckBox("Show viewcells", hbox);
2017        hlayout->addWidget(cb);
2018        cb->setChecked(false);
2019        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool)));
2020       
2021        cb = new QCheckBox("Render errors", hbox);
2022        hlayout->layout()->addWidget(cb);
2023        cb->setChecked(false);
2024        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool)));
2025
2026#if REMOVE_TEMPORARY
2027        cb = new QCheckBox("Render cost curve", hbox);
2028        hlayout->addWidget(cb);
2029        cb->setChecked(false);
2030        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool)));
2031#endif
2032        cb = new QCheckBox("Show rays", hbox);
2033        hlayout->addWidget(cb);
2034        cb->setChecked(false);
2035        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRays(bool)));
2036#if REMOVE_TEMPORARY   
2037        cb = new QCheckBox("Show Comparison", hbox);
2038        hlayout->addWidget(cb);
2039        cb->setChecked(false);
2040        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowComparison(bool)));
2041#endif
2042
2043        //////////////////
2044
2045        QHBoxLayout *vh = new QHBoxLayout;
2046
2047        QGroupBox *myBox = new QGroupBox("Visualization");
2048
2049        myBox->setLayout(vh);
2050        vl->addWidget(myBox, 0, 0);
2051
2052        QGroupBox *groupBox = CreateVisualizationPanel(hbox);
2053        vh->addWidget(groupBox, 0, 0);
2054
2055#if REMOVE_TEMPORARY
2056        QGroupBox *groupBox2 = CreateRenderCostPanel(hbox);
2057        vh->addWidget(groupBox2, 0, 0);
2058       
2059        QGroupBox *groupBox3 = CreateRayVisualizationPanel(hbox);
2060        vh->addWidget(groupBox3, 0, 0);
2061
2062        QGroupBox *groupBox4 = CreateTrafoPanel(hbox);
2063        vh->addWidget(groupBox4, 0, 0);
2064#endif
2065
2066        //////////////////////////////////
2067
2068        bool tmp = false;
2069        const int range = 1000;
2070
2071        //vbox->resize(800,150);
2072        QWidget *vbox;
2073
2074        vbox = new QGroupBox("Rendering", this);
2075        layout()->addWidget(vbox);
2076
2077        vl = new QVBoxLayout;
2078        vbox->setLayout(vl);
2079
2080
2081        cb = new QCheckBox("Cut view cells", vbox);
2082        vbox->layout()->addWidget(cb);
2083        cb->setChecked(false);
2084        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool)));
2085
2086
2087        slider = new QSlider(Qt::Horizontal, vbox);
2088        vbox->layout()->addWidget(slider);
2089        slider->show();
2090        slider->setRange(0, 1000);
2091        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2092        slider->setValue(1000);
2093
2094        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int)));
2095
2096
2097        cb = new QCheckBox("Use spatial filter", vbox);
2098        vbox->layout()->addWidget(cb);
2099        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp);
2100        cb->setChecked(tmp);
2101        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool)));
2102
2103
2104        label = new QLabel("Spatial Filter size");
2105        vbox->layout()->addWidget(label);
2106       
2107        slider = new QSlider(Qt::Horizontal, vbox);
2108        vbox->layout()->addWidget(slider);
2109        slider->show();
2110        slider->setRange(1, 100);
2111        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2112        slider->setValue(10);
2113
2114        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int)));
2115
2116        ////////////////////////////
2117
2118       
2119        cb = new QCheckBox("Hide view cells by render cost ", vbox);
2120        vbox->layout()->addWidget(cb);
2121        cb->setChecked(false);
2122        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetHideByCost(bool)));
2123
2124        label = new QLabel("Hide by cost");
2125        vbox->layout()->addWidget(label);
2126
2127        // the render cost visualization
2128        slider = new QSlider(Qt::Horizontal, vbox);
2129        vbox->layout()->addWidget(slider);
2130        slider->show();
2131        slider->setRange(0, range);
2132        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2133        slider->setValue(0);
2134        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetHidingCost(int)));
2135
2136        ///////////////////////////////////////////
2137
2138        cb = new QCheckBox("Top View", vbox);
2139        vbox->layout()->addWidget(cb);
2140        cb->setChecked(false);
2141        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool)));
2142
2143
2144        label = new QLabel("Top distance");
2145        vbox->layout()->addWidget(label);
2146       
2147        slider = new QSlider(Qt::Horizontal, vbox);
2148        vbox->layout()->addWidget(slider);
2149        slider->show();
2150        slider->setRange(1, 1000);
2151        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2152        slider->setValue(500);
2153
2154        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int)));
2155       
2156
2157        ///////////////////////////////////////////
2158#if REMOVE_TEMPORARY
2159        cb = new QCheckBox("Transparency", vbox);
2160        vbox->layout()->addWidget(cb);
2161        cb->setChecked(false);
2162        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseTransparency(bool)));
2163
2164        label = new QLabel("Use transparency");
2165        vbox->layout()->addWidget(label);
2166
2167        // the render cost visualization
2168        slider = new QSlider(Qt::Horizontal, vbox);
2169        vbox->layout()->addWidget(slider);
2170        slider->show();
2171        slider->setRange(0, range);
2172        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2173        slider->setValue(0);
2174        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransparency(int)));
2175#endif
2176       
2177
2178        //////////////////////////////
2179
2180#if REMOVE_TEMPORARY
2181
2182        cb = new QCheckBox("Cut scene", vbox);
2183        vbox->layout()->addWidget(cb);
2184        cb->setChecked(false);
2185        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool)));
2186
2187        cb = new QCheckBox("Render boxes", vbox);
2188        vbox->layout()->addWidget(cb);
2189        cb->setChecked(false);
2190        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool)));
2191
2192        cb = new QCheckBox("Render visibility estimates", vbox);
2193        vbox->layout()->addWidget(cb);
2194        cb->setChecked(false);
2195        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool)));
2196#endif
2197
2198#if REMOVE_TEMPORARY
2199
2200        cb = new QCheckBox("Use filter", vbox);
2201        vbox->layout()->addWidget(cb);
2202        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp);
2203        cb->setChecked(tmp);
2204        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool)));
2205#endif
2206
2207
2208       
2209
2210#if REMOVE_TEMPORARY
2211       
2212        cb = new QCheckBox("Render filter", vbox);
2213        vbox->layout()->addWidget(cb);
2214        cb->setChecked(true);
2215        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool)));
2216
2217
2218        /*vbox = new QGroupBox("PVS Errors", this);
2219        layout()->addWidget(vbox);
2220
2221        vl = new QVBoxLayout;
2222        vbox->setLayout(vl);
2223
2224        button = new QPushButton("Compute Visibility", vbox);
2225        vbox->layout()->addWidget(button);
2226        connect(button, SIGNAL(clicked()), SLOT(ComputeVisibility()));
2227
2228        button = new QPushButton("Stop Computation", vbox);
2229        vbox->layout()->addWidget(button);
2230        connect(button, SIGNAL(clicked()), SLOT(StopComputation()));
2231
2232        button = new QPushButton("Set Random View Point", vbox);
2233        vbox->layout()->addWidget(button);
2234        connect(button, SIGNAL(clicked()), SLOT(SetRandomViewPoint()));*/
2235
2236        button = new QPushButton("Store statistics", vbox);
2237        vbox->layout()->addWidget(button);
2238        connect(button, SIGNAL(clicked()), SIGNAL(StoreStatistics()));
2239
2240#endif
2241
2242        button = new QPushButton("Compute GVS", vbox);
2243        vbox->layout()->addWidget(button);
2244        connect(button, SIGNAL(clicked()), SIGNAL(ComputeGVS()));
2245
2246#if DYNAMIC_OBJECTS_HACK
2247
2248        button = new QPushButton("Load object", vbox);
2249        vbox->layout()->addWidget(button);
2250        connect(button, SIGNAL(clicked()), SIGNAL(LoadObject()));
2251#endif
2252
2253        /*cb = new QCheckBox("Stats", vbox);
2254        vbox->layout()->addWidget(cb);
2255        cb->setChecked(false);
2256        connect(cb, SIGNAL(toggled(bool)), SIGNAL(StoreStatistics()));*/
2257
2258        if (0)
2259        {
2260                vbox = new QGroupBox("PVS Errors", this);
2261                layout()->addWidget(vbox);
2262
2263                vl = new QVBoxLayout;
2264                vbox->setLayout(vl);
2265
2266                mPvsErrorWidget = new QListWidget(vbox);
2267                vbox->layout()->addWidget(mPvsErrorWidget);
2268
2269                connect(mPvsErrorWidget,
2270                        SIGNAL(doubleClicked(const QModelIndex &)),
2271                        this,
2272                        SLOT(PvsErrorClicked(const QModelIndex &)));
2273
2274                button = new QPushButton("Next Error Frame", vbox);
2275                vbox->layout()->addWidget(button);
2276                connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void)));
2277        }
2278       
2279        //connect(button, SIGNAL(clicked(void)), SLOT(StoreStatistics(void)));
2280       
2281        //////////////////////////////////////////
2282
2283
2284        setWindowTitle("Preprocessor Control Widget");
2285        adjustSize();
2286}
2287
2288
2289
2290
2291void
2292QtRendererControlWidget::FocusNextPvsErrorFrame(void)
2293{}
2294
2295void
2296QtRendererControlWidget::UpdatePvsErrorItem(int row,
2297                                                                                        GlRendererBuffer::PvsErrorEntry &pvsErrorEntry)
2298{
2299
2300        QListWidgetItem *i = mPvsErrorWidget->item(row);
2301        QString s;
2302        s.sprintf("%5.5f", pvsErrorEntry.mError);
2303        if (i) {
2304                i->setText(s);
2305        } else {
2306                new QListWidgetItem(s, mPvsErrorWidget);
2307        }
2308        mPvsErrorWidget->update();
2309}
2310
2311
2312
2313
2314/*********************************************************************/
2315/*                   QtGlDebuggerWidget implementation               */
2316/*********************************************************************/
2317
2318
2319QtGlDebuggerWidget::QtGlDebuggerWidget(QtGlRendererBuffer *buf, QWidget *parent)
2320: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf)
2321{
2322        // create the pbuffer
2323        //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this);
2324        timerId = startTimer(20);
2325        setWindowTitle(("OpenGL pbuffers"));
2326}
2327
2328
2329QtGlDebuggerWidget::~QtGlDebuggerWidget()
2330{
2331        mRenderBuffer->releaseFromDynamicTexture();
2332        glDeleteTextures(1, &dynamicTexture);
2333
2334        DEL_PTR(mRenderBuffer);
2335}
2336
2337
2338void QtGlDebuggerWidget::initializeGL()
2339{
2340        glMatrixMode(GL_PROJECTION);
2341        glLoadIdentity();
2342
2343        glFrustum(-1, 1, -1, 1, 10, 100);
2344        glTranslatef(-0.5f, -0.5f, -0.5f);
2345        glTranslatef(0.0f, 0.0f, -15.0f);
2346        glMatrixMode(GL_MODELVIEW);
2347
2348        glEnable(GL_CULL_FACE);
2349        initCommon();
2350        initPbuffer();
2351
2352}
2353
2354
2355void QtGlDebuggerWidget::resizeGL(int w, int h)
2356{
2357        glViewport(0, 0, w, h);
2358}
2359
2360
2361void QtGlDebuggerWidget::paintGL()
2362{
2363        // draw a spinning cube into the pbuffer..
2364        mRenderBuffer->makeCurrent();
2365
2366        BeamSampleStatistics stats;
2367        mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats);
2368
2369        glFlush();
2370
2371        // rendering directly to a texture is not supported on X11, unfortunately
2372        mRenderBuffer->updateDynamicTexture(dynamicTexture);
2373
2374        // and use the pbuffer contents as a texture when rendering the
2375        // background and the bouncing cubes
2376        makeCurrent();
2377        glBindTexture(GL_TEXTURE_2D, dynamicTexture);
2378        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2379
2380        // draw the background
2381        glMatrixMode(GL_MODELVIEW);
2382        glPushMatrix();
2383        glLoadIdentity();
2384        glMatrixMode(GL_PROJECTION);
2385        glPushMatrix();
2386        glLoadIdentity();
2387
2388        glPopMatrix();
2389        glMatrixMode(GL_MODELVIEW);
2390        glPopMatrix();
2391}
2392
2393
2394void QtGlDebuggerWidget::initPbuffer()
2395{
2396        // set up the pbuffer context
2397        mRenderBuffer->makeCurrent();
2398       
2399        // generate a texture that has the same size/format as the pbuffer
2400        dynamicTexture = mRenderBuffer->generateDynamicTexture();
2401
2402        // bind the dynamic texture to the pbuffer - this is a no-op under X11
2403        mRenderBuffer->bindToDynamicTexture(dynamicTexture);
2404        makeCurrent();
2405}
2406
2407
2408void QtGlDebuggerWidget::initCommon()
2409{
2410        glEnable(GL_TEXTURE_2D);
2411        glEnable(GL_DEPTH_TEST);
2412
2413        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
2414}
2415
2416
2417void QtGlRendererWidget::_RenderColoredPvs()
2418{
2419        // note: could be done more efficiently using color buffers
2420        mPvsSize = mPvsCache.mPvs.GetSize();
2421
2422        ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
2423
2424        PvsData pvsData;
2425
2426        while (it.HasMoreEntries())
2427        {
2428                Intersectable *object = it.Next(pvsData);
2429
2430                RgbColor color;
2431
2432                //float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f
2433                // glColor3f(visibility, 0.0f, 0.0f);
2434                //cerr << "sumpdf: " << pvsData.mSumPdf << endl;
2435                if (mUseRandomColorPerPvsObject)
2436                {
2437                        KdIntersectable *kdint = static_cast<KdIntersectable *>(object);
2438
2439                        if (kdint->mGenericIdx == -1)
2440                        {
2441                                kdint->mGenericIdx = (int)mColors.size();
2442                                mColors.push_back(RandomColor());
2443                        }
2444                        color = mColors[kdint->mGenericIdx];
2445                }
2446                else
2447                {
2448                        color = RainbowColorMapping(mTransferFunction * log10(pvsData.mSumPdf + 1));
2449                }
2450
2451                glColor3f(color.r, color.g, color.b);
2452
2453                mUseForcedColors = true;
2454                RenderIntersectable(object);
2455                mUseForcedColors = false;
2456        }
2457}
2458
2459void
2460QtGlRendererWidget::UpdateDynamicObjects()
2461{
2462  preprocessor->ScheduleUpdateDynamicObjects();
2463 
2464}
2465
2466}
Note: See TracBrowser for help on using the repository browser.