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

Revision 542, 5.1 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
76Beam::~Beam()
77{
78        DEL_PTR(mMesh);
79}
80
81
82void Beam::ComputePerspectiveFrustum(float &left, float &right,
83                                                                         float &bottom, float &top,
84                                                                         float &near, float &far,
85                                                                         const AxisAlignedBox3 &sceneBBox) const
86{
87        const float xDirRange = mDirBox.Max().x - mDirBox.Min().x;
88        const float yDirRange = mDirBox.Max().y - mDirBox.Min().y;
89        //Debug << "xdir range: " << xDirRange << endl;
90        //Debug << "ydir range: " << yDirRange << endl;
91
92        near = 0.1f; // NOTE: what is the best value for near and far plane?
93        far = 2.0f * Magnitude(sceneBBox.Diagonal());
94       
95        right = fabs(near * tan(xDirRange * 0.5f));
96        left = -right;
97
98        top = fabs(near * tan(yDirRange * 0.5f));
99        bottom = -top;
100}
101
102
103void Beam::ComputeOrthoFrustum(float &left, float &right,
104                                                           float &bottom, float &top,
105                                                           float &near, float &far,
106                                                           const AxisAlignedBox3 &sceneBBox) const
107{
108        const int vAxis = GetMainDirection().DrivingAxis();
109        const int axis2 = (vAxis + 1) % 3;
110        const int axis3 = (vAxis + 2) % 3;
111
112        const float xDirRange = mBox.Max()[axis2] - mDirBox.Min()[axis2];
113        const float yDirRange = mDirBox.Max()[axis3] - mDirBox.Min()[axis3];
114
115        near = 0.1f; // NOTE: what is the best value for near and far plane?
116        far = 2.0f * Magnitude(sceneBBox.Diagonal());
117
118        right = xDirRange * 0.5f;
119        left = -right;
120
121        top = yDirRange * 0.5;
122        bottom = -top;
123}
124
125
126Vector3 Beam::GetMainDirection() const
127{
128        return - mPlanes[0].mNormal;
129}
130
131
132void BeamSampleStatistics::Print(ostream &app) const
133{
134  app << "===== Beam sample statistics ===============\n";
135
136  app << "#N_PVSSIZE ( size of pvs )\n" << pvsSize << "\n";
137
138  app << "#N_RAYS ( Number of rays )\n" << rays << "\n";
139
140  app << "#N_RAYCONTRIBUTIONS ( number of ray constributions )\n" <<
141    rayContributions << "\n";
142
143  app << "#N_RAYLENGHTENTROPY  ( Ray lenght entropy )\n" <<
144    rayLengthEntropy << "\n";
145
146  app << "#N_IMPORTANCE  ( importance )\n" <<
147    importance << "\n";
148
149  app << "#N_CTIME  ( Construction time [s] )\n"
150      << Time() << " \n";
151
152  app << "===== END OF KdTree statistics ==========\n";
153
154}
155
156
157void Beam::CreateMesh(const float zfar)
158{
159        if (mMesh)
160                return;
161
162        mMesh = new Mesh();
163       
164        // -- compute far plane
165
166        // box should not never remove part of beam polygons
167        Vector3 bmin = mBox.Min() - Vector3(zfar * 2.0);
168        Vector3 bmax = mBox.Max() + Vector3(zfar * 2.0);
169
170        AxisAlignedBox3 bbox(bmin, bmax);
171        Plane3 fplane;
172        fplane.mNormal = -mPlanes[0].mNormal;
173
174        // NOTE: beam far plane must not not be culled by gl far plane
175        fplane.mD = mPlanes[0].mD - zfar - 1.0f;
176        mPlanes.push_back(fplane);
177
178        for (int i = 0; i < mPlanes.size(); ++ i)
179        {
180                Polygon3 *poly = bbox.CrossSection(mPlanes[i]);
181               
182                if (!poly->Valid(Limits::Small))
183                        DEL_PTR(poly);
184               
185                for (int j = 0; (j < mPlanes.size()) && poly; ++ j)
186                {
187                        if (j != i)
188                        {
189                                Polygon3 *front = new Polygon3();
190                                Polygon3 *back = new Polygon3();
191                               
192                                poly->Split(mPlanes[j], *front, *back, Limits::Small);
193                                DEL_PTR(poly);
194                                DEL_PTR(front);
195
196                                if (!back->Valid(Limits::Small))
197                                        DEL_PTR(back);
198                                poly = back;
199                        }
200                }
201       
202                if (poly)
203                {
204                        poly->AddToMesh(*mMesh);
205                }
206        }
207
208        // remove far plane
209        mPlanes.pop_back();
210}
Note: See TracBrowser for help on using the repository browser.