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 |
|
---|
10 | namespace GtpVisibilityPreprocessor
|
---|
11 | {
|
---|
12 |
|
---|
13 |
|
---|
14 | GvsPreprocessor::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 |
|
---|
31 | const 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 |
|
---|
40 | int 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 | */
|
---|
60 | static 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 |
|
---|
100 | int 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 |
|
---|
129 | int GvsPreprocessor::ReverseSampling(const VssRay &oldRay)
|
---|
130 | {
|
---|
131 | cout << "r" << endl;
|
---|
132 | // TODO
|
---|
133 | return 1;
|
---|
134 | }
|
---|
135 |
|
---|
136 |
|
---|
137 | int 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 |
|
---|
159 | void 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 |
|
---|
172 | int 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 |
|
---|
191 | int 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 |
|
---|
208 | bool 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 | }
|
---|