source: branches/VUT/0.2/GtpVisibilityPreprocessor/src/MutualVisibility.cpp @ 209

Revision 209, 7.1 KB checked in by bittner, 19 years ago (diff)

data added

Line 
1#include <assert.h>
2#include <stack>
3using namespace std;
4#include "KdTree.h"
5#include "AxisAlignedBox3.h"
6#include "Ray.h"
7#include "MutualVisibility.h"
8#include "Exporter.h"
9#include "Mesh.h"
10#include "Triangle3.h"
11
12void
13RayShaft::Init(
14               const Rectangle3 &source,
15               const Rectangle3 &target)
16{
17  mDepth = 0;
18  mSource = source;
19  mTarget = target;
20}
21
22
23Vector3
24RayShaft::GetIntersectionPoint(const int rayIndex,
25                               const int depth) const
26{
27  Vector3 origin, direction;
28  GetRay(rayIndex, origin, direction);
29  return origin + direction*mIntersections[rayIndex][depth].mT;
30}
31
32void
33RayShaft::GetRay(const int rayIndex,
34                 Vector3 &origin,
35                 Vector3 &direction) const
36{
37 
38  assert(rayIndex < 4);
39 
40  origin = mSource.mVertices[rayIndex];
41  direction = mTarget.mVertices[rayIndex] - origin;
42}
43
44void
45MutualVisibilitySampler::PerformSplit(
46                                      const RayShaft &sample,
47                                      const bool splitSource,
48                                      const int axis,
49                                      RayShaft &sample1,
50                                      RayShaft &sample2
51                                      )
52{
53 
54
55  // split the triangles
56
57  if (splitSource) {
58    sample1.mTarget = sample.mTarget;
59    sample2.mTarget = sample.mTarget;
60    sample.mSource.Split(
61                         axis,
62                         sample1.mSource,
63                         sample2.mSource);
64  } else {
65   
66    sample1.mSource = sample.mSource;
67    sample2.mSource = sample.mSource;
68   
69    sample.mTarget.Split(
70                         axis,
71                         sample1.mTarget,
72                         sample2.mTarget);
73  }
74 
75  // split the intersections
76  switch (axis) {
77  case 0:
78    sample1.mIntersections[0] = sample.mIntersections[0];
79    sample1.mIntersections[3] = sample.mIntersections[3];
80   
81    sample2.mIntersections[1] = sample.mIntersections[1];
82    sample2.mIntersections[2] = sample.mIntersections[2];
83    break;
84
85  case 1:
86    sample1.mIntersections[0] = sample.mIntersections[0];
87    sample1.mIntersections[1] = sample.mIntersections[1];
88
89    sample2.mIntersections[2] = sample.mIntersections[2];
90    sample2.mIntersections[2] = sample.mIntersections[3];
91    break;
92  }
93
94  // the intersections for the new shaft rays will be established
95  // later
96  sample1.mDepth = sample2.mDepth = sample.mDepth+1;
97}
98
99float
100MutualVisibilitySampler::GetSpatialAngle(const RayShaft &sample,
101                                         const Vector3 &point
102                                         )
103{
104  const int sampleIndices[][2]={
105    (0,1,2),
106    (0,2,3)
107  };
108 
109  float sum = 0.0f;
110  int i;
111 
112  for (i=0; i < 2; i++) {
113    Triangle3 triangle(sample.GetIntersectionPoint(sampleIndices[i][0], 0),
114                       sample.GetIntersectionPoint(sampleIndices[i][1], 0),
115                       sample.GetIntersectionPoint(sampleIndices[i][2], 0));
116    sum += triangle.GetSpatialAngle(point);
117  }
118
119  return sum;
120}
121
122
123void
124MutualVisibilitySampler::ComputeError(RayShaft &sample)
125{
126  // evaluate minimal error which can be achieved by more precise evaluation
127  // if this is above the threshold do not proceed further
128
129  float maxAngle = GetSpatialAngle(sample,
130                                   sample.mSource.GetCenter());
131 
132  for (int i=0; i < 3; i++) {
133    float angle = GetSpatialAngle(sample,
134                                  sample.mSource.mVertices[i]);
135    if (angle > maxAngle)
136      maxAngle = angle;
137  }
138 
139  sample.mError = maxAngle;
140}
141
142
143void
144MutualVisibilitySampler::ConstructInitialSamples(
145                                                 const AxisAlignedBox3 &source,
146                                                 const AxisAlignedBox3 &target,
147                                                 vector<RayShaft *> &samples
148                                                 )
149{
150  Vector3 normal = target.Center() - source.Center();
151
152  Plane3 sourcePlane(normal, source.GetVertex(0));
153  int i;
154  for (i=1; i < 8; i++) {
155    Vector3 v = source.GetVertex(i);
156    if (sourcePlane.Distance(v) > 0)
157      sourcePlane = Plane3(normal, v);
158  }
159 
160  Plane3 targetPlane(-normal, target.GetVertex(0));
161  for (i=1; i < 8; i++) {
162    Vector3 v = target.GetVertex(i);
163    if (targetPlane.Distance(v) > 0)
164      targetPlane = Plane3(-normal, v);
165  }
166
167 
168  Vector3 xBasis = CrossProd(Vector3(0,1,0), normal);
169
170  if (Magnitude(xBasis) > 1e-6)
171    xBasis.Normalize();
172  else {
173    xBasis = CrossProd(Vector3(0,0,1), normal);
174  }
175
176  Vector3 yBasis = Normalize( CrossProd(normal, xBasis) );
177 
178  Plane3 bottomPlane(xBasis, source.Center());
179  Plane3 sidePlane(yBasis, source.Center());
180 
181  // cast rays between corresponding vertices of the boxes
182  for (i=0; i < 8; i++) {
183   
184   
185  }
186 
187  //  AddInitialSamples(sourceRectangle, targetRectangle, samples);
188}
189
190void
191MutualVisibilitySampler::AddInitialSamples(
192                                           const Rectangle3 &sourceRect,
193                                           const Rectangle3 &targetRect,
194                                           vector<RayShaft *> &samples
195                                           )
196{
197
198  RayShaft *sample = new RayShaft(sourceRect,
199                                  targetRect);
200  samples.push_back(sample);
201}
202
203
204void
205MutualVisibilitySampler::ExportSamples(vector<RayShaft *> &samples)
206{
207  static int id = 0;
208  char filename[64];
209  if (id > 20)
210    return;
211                           
212  for (int i=0; i < samples.size(); i++) {
213    sprintf(filename, "samples%04d-%02d.x3d", id++, i);
214    Exporter *exporter = Exporter::GetExporter(filename);
215    exporter->SetFilled();
216
217
218    RayShaft *sample = samples[i];
219    Mesh *mesh = new Mesh;
220    mesh->AddRectangle(sample->mSource);
221    mesh->AddRectangle(sample->mTarget);
222    vector<Ray> rays;
223    for (int j=0; j < 4; j++) {
224      Vector3 origin, direction;
225      sample->GetRay(j, origin, direction);
226      Ray ray(origin, direction, Ray::LINE_SEGMENT);
227      rays.push_back(ray);
228    }
229   
230    Material m = RandomMaterial();
231    exporter->SetForcedMaterial(m);
232    MeshInstance mi(mesh);
233    exporter->ExportIntersectable(&mi);
234    exporter->ExportRays(rays, -1.0f, m.mDiffuseColor);
235    delete exporter;
236  }
237}
238
239int
240MutualVisibilitySampler::ComputeVisibility()
241{
242
243  vector<RayShaft *> samples;
244  ConstructInitialSamples(mSource, mTarget, samples);
245  ExportSamples(samples);
246
247  stack<RayShaft *> sampleStack;
248 
249 
250 
251  Ray ray;
252  // now process the samples as long as we have something to do
253  while (!sampleStack.empty()) {
254    RayShaft *sample = sampleStack.top();
255    sampleStack.pop();
256   
257//      // cast a new ray
258//      int triangleSplitEdge = SetupExtremalRay(sample, source, ray);
259   
260//      if (!kdTree->CastRay(ray))
261//        return VISIBLE;
262   
263//      // generate 2 new samples
264//      RayShaft newSamples[2];
265//      sample.Split(triangleSplitEdge, ray, newSamples[0], newSamples[1]);
266//      for (i=0; i < 2; i++) {
267//        newSamples[i].ComputeError();
268//        if (newSamples[i].mError > solidAngleThreshold) {
269//      sampleStack.push(newSamples[i]);
270//        }
271//      }
272//    }
273  }
274
275  for (int i=0; i < samples.size(); i++)
276    delete samples[i];
277  return INVISIBLE;
278}
279
280MutualVisibilitySampler::MutualVisibilitySampler(KdTree *kdTree,
281                                                 AxisAlignedBox3 &source,
282                                                 AxisAlignedBox3 &target,
283                                                 const float solidAngleThreshold)
284{
285  mKdTree = kdTree;
286  mSource = source;
287  mTarget = target;
288  mSolidAngleThreshold = solidAngleThreshold;
289}
290 
291
292int
293ComputeBoxVisibility(KdTree *kdTree,
294                     AxisAlignedBox3 &source,
295                     AxisAlignedBox3 &target,
296                     const float solidAngleThreshold)
297{
298  MutualVisibilitySampler sampler(kdTree, source, target, solidAngleThreshold);
299
300 
301  int visibility = sampler.ComputeVisibility();
302
303  return visibility;
304 
305}
306 
Note: See TracBrowser for help on using the repository browser.