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

Revision 1492, 6.5 KB checked in by mattausch, 18 years ago (diff)
  • Property svn:executable set to *
Line 
1#include "Environment.h"
2#include "GvsPreprocessor.h"
3#include "GlRenderer.h"
4#include "VssRay.h"
5#include "ViewCellsManager.h"
6#include "Triangle3.h"
7#include "IntersectableWrapper.h"
8
9
10namespace GtpVisibilityPreprocessor
11{
12 
13
14GvsPreprocessor::GvsPreprocessor(): Preprocessor(), mSamplingType(0)
15{
16        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.totalSamples", mTotalSamples);
17        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.initialSamples", mInitialSamples);
18        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.samplesPerPass", mSamplesPerPass);
19        Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.epsilon", mEps);
20               
21
22        Debug << "Gvs preprocessor options" << endl;
23        Debug << "number of total samples: " << mTotalSamples << endl;
24        Debug << "number of initial samples: " << mInitialSamples << endl;
25        Debug << "number of samples per pass: " << mSamplesPerPass << endl;
26
27        mStats.open("gvspreprocessor.log");
28}
29
30
31const bool GvsPreprocessor::DiscontinuityFound(const VssRay &ray,
32                                                                                           const VssRay &oldRay) const
33{
34        //|predicted(x)-xp|-|hit(x)-xp| > ?,
35    //const Plane3 plane = tri->GetPlane();
36        return false;
37}
38
39
40int GvsPreprocessor::HandleRay(const GvsRayInfo &gvsRay)
41{
42        VssRay *ray = gvsRay.mRay;
43
44        if (!mViewCellsManager->ComputeSampleContribution(*ray, true, false))
45                return 1;
46
47        if (gvsRay.mFoundDiscontinuity)
48        {
49                return ReverseSampling(*ray);
50        }
51        else
52        {
53                return AdaptiveBorderSampling(*ray);
54        }
55}
56
57/** Hepler function for adaptive border sampling. It finds
58        new sample points around a triangle in a eps environment
59*/
60static void CreateNewRays(SimpleRayContainer &simpleRays,
61                                                  const Triangle3 &hitTriangle,
62                                                  const VssRay &ray,
63                                                  const int index,
64                                                  const float eps)
65{
66        const int indexU = (index + 1) % 3;
67        const int indexL = (index == 0) ? 2 : index - 1;
68
69        const Vector3 a = hitTriangle.mVertices[index] - ray.GetDir();
70        const Vector3 b = hitTriangle.mVertices[indexU] - hitTriangle.mVertices[index];
71        const Vector3 c = hitTriangle.mVertices[index] - hitTriangle.mVertices[indexL];
72       
73        const float len = Magnitude(a);
74
75        const Vector3 dir1 = CrossProd(a, b); //N((pi-xp)×(pi+1- pi));
76        const Vector3 dir2 = CrossProd(a, c); // N((pi-xp)×(pi- pi-1))
77        const Vector3 dir3 = DotProd(dir1, dir2) > 0 ?
78                Normalize(dir2 + dir1) : Normalize(CrossProd(a, dir2) + CrossProd(dir1, a)); // N((pi-xp)×di,i-1+di,i+1×(pi-xp))
79
80        // compute the new three hit points
81        // pi, i + 1
82        const Vector3 pt1 = hitTriangle.mVertices[index] + eps * len * dir1; //pi+ e·|pi-xp|·di, j
83        // pi, i - 1
84    const Vector3 pt2 = hitTriangle.mVertices[index] + eps * len * dir2; //pi+ e·|pi-xp|·di, j
85        // pi, i
86        const Vector3 pt3 = hitTriangle.mVertices[index] + eps * len * dir3; //pi+ e·|pi-xp|·di, j
87       
88        /// create simple rays and store them in container
89        Vector3 rayDir;
90        rayDir = Normalize(pt1 - ray.GetOrigin());
91        simpleRays.push_back(SimpleRay(rayDir, ray.GetOrigin()));
92        rayDir = Normalize(pt2 - ray.GetOrigin());
93        simpleRays.push_back(SimpleRay(rayDir, ray.GetOrigin()));
94        rayDir = Normalize(pt3 - ray.GetOrigin());
95        simpleRays.push_back(SimpleRay(rayDir, ray.GetOrigin()));
96}
97
98
99
100int GvsPreprocessor::AdaptiveBorderSampling(const VssRay &prevRay)
101{
102        cout << "a";
103        Intersectable *tObj = prevRay.mTerminationObject;
104        Triangle3 hitTriangle;
105
106        // other types not implemented yet
107        if (tObj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
108        {
109                hitTriangle = dynamic_cast<TriangleIntersectable *>(tObj)->GetItem();
110        }
111
112        SimpleRayContainer simpleRays;
113        simpleRays.reserve(9);
114
115        CreateNewRays(simpleRays, hitTriangle, prevRay, 0, mEps);
116        CreateNewRays(simpleRays, hitTriangle, prevRay, 1, mEps);
117        CreateNewRays(simpleRays, hitTriangle, prevRay, 2, mEps);
118
119        VssRayContainer vssRays;
120       
121        CastRays(simpleRays, vssRays);
122        // add to ray queue
123        EnqueueRays(vssRays);
124
125        return (int)vssRays.size();
126}
127
128
129int GvsPreprocessor::ReverseSampling(const VssRay &oldRay)
130{
131        cout << "r" << endl;
132        // TODO
133        return 1;
134}
135
136
137int GvsPreprocessor::CastInitialSamples(const int numSamples,
138                                                                                const int sampleType)
139{       
140        const long startTime = GetTime();
141
142        // generate simple rays
143        SimpleRayContainer simpleRays;
144        GenerateRays(numSamples, sampleType, simpleRays);
145       
146        // generate vss rays
147        VssRayContainer samples;
148        CastRays(simpleRays, samples);
149       
150        // add to ray queue
151        EnqueueRays(samples);
152
153        Debug << "generated " <<  numSamples << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
154
155        return (int)samples.size();
156}
157
158
159void GvsPreprocessor::EnqueueRays(VssRayContainer &samples, VssRay *oldRay)
160{
161        // add samples to ray queue
162        VssRayContainer::const_iterator vit, vit_end = samples.end();
163        for (vit = samples.begin(); vit != vit_end; ++ vit)
164        {
165                /// if there is no old ray, no discontinuity
166                const bool gap = oldRay ? DiscontinuityFound(*(*vit), *oldRay) : false;
167                mRayQueue.push(GvsRayInfo(*vit, gap));
168        }
169}
170
171
172int GvsPreprocessor::Pass()
173{
174        int castSamples = 0;
175        const int mSampleType = 0;
176        while (castSamples < mSamplesPerPass)
177        {
178                // Ray queue empty =>
179                // cast a number of uniform samples to fill ray Queue
180                CastInitialSamples(mInitialSamples, mSampleType);
181
182                const int gvsSamples = ProcessQueue();
183                castSamples += gvsSamples;
184                //cout << "\ncast " << castSamples << " of " << mSamplesPerPass << endl;
185        }
186
187        return castSamples;
188}
189
190
191int GvsPreprocessor::ProcessQueue()
192{
193        int castSamples = 0;
194
195        while (!mRayQueue.empty())
196        {
197                // handle next ray
198                GvsRayInfo rayInfo = mRayQueue.top();
199                mRayQueue.pop();
200               
201                castSamples += HandleRay(rayInfo);
202        }
203
204        return castSamples;
205}
206
207
208bool GvsPreprocessor::ComputeVisibility()
209{
210        Randomize(0);
211        const long startTime = GetTime();
212       
213        mViewSpaceBox = mKdTree->GetBox();
214        cout << "Gvs Preprocessor started\n" << flush;
215       
216        if (!mLoadViewCells)
217        {       /// construct the view cells from the scratch
218                ConstructViewCells(mViewSpaceBox);
219                cout << "view cells loaded" << endl;
220        }
221
222        int castSamples = 0;
223
224        while (castSamples < mTotalSamples)
225        {
226                const int passSamples = Pass();
227                castSamples += passSamples;
228               
229                /////////////
230                // -- stats
231                cout << "+";
232                cout << "\nsamples cast " << passSamples << " (=" << castSamples << " of " << mTotalSamples << ")" << endl;
233                //mVssRays.PrintStatistics(mStats);
234                mStats << "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl
235                           << "#TotalSamples\n" << castSamples << endl;
236
237                mViewCellsManager->PrintPvsStatistics(mStats);
238                // ComputeRenderError();
239        }
240
241        return true;
242}
243
244}
Note: See TracBrowser for help on using the repository browser.