source: trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp @ 540

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