source: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp @ 1981

Revision 1981, 19.0 KB checked in by mattausch, 17 years ago (diff)
  • Property svn:executable set to *
RevLine 
[1460]1#include "Environment.h"
2#include "GvsPreprocessor.h"
3#include "GlRenderer.h"
[1473]4#include "VssRay.h"
5#include "ViewCellsManager.h"
[1486]6#include "Triangle3.h"
[1489]7#include "IntersectableWrapper.h"
[1500]8#include "Plane3.h"
[1521]9#include "RayCaster.h"
[1522]10#include "Exporter.h"
[1545]11#include "SamplingStrategy.h"
[1460]12
[1473]13
[1460]14namespace GtpVisibilityPreprocessor
15{
16 
[1935]17#define GVS_DEBUG 1
[1934]18
[1522]19struct VizStruct
20{
21        Polygon3 *enlargedTriangle;
22        Triangle3 originalTriangle;
23        VssRay *ray;
24};
[1460]25
[1522]26static vector<VizStruct> vizContainer;
27
[1533]28GvsPreprocessor::GvsPreprocessor():
[1545]29Preprocessor(),
30//mSamplingType(SamplingStrategy::DIRECTION_BASED_DISTRIBUTION),
[1934]31mSamplingType(SamplingStrategy::DIRECTION_BOX_BASED_DISTRIBUTION)
[1460]32{
[1486]33        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.totalSamples", mTotalSamples);
34        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.initialSamples", mInitialSamples);
35        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.samplesPerPass", mSamplesPerPass);
36        Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.epsilon", mEps);
[1500]37        Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.threshold", mThreshold);   
[1976]38        Environment::GetSingleton()->GetBoolValue("GvsPreprocessor.UsePerViewCellSampling", mPerViewCell);
[1473]39
[1934]40        char gvsStatsLog[100];
41        Environment::GetSingleton()->GetStringValue("GvsPreprocessor.stats", gvsStatsLog);
42        mGvsStatsStream.open(gvsStatsLog);
43
[1486]44        Debug << "Gvs preprocessor options" << endl;
45        Debug << "number of total samples: " << mTotalSamples << endl;
46        Debug << "number of initial samples: " << mInitialSamples << endl;
47        Debug << "number of samples per pass: " << mSamplesPerPass << endl;
[1501]48        Debug << "threshold: " << mThreshold << endl;
[1934]49        Debug << "epsilon: " << mEps << endl;
50        Debug << "stats: " << gvsStatsLog << endl;
[1486]51
[1934]52        if (0)
53                mOnlyRandomSampling = true;
54        else
55                mOnlyRandomSampling = false;
56
57        //mGvsStatsStream.open("gvspreprocessor.log");
58        mGvsStats.Reset();
[1460]59}
60
[1473]61
[1500]62bool GvsPreprocessor::CheckDiscontinuity(const VssRay &currentRay,
63                                                                                 const Triangle3 &hitTriangle,
64                                                                                 const VssRay &oldRay)
[1460]65{
[1932]66        // the predicted hitpoint: we expect to hit the same mesh again
67        const Vector3 predictedHit = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay);
68
69        const float predictedLen = Magnitude(predictedHit - currentRay.mOrigin);
70        const float len = Magnitude(currentRay.mTermination - currentRay.mOrigin);
71       
72        // distance large => this is likely to be a discontinuity
[1933]73#if 1
[1932]74        if ((predictedLen - len) > mThreshold)
[1933]75#else // rather use relative distance
76        if ((predictedLen / len) > mThreshold)
77#endif
[1500]78        {
[1934]79                //cout << "r";
[1933]80                // apply reverse sampling to find the gap
[1500]81                VssRay *newRay = ReverseSampling(currentRay, hitTriangle, oldRay);
[1933]82
83                if (!newRay)
84                        return false;
85
[1572]86                // set flag for visualization
[1571]87                newRay->mFlags |= VssRay::ReverseSample;
[1580]88               
[1977]89                // if ray is not further processed => delete ray
[1521]90                if (!HandleRay(newRay))
[1933]91                {
[1521]92                        delete newRay;
[1933]93                }
[1934]94                else if (GVS_DEBUG && (mVssRays.size() < 9))
[1933]95                {
96                        mVssRays.push_back(new VssRay(oldRay));
97                        mVssRays.push_back(new VssRay(currentRay));
98                        mVssRays.push_back(new VssRay(*newRay));
99                }
100
[1500]101                return true;
102        }
103
[1486]104        return false;
105}
[1473]106
[1486]107
[1521]108bool GvsPreprocessor::HandleRay(VssRay *vssRay)
[1486]109{
[1932]110        // compute the contribution to the view cells
[1934]111        const bool storeRaysForViz = GVS_DEBUG;
[1933]112
[1977]113        if (!mPerViewCell)
114        {
115                mViewCellsManager->ComputeSampleContribution(*vssRay,
116                                                                                                         true,
117                                                                                                         storeRaysForViz);
118        }
119        else
120        {
121                mViewCellsManager->ComputeSampleContribution(*vssRay,
122                                                                                                         true,
123                                                                                                         mCurrentViewCell);
124        }
[1932]125
[1528]126        // some pvs contribution for this ray?
[1977]127        if (!vssRay->mPvsContribution)
128                return false;
129
130        // add new ray to ray queue
131        mRayQueue.push(vssRay);
132
133        if (storeRaysForViz)
[1528]134        {
[1977]135                VssRay *nray = new VssRay(*vssRay);
136                nray->mFlags = vssRay->mFlags;
[1570]137
[1977]138                // store ray in contributing view cell
139                ViewCellContainer::const_iterator vit, vit_end = vssRay->mViewCells.end();
140                for (vit = vssRay->mViewCells.begin(); vit != vit_end; ++ vit)
141                {                       
142                        (*vit)->GetOrCreateRays()->push_back(nray);                             
[1570]143                }
[1977]144        }
[1932]145
[1977]146        ++ mGvsStats.mPassContribution;
[1533]147
[1977]148        return true;
[1460]149}
150
[1500]151
152/** Creates 3 new vertices for triangle vertex with specified index.
[1489]153*/
[1932]154void GvsPreprocessor::CreateDisplacedVertices(VertexContainer &vertices,
155                                                                                          const Triangle3 &hitTriangle,
156                                                                                          const VssRay &ray,
157                                                                                          const int index) const
[1460]158{
[1486]159        const int indexU = (index + 1) % 3;
160        const int indexL = (index == 0) ? 2 : index - 1;
161
[1524]162        const Vector3 a = hitTriangle.mVertices[index] - ray.GetOrigin();
[1486]163        const Vector3 b = hitTriangle.mVertices[indexU] - hitTriangle.mVertices[index];
164        const Vector3 c = hitTriangle.mVertices[index] - hitTriangle.mVertices[indexL];
[1492]165       
[1533]166        const float len = Magnitude(a);
[1932]167       
[1523]168        const Vector3 dir1 = Normalize(CrossProd(a, b)); //N((pi-xp)×(pi+1- pi));
169        const Vector3 dir2 = Normalize(CrossProd(a, c)); // N((pi-xp)×(pi- pi-1))
[1524]170        const Vector3 dir3 = DotProd(dir2, dir1) > 0 ? // N((pi-xp)×di,i-1+di,i+1×(pi-xp))
171                Normalize(dir2 + dir1) : Normalize(CrossProd(a, dir1) + CrossProd(dir2, a));
[1492]172
[1486]173        // compute the new three hit points
[1500]174        // pi, i + 1:  pi+ e·|pi-xp|·di, j
[1932]175        const Vector3 pt1 = hitTriangle.mVertices[index] + mEps * len * dir1;
[1500]176        // pi, i - 1:  pi+ e·|pi-xp|·di, j
[1932]177    const Vector3 pt2 = hitTriangle.mVertices[index] + mEps * len * dir2;
[1500]178        // pi, i:  pi+ e·|pi-xp|·di, j
[1932]179        const Vector3 pt3 = hitTriangle.mVertices[index] + mEps * len * dir3;
[1489]180       
[1524]181        vertices.push_back(pt2);
182        vertices.push_back(pt3);
[1500]183        vertices.push_back(pt1);
[1489]184}
185
186
[1500]187void GvsPreprocessor::EnlargeTriangle(VertexContainer &vertices,
188                                                                          const Triangle3 &hitTriangle,
[1932]189                                                                          const VssRay &ray) const
[1500]190{
[1932]191        CreateDisplacedVertices(vertices, hitTriangle, ray, 0);
192        CreateDisplacedVertices(vertices, hitTriangle, ray, 1);
193        CreateDisplacedVertices(vertices, hitTriangle, ray, 2);
[1500]194}
[1492]195
[1500]196
[1932]197Vector3 GvsPreprocessor::CalcPredictedHitPoint(const VssRay &newRay,
198                                                                                           const Triangle3 &hitTriangle,
199                                                                                           const VssRay &oldRay) const
[1489]200{
[1932]201        // find the intersection of the plane induced by the
202        // hit triangle with the new ray
[1500]203        Plane3 plane(hitTriangle.GetNormal(), hitTriangle.mVertices[0]);
204
205        const Vector3 hitPt =
206                plane.FindIntersection(newRay.mTermination, newRay.mOrigin);
207       
208        return hitPt;
209}
210
211
212static bool EqualVisibility(const VssRay &a, const VssRay &b)
213{
214        return a.mTerminationObject == b.mTerminationObject;
215}
216
217
218int GvsPreprocessor::SubdivideEdge(const Triangle3 &hitTriangle,
219                                                                   const Vector3 &p1,
220                                                                   const Vector3 &p2,
[1932]221                                                                   const VssRay &ray1,
222                                                                   const VssRay &ray2,
[1500]223                                                                   const VssRay &oldRay)
224{
[1932]225        CheckDiscontinuity(ray1, hitTriangle, oldRay);
226        CheckDiscontinuity(ray2, hitTriangle, oldRay);
[1500]227
[1932]228        if (EqualVisibility(ray1, ray2) || (Magnitude(p1 - p2) <= mEps))
[1500]229        {
[1533]230                return 0;
[1500]231        }
232        else
233        {
[1932]234                // the new subdivision point
[1500]235                const Vector3 p = (p1 + p2) * 0.5f;
[1932]236       
237                //cout << "tobj " << ray1.mTerminationObject << " " << ray2.mTerminationObject << " " << p1 << " " << p2 << endl;
238                //cout << "term " << ray1.mTermination << " " << ray2.mTermination << endl;
239
240                // cast ray into the new point
[1883]241                SimpleRay sray(oldRay.mOrigin, p - oldRay.mOrigin, SamplingStrategy::GVS, 1.0f);
[1521]242       
[1932]243                VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox());
244
[1551]245                if (!newRay) return 0;
[1580]246
247                newRay->mFlags |= VssRay::BorderSample;
248
249                // add new ray to queue
[1522]250                const bool enqueued = HandleRay(newRay);
[1521]251               
[1566]252                // subdivide further
[1932]253                const int samples1 = SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay);
254                const int samples2 = SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay);
255                       
256                // this ray will not be further processed
[1522]257                if (!enqueued)
[1521]258                        delete newRay;
[1533]259               
[1932]260                return samples1 + samples2 + 1;
[1500]261        }
262}
263
264
265int GvsPreprocessor::AdaptiveBorderSampling(const VssRay &currentRay)
266{
267        Intersectable *tObj = currentRay.mTerminationObject;
[1486]268        Triangle3 hitTriangle;
[1489]269
270        // other types not implemented yet
271        if (tObj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
272        {
273                hitTriangle = dynamic_cast<TriangleIntersectable *>(tObj)->GetItem();
274        }
[1522]275        else
276        {
277                cout << "not yet implemented" << endl;
278        }
[1489]279
[1500]280        VertexContainer enlargedTriangle;
281       
282        /// create 3 new hit points for each vertex
283        EnlargeTriangle(enlargedTriangle, hitTriangle, currentRay);
284       
285        /// create rays from sample points and handle them
[1492]286        SimpleRayContainer simpleRays;
287        simpleRays.reserve(9);
[1486]288
[1932]289        //cout << "currentRay: " << currentRay.mOrigin << " dir: " << currentRay.GetDir() << endl;
290
[1500]291        VertexContainer::const_iterator vit, vit_end = enlargedTriangle.end();
[1486]292
[1500]293        for (vit = enlargedTriangle.begin(); vit != vit_end; ++ vit)
294        {
295                const Vector3 rayDir = (*vit) - currentRay.GetOrigin();
[1883]296                SimpleRay sr(currentRay.GetOrigin(), rayDir, SamplingStrategy::GVS, 1.0f);
[1528]297                simpleRays.AddRay(sr);
[1932]298
299                //cout << "new: " << sr.mOrigin << " dist: " << sr.mDirection << endl;
[1500]300        }
[1522]301
[1566]302        if (0)
303        {
[1932]304                // visualize enlarged triangles
[1566]305                VizStruct dummy;
306                dummy.enlargedTriangle = new Polygon3(enlargedTriangle);
307                dummy.originalTriangle = hitTriangle;
308                vizContainer.push_back(dummy);
309        }
310
[1524]311        // cast rays to triangle vertices and determine visibility
[1489]312        VssRayContainer vssRays;
[1533]313
[1932]314        // don't cast double rays as we need only the forward rays
315        const bool castDoubleRays = false;
316        // cannot prune invalid rays because we have to
317        // compare adjacent  rays.
318        const bool pruneInvalidRays = false;
319
320        CastRays(simpleRays, vssRays, castDoubleRays, pruneInvalidRays);
321
[1580]322        // set flags
323        VssRayContainer::const_iterator rit, rit_end = vssRays.end();
324        for (rit = vssRays.begin(); rit != rit_end; ++ rit)
[1595]325        {
[1580]326                (*rit)->mFlags |= VssRay::BorderSample;
327        }
[1595]328
[1932]329        // handle rays
[1492]330        EnqueueRays(vssRays);
[1528]331       
[1524]332        const int n = (int)enlargedTriangle.size();
[1533]333        int castRays = (int)vssRays.size();
[1571]334
[1500]335    // recursivly subdivide each edge
[1932]336        for (int i = 0; i < n; ++ i)
[1500]337        {
[1932]338                castRays += SubdivideEdge(hitTriangle,
339                                                                  enlargedTriangle[i],
340                                                                  enlargedTriangle[(i + 1) % n],
341                                                                  *vssRays[i],
342                                                                  *vssRays[(i + 1) % n],
343                                                                  currentRay);
[1500]344        }
[1533]345
[1934]346        mGvsStats.mBorderSamples += castRays;
[1932]347
[1533]348        return castRays;
[1473]349}
350
351
[1933]352/*Vector3 GvsPreprocessor::GetPassingPoint(const VssRay &currentRay,
[1932]353                                                                                 const Triangle3 &hitTriangle,
354                                                                                 const VssRay &oldRay) const
[1473]355{
[1932]356        //-- intersect triangle plane with plane spanned by current samples
[1500]357        Plane3 plane(currentRay.GetOrigin(), currentRay.GetTermination(), oldRay.GetTermination());
358        Plane3 triPlane(hitTriangle.GetNormal(), hitTriangle.mVertices[0]);
359
360        SimpleRay intersectLine = GetPlaneIntersection(plane, triPlane);
361
362        // Evaluate new hitpoint just outside the triangle
363        const float factor = 0.95f;
[1932]364        const float t = triPlane.FindT(intersectLine);
[1500]365        const Vector3 newPoint = intersectLine.mOrigin + t * factor * intersectLine.mDirection;
366
367        return newPoint;
[1933]368}*/
369
370
371Vector3 GvsPreprocessor::GetPassingPoint(const VssRay &currentRay,
372                                                                                 const Triangle3 &occluder,
373                                                                                 const VssRay &oldRay) const
374{
375        //-- The plane p = (xp, hit(x), hit(xold)) is intersected
376        //-- with the newly found occluder (xold is the previous ray from
377        //-- which x was generated). On the intersecting line, we select a point
378        //-- pnew which lies just outside of the new triangle so the ray
379        //-- just passes through the gap
380
381        const Plane3 plane(currentRay.GetOrigin(),
382                                           currentRay.GetTermination(),
383                                           oldRay.GetTermination());
384       
385        Vector3 pt1, pt2;
386
387        const bool intersects = occluder.GetPlaneIntersection(plane, pt1, pt2);
388
389        if (!intersects)
390                cerr << "big error!! no intersection" << endl;
391
392        // get the intersection point on the old ray
393        const Plane3 triPlane(occluder.GetNormal(), occluder.mVertices[0]);
394
395        const float t = triPlane.FindT(oldRay.mOrigin, oldRay.mTermination);
396        const Vector3 pt3 = oldRay.mOrigin + t * (oldRay.mTermination - oldRay.mOrigin);
397
398        // Evaluate new hitpoint just outside the triangle
399        Vector3 newPoint;
400
401        const float eps = mEps;
402        // the point is chosen to be on the side closer to the original ray
403        if (Distance(pt1, pt3) < Distance(pt2, pt3))
404        {
405                newPoint = pt1 + eps * (pt1 - pt2);
406        }       
407        else
408        {
409                newPoint = pt2 + eps * (pt2 - pt1);
410        }
411
[1934]412        //cout << "passing point: " << newPoint << endl << endl;
[1933]413        return newPoint;
[1500]414}
415
416
417VssRay *GvsPreprocessor::ReverseSampling(const VssRay &currentRay,
418                                                                                 const Triangle3 &hitTriangle,
419                                                                                 const VssRay &oldRay)
420{
[1933]421        // get triangle occluding the path to the hit mesh
422        Triangle3 occluder;
423        Intersectable *tObj = currentRay.mTerminationObject;
[1934]424
[1933]425        // q: why can this happen?
426        if (!tObj)
427                return NULL;
428
429        // other types not implemented yet
430        if (tObj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
431                occluder = dynamic_cast<TriangleIntersectable *>(tObj)->GetItem();
432        else
433                cout << "not yet implemented" << endl;
434       
435        // get a point which is passing just outside of the occluder
436    const Vector3 newPoint = GetPassingPoint(currentRay, occluder, oldRay);
[1500]437        const Vector3 predicted = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay);
438
[1932]439        //-- Construct the mutated ray with xnew,
440        //-- dir = predicted(x)- pnew as direction vector
[1933]441        const Vector3 newDir = predicted - newPoint;
[1932]442
[1933]443        // take xnew, p = intersect(viewcell, line(pnew, predicted(x)) as origin ?
[1500]444        // difficult to say!!
[1935]445        const float offset = 0.5f;
446        const Vector3 newOrigin = newPoint - newDir * offset;
[1500]447
[1981]448        static Ray ray(newOrigin, newDir, Ray::LOCAL_RAY);
449        ray.Precompute();
450
451        // check if ray intersects view cell
452        if (mPerViewCell && !mCurrentViewCell->CastRay(ray))
453                return NULL;
454
[1933]455        const SimpleRay simpleRay(newOrigin, newDir, SamplingStrategy::GVS, 1.0f);
[1571]456
[1933]457        VssRay *reverseRay =
458                mRayCaster->CastRay(simpleRay, mViewCellsManager->GetViewSpaceBox());
459
[1934]460    ++ mGvsStats.mReverseSamples;
[1933]461
462        return reverseRay;
[1473]463}
464
[1489]465
466int GvsPreprocessor::CastInitialSamples(const int numSamples,
467                                                                                const int sampleType)
468{       
[1473]469        const long startTime = GetTime();
[1595]470
[1489]471        // generate simple rays
472        SimpleRayContainer simpleRays;
473        GenerateRays(numSamples, sampleType, simpleRays);
[1528]474
[1489]475        // generate vss rays
[1473]476        VssRayContainer samples;
[1520]477        CastRays(simpleRays, samples, true);
[1489]478        // add to ray queue
[1492]479        EnqueueRays(samples);
[1533]480
[1545]481        //Debug << "generated " <<  numSamples << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
[1489]482        return (int)samples.size();
483}
484
485
[1500]486void GvsPreprocessor::EnqueueRays(VssRayContainer &samples)
[1489]487{
[1486]488        // add samples to ray queue
[1473]489        VssRayContainer::const_iterator vit, vit_end = samples.end();
[1576]490        for (vit = samples.begin(); vit != vit_end; ++ vit)
[1473]491        {
[1521]492                HandleRay(*vit);
[1460]493        }
494}
495
[1473]496
[1486]497int GvsPreprocessor::Pass()
[1460]498{
[1528]499        // reset samples
[1533]500        int castSamples = 0;
[1934]501        mGvsStats.mPassContribution = 0;
[1545]502
[1533]503        while (castSamples < mSamplesPerPass)
[1528]504        {       
[1473]505                // Ray queue empty =>
[1545]506                // cast a number of uniform samples to fill ray queue
507                castSamples += CastInitialSamples(mInitialSamples, mSamplingType);
[1934]508
509                if (!mOnlyRandomSampling)
510                        castSamples += ProcessQueue();
[1473]511        }
512
[1934]513        mGvsStats.mTotalContribution += mGvsStats.mPassContribution;
[1533]514        return castSamples;
[1460]515}
516
[1473]517
[1489]518int GvsPreprocessor::ProcessQueue()
[1460]519{
[1473]520        int castSamples = 0;
[1934]521        ++ mGvsStats.mGvsPass;
[1473]522
523        while (!mRayQueue.empty())
524        {
525                // handle next ray
[1500]526                VssRay *ray = mRayQueue.top();
[1473]527                mRayQueue.pop();
[1545]528
[1501]529                castSamples += AdaptiveBorderSampling(*ray);
[1521]530                delete ray;
[1460]531        }
[1528]532       
[1473]533        return castSamples;
[1460]534}
535
536
[1489]537bool GvsPreprocessor::ComputeVisibility()
[1460]538{
[1533]539        cout << "Gvs Preprocessor started\n" << flush;
[1545]540        const long startTime = GetTime();
[1533]541
[1473]542        Randomize(0);
[1545]543       
[1934]544        mGvsStats.Reset();
545        mGvsStats.Start();
[1545]546
[1486]547        if (!mLoadViewCells)
[1563]548        {       
549                /// construct the view cells from the scratch
550                ConstructViewCells();
[1580]551                // reset pvs already gathered during view cells construction
552                mViewCellsManager->ResetPvs();
[1563]553                cout << "finished view cell construction" << endl;
[1486]554        }
[1571]555        else if (0)
[1563]556        {       
[1551]557                //-- test successful view cells loading by exporting them again
558                VssRayContainer dummies;
559                mViewCellsManager->Visualize(mObjects, dummies);
[1563]560                mViewCellsManager->ExportViewCells("test.xml.gz", mViewCellsManager->GetExportPvs(), mObjects);
[1551]561        }
[1460]562
[1934]563        mGvsStats.Stop();
564        mGvsStats.Print(mGvsStatsStream);
565
566        while (mGvsStats.mTotalSamples < mTotalSamples)
[1473]567        {
[1934]568                ++ mPass;
569
570                mGvsStats.mTotalSamples += Pass();
[1528]571                               
[1500]572                ////////
573                //-- stats
[1932]574
[1934]575                cout << "\nPass " << mPass << " #samples: " << mGvsStats.mTotalSamples << " of " << mTotalSamples << endl;
576                mGvsStats.mPass = mPass;
577                mGvsStats.Stop();
578                mGvsStats.Print(mGvsStatsStream);
579                //mViewCellsManager->PrintPvsStatistics(mGvsStats);
[1460]580
[1934]581                if (GVS_DEBUG)
582                {
583                        char str[64]; sprintf(str, "tmp/pass%04d-", mPass);
[1570]584               
[1934]585                        // visualization
586                        if (mGvsStats.mPassContribution > 0)
587                        {
588                                const bool exportRays = true;
589                                const bool exportPvs = true;
[1571]590
[1934]591                                mViewCellsManager->ExportSingleViewCells(mObjects,
592                                                                                                                 10,
593                                                                                                                 false,
594                                                                                                                 exportPvs,
595                                                                                                                 exportRays,
596                                                                                                                 1000,
597                                                                                                                 str);
598                        }
[1571]599
[1934]600                        // remove pass samples
601                        ViewCellContainer::const_iterator vit, vit_end = mViewCellsManager->GetViewCells().end();
602                        for (vit = mViewCellsManager->GetViewCells().begin(); vit != vit_end; ++ vit)
603                        {
604                                (*vit)->DelRayRefs();
605                        }
[1570]606                }
607
[1473]608                // ComputeRenderError();
[1460]609        }
610
[1934]611        cout << "cast " << 2 * mGvsStats.mTotalSamples / (1e3f * TimeDiff(startTime, GetTime())) << "M rays/s" << endl;
[1545]612
[1934]613        if (GVS_DEBUG)
614        {
615                Visualize();
616                CLEAR_CONTAINER(mVssRays);
617        }
618
[1473]619        return true;
[1460]620}
621
[1522]622
623void GvsPreprocessor::Visualize()
624{
625        Exporter *exporter = Exporter::GetExporter("gvs.wrl");
626
627        if (!exporter)
628                return;
629       
630        vector<VizStruct>::const_iterator vit, vit_end = vizContainer.end();
631        for (vit = vizContainer.begin(); vit != vit_end; ++ vit)
632        {
[1524]633                exporter->SetWireframe();
[1522]634                exporter->ExportPolygon((*vit).enlargedTriangle);
635                //Material m;
[1524]636                exporter->SetFilled();
637                Polygon3 poly = Polygon3((*vit).originalTriangle);
638                exporter->ExportPolygon(&poly);
[1522]639        }
640
[1933]641        VssRayContainer::const_iterator rit, rit_end = mVssRays.end();
642        for (rit = mVssRays.begin(); rit != rit_end; ++ rit)
643        {
644                Intersectable *obj = (*rit)->mTerminationObject;
645                exporter->ExportIntersectable(obj);
646        }
647
648        VssRayContainer vcRays, vcRays2, vcRays3;
649
650        // prepare some rays for output
651        for (rit = mVssRays.begin(); rit != rit_end; ++ rit)
652        {
653                const float p = RandomValue(0.0f, (float)mVssRays.size());
654                if (1)//(p < raysOut)
655                {
656                        if ((*rit)->mFlags & VssRay::BorderSample)
657                        {
658                                vcRays.push_back(*rit);
659                        }
660                        else if ((*rit)->mFlags & VssRay::ReverseSample)
661                        {
662                                vcRays2.push_back(*rit);
663                        }
664                        else
665                        {
666                                vcRays3.push_back(*rit);
667                        }       
668                }
669        }
670
671        exporter->ExportRays(vcRays, RgbColor(1, 0, 0));
672        exporter->ExportRays(vcRays2, RgbColor(0, 1, 0));
673        exporter->ExportRays(vcRays3, RgbColor(1, 1, 1));
674
675        //exporter->ExportRays(mVssRays);
[1522]676        delete exporter;
[1460]677}
[1522]678
[1934]679
680void GvsStatistics::Print(ostream &app) const
681{
682        app << "#Pass\n" << mPass << endl;
683        app << "#Time\n" << Time() << endl;
684        app << "#TotalSamples\n" << mTotalSamples << endl;
685        app << "#ScDiff\n" << mPassContribution << endl;
686        app     << "#SamplesContri\n" << mTotalContribution << endl;
687        app << "#ReverseSamples\n" << mReverseSamples << endl;
688        app << "#BorderSamples\n" << mBorderSamples << endl;           
689        app << "#GvsRuns\n" << mGvsPass << endl;
[1883]690}
[1934]691
692
693}
Note: See TracBrowser for help on using the repository browser.