source: GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp @ 863

Revision 863, 5.1 KB checked in by mattausch, 19 years ago (diff)

working on preprocessor integration
added iv stuff

  • Property svn:executable set to *
RevLine 
[504]1#include "VssRay.h"
[511]2#include "Beam.h"
[540]3#include "Mesh.h"
4#include "Polygon3.h"
[504]5
[863]6namespace GtpVisibilityPreprocessor {
[504]7
8void
[540]9Beam::Construct(const AxisAlignedBox3 &box, const AxisAlignedBox3 &dBox)
[504]10{
11  // the frustum is defined by set of negative halfspace described by mPlanes
12 
13  // construct
14  Vector3 center = box.Center();
15  Vector3 dCenter = dBox.Center();
16
17  // "back plane"
18  mPlanes.push_back(Plane3(-VssRay::GetDirection(dCenter.x, dCenter.y), center));
[534]19 
[504]20  Vector3 directions[4];
21  directions[0] = VssRay::GetDirection(dBox.Min().x, dBox.Min().y);
22  directions[1] = VssRay::GetDirection(dBox.Max().x, dBox.Min().y);
23  directions[2] = VssRay::GetDirection(dBox.Max().x, dBox.Max().y);
24  directions[3] = VssRay::GetDirection(dBox.Min().x, dBox.Max().y);
25 
26  // side planes
[534]27  mPlanes.push_back(Plane3(-CrossProd(directions[0], directions[1]), center));
28  mPlanes.push_back(Plane3(-CrossProd(directions[1], directions[2]), center));
29  mPlanes.push_back(Plane3(-CrossProd(directions[2], directions[3]), center));
30  mPlanes.push_back(Plane3(-CrossProd(directions[3], directions[0]), center));
[504]31
32  // now make sure all planes contain the spatial box
33  int i, j;
[535]34  for (i=0; i < mPlanes.size(); i++)
35  {
36          float maxDist = 0;
37         
38          for (j=0; j < 8; j++)
39          {
40                float dist = mPlanes[i].Distance(box.GetVertex(j));
41       
42                if (dist > maxDist)
43                        maxDist = dist;
44          }
45
46          mPlanes[i].mD -= maxDist;
[504]47  }
[507]48
49  mBox = box;
50  mDirBox = dBox;
51 
52  SetValid();
[504]53}
54
55// conservative frustum box intersection
56// returns
57// 0 - box intersects the frustum
58// -1 - box intersects the frustum and is fully inside
59// 1 - box does not intersect the frustum
60
61int
[512]62Beam::ComputeIntersection(const AxisAlignedBox3 &box)
[504]63{
64  int i;
65  int result = -1;
66  for (i=0; i < mPlanes.size(); i++) {
67        int side = box.Side(mPlanes[i]);
68        if (side == 1)
69          return 1;
70        if (side > result)
71          result = side;
72  }
73  return result;
[522]74}
75
76
[542]77Beam::~Beam()
78{
79        DEL_PTR(mMesh);
80}
81
82
[540]83void Beam::ComputePerspectiveFrustum(float &left, float &right,
84                                                                         float &bottom, float &top,
85                                                                         float &near, float &far,
86                                                                         const AxisAlignedBox3 &sceneBBox) const
[522]87{
88        const float xDirRange = mDirBox.Max().x - mDirBox.Min().x;
89        const float yDirRange = mDirBox.Max().y - mDirBox.Min().y;
[540]90        //Debug << "xdir range: " << xDirRange << endl;
91        //Debug << "ydir range: " << yDirRange << endl;
[522]92
[531]93        near = 0.1f; // NOTE: what is the best value for near and far plane?
[525]94        far = 2.0f * Magnitude(sceneBBox.Diagonal());
[540]95       
96        right = fabs(near * tan(xDirRange * 0.5f));
97        left = -right;
[522]98
[540]99        top = fabs(near * tan(yDirRange * 0.5f));
100        bottom = -top;
101}
[522]102
[540]103
104void Beam::ComputeOrthoFrustum(float &left, float &right,
105                                                           float &bottom, float &top,
106                                                           float &near, float &far,
107                                                           const AxisAlignedBox3 &sceneBBox) const
108{
109        const int vAxis = GetMainDirection().DrivingAxis();
110        const int axis2 = (vAxis + 1) % 3;
111        const int axis3 = (vAxis + 2) % 3;
112
113        const float xDirRange = mBox.Max()[axis2] - mDirBox.Min()[axis2];
114        const float yDirRange = mDirBox.Max()[axis3] - mDirBox.Min()[axis3];
115
116        near = 0.1f; // NOTE: what is the best value for near and far plane?
117        far = 2.0f * Magnitude(sceneBBox.Diagonal());
118
119        right = xDirRange * 0.5f;
120        left = -right;
121
[704]122        top = yDirRange * 0.5f;
[540]123        bottom = -top;
[525]124}
125
[535]126
[525]127Vector3 Beam::GetMainDirection() const
128{
[540]129        return - mPlanes[0].mNormal;
[531]130}
131
132
133void BeamSampleStatistics::Print(ostream &app) const
134{
135  app << "===== Beam sample statistics ===============\n";
136
137  app << "#N_PVSSIZE ( size of pvs )\n" << pvsSize << "\n";
138
139  app << "#N_RAYS ( Number of rays )\n" << rays << "\n";
140
141  app << "#N_RAYCONTRIBUTIONS ( number of ray constributions )\n" <<
142    rayContributions << "\n";
143
144  app << "#N_RAYLENGHTENTROPY  ( Ray lenght entropy )\n" <<
145    rayLengthEntropy << "\n";
146
147  app << "#N_IMPORTANCE  ( importance )\n" <<
148    importance << "\n";
149
150  app << "#N_CTIME  ( Construction time [s] )\n"
151      << Time() << " \n";
152
153  app << "===== END OF KdTree statistics ==========\n";
154
[534]155}
156
[540]157
158void Beam::CreateMesh(const float zfar)
159{
160        if (mMesh)
161                return;
162
163        mMesh = new Mesh();
164       
165        // -- compute far plane
166
167        // box should not never remove part of beam polygons
[704]168        Vector3 bmin = mBox.Min() - Vector3(zfar * 2.0f);
169        Vector3 bmax = mBox.Max() + Vector3(zfar * 2.0f);
[540]170
171        AxisAlignedBox3 bbox(bmin, bmax);
172        Plane3 fplane;
173        fplane.mNormal = -mPlanes[0].mNormal;
174
175        // NOTE: beam far plane must not not be culled by gl far plane
176        fplane.mD = mPlanes[0].mD - zfar - 1.0f;
177        mPlanes.push_back(fplane);
178
179        for (int i = 0; i < mPlanes.size(); ++ i)
180        {
181                Polygon3 *poly = bbox.CrossSection(mPlanes[i]);
182               
183                if (!poly->Valid(Limits::Small))
184                        DEL_PTR(poly);
185               
186                for (int j = 0; (j < mPlanes.size()) && poly; ++ j)
187                {
188                        if (j != i)
189                        {
190                                Polygon3 *front = new Polygon3();
191                                Polygon3 *back = new Polygon3();
192                               
193                                poly->Split(mPlanes[j], *front, *back, Limits::Small);
194                                DEL_PTR(poly);
195                                DEL_PTR(front);
196
197                                if (!back->Valid(Limits::Small))
198                                        DEL_PTR(back);
199                                poly = back;
200                        }
201                }
202       
203                if (poly)
204                {
[840]205                        IncludePolyInMesh(*poly, *mMesh);
[540]206                }
207        }
208
209        // remove far plane
210        mPlanes.pop_back();
[860]211}
212
[540]213}
Note: See TracBrowser for help on using the repository browser.