Changeset 2755 for GTP/trunk/App/Demos/Vis
- Timestamp:
- 06/12/08 01:09:23 (17 years ago)
- Location:
- GTP/trunk/App/Demos/Vis/CHC_revisited
- Files:
-
- 6 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.cpp
r2751 r2755 2 2 #include <iostream> 3 3 #include "AxisAlignedBox3.h" 4 #include "Plane3.h" 4 5 5 6 6 7 using namespace std; 8 7 9 8 10 namespace CHCDemo … … 1027 1029 return mMin[face]; 1028 1030 else 1029 return mMax[face - 3]; 1030 } 1031 1032 1033 } 1034 1031 return mMax[face - 3]; 1032 } 1033 1034 1035 int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal) 1036 { 1037 int index; 1038 1039 if (vecPlaneNormal.x > 0.0f) 1040 index = (vecPlaneNormal.y > 0.0f) ? 0 : 3; 1041 else 1042 index = (vecPlaneNormal.y > 0.0f) ? 1 : 2; 1043 1044 return (vecPlaneNormal.z > 0.0f) ? index : 7 - index; 1045 } 1046 1047 1048 int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal) 1049 { 1050 int index; 1051 1052 if (vecPlaneNormal.x <= 0.0f) 1053 index = (vecPlaneNormal.y <= 0.0f) ? 0 : 3; 1054 else 1055 index = (vecPlaneNormal.y <= 0.0f) ? 1 : 2; 1056 1057 return (vecPlaneNormal.z <= 0.0f) ? index : 7 - index; 1058 } 1059 1060 1061 float AxisAlignedBox3::GetDistance(int index, const Plane3 &plane) const 1062 { 1063 return plane.Distance(GetVertex(index)); 1064 } 1065 1066 1067 float AxisAlignedBox3::GetMinVisibleDistance(const Plane3 &near) const 1068 { 1069 return near.mNormal.x * ((near.mNormal.x > 0.0f) ? mMin.x : mMax.x) + 1070 near.mNormal.y * ((near.mNormal.y > 0.0f) ? mMin.y : mMax.y) + 1071 near.mNormal.z * ((near.mNormal.z > 0.0f) ? mMin.z : mMax.z) + 1072 near.mD; 1073 } 1074 1075 } 1076 -
GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.h
r2751 r2755 3 3 4 4 5 6 5 #include "Matrix4x4.h" 7 6 #include "Vector3.h" 8 //#include "Plane3.h"9 //#include "Containers.h"10 7 11 8 … … 14 11 15 12 struct Triangle3; 13 class Plane3; 16 14 17 15 /** Axis alignedd box class. … … 52 50 const Vector3& Max() const; 53 51 54 void Enlarge 52 void Enlarge(const Vector3 &v); 55 53 56 54 void EnlargeToMinSize(); … … 63 61 64 62 void SetMax(int axis, const float value); 65 66 // Decrease box by given splitting plane63 /** Decrease box by given splitting plane 64 */ 67 65 void Reduce(int axis, int right, float value); 68 66 … … 71 69 // the size of the box along all the axes 72 70 Vector3 Size() const; 73 float Radius() const { return 0.5f *Magnitude(Size()); }74 float SqrRadius() const { return 0.5f *SqrMagnitude(Size()); }71 float Radius() const { return 0.5f * Magnitude(Size()); } 72 float SqrRadius() const { return 0.5f * SqrMagnitude(Size()); } 75 73 76 74 // Return whether the box is unbounded. Unbounded boxes appear … … 84 82 */ 85 83 void Include(const int &axis, const float &newBound); 86 // int Side(const Plane3 &plane) const;87 88 // Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly89 friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &);90 91 // Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly92 friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &);93 94 /** Overlap returns 1 if the two axis-aligned boxes overlap for a given95 epsilon. If eps > 0.0, then the boxes has to have the real intersection96 box, if eps < 0.0, then the boxes need not intersect really, they97 can be at eps distance in the projection.98 */99 friend inline bool Overlap(const AxisAlignedBox3 &,100 const AxisAlignedBox3 &,101 float eps);102 103 84 /** Includes returns true if a includes b (completely) 104 85 */ 105 86 bool Includes(const AxisAlignedBox3 &b) const; 106 107 87 /** Returns true if this point is inside box. 108 88 */ … … 122 102 /** Scales the box with the factor. 123 103 */ 124 void Scale( constfloat scale);104 void Scale(float scale); 125 105 126 106 void Scale(const Vector3 &scale); … … 177 157 178 158 int GetFaceVisibilityMask(const Vector3 &position) const; 179 /** Extracts plane of bounding box.180 */181 //Plane3 GetPlane(const int face) const;182 159 /** Returns vertex indices of edge. 183 160 */ 184 void GetEdge(const int edge, int &aIdx, int &bIdx) const; 185 161 void GetEdge(int edge, int &aIdx, int &bIdx) const; 162 /** Get distance of plane to vertex with specified index. 163 */ 164 float GetDistance(int index, const Plane3 &plane) const; 165 /** Returns the distance between the plane given by 'vecNearplaneNormal' and the vertex that 166 is closest to it (this vertex is unequivocally identified by the direction of the vector) 167 */ 168 float GetMinVisibleDistance(const Plane3 &near) const; 186 169 187 170 188 171 //////////// 189 172 //-- friend functions 173 174 /// Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly 175 friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &); 176 177 /// Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly 178 friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &); 179 180 /** Overlap returns 1 if the two axis-aligned boxes overlap for a given 181 epsilon. If eps > 0.0, then the boxes has to have the real intersection 182 box, if eps < 0.0, then the boxes need not intersect really, they 183 can be at eps distance in the projection. 184 */ 185 friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &, float eps); 186 190 187 191 188 // Returns the smallest axis-aligned box that includes all points … … 250 247 static const int fsvertices[27][9]; 251 248 249 /** Returns the vertex index nearest from the plane specified by the normal. 250 */ 251 static int GetIndexNearestVertex(const Vector3 &vecPlaneNormal); 252 /** Returns the vertwx index farthest from the plane specified by the normal. 253 */ 254 static int GetIndexFarthestVertex(const Vector3 &vecPlaneNormal); 255 256 257 252 258 protected: 253 259 254 260 Vector3 mMin, mMax; 255 256 261 }; 257 262 -
GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.cpp
r2747 r2755 1 1 #include "BinaryLoader.h" 2 #include "yare.h" 3 #include "yamath.h" 4 #include "gzstream.h" 5 #include "ImageComponent.h" 6 #include "RenderState.h" 7 #include "GeometryProcessor.h" 2 #include "Matrix4x4.h" 3 #include "Geometry.h" 4 #include "Material.h" 5 //#include "gzstream.h" 8 6 9 7 10 8 using namespace std; 11 9 12 static STL_MAP<String,Texture *> stlm_textures; 10 11 namespace CHCDemo 12 { 13 14 /*static STL_MAP<String,Texture *> stlm_textures; 13 15 14 16 … … 61 63 62 64 return myTexture; 63 } 64 65 66 Shape3D *BinaryLoader::LoadShape(igzstream &str) 65 }*/ 66 67 68 //SceneEntity *BinaryLoader::LoadShape(igzstream &str) 69 SceneEntity *BinaryLoader::LoadShape(ifstream &str) 67 70 { 68 71 Geometry *geom = LoadGeometry(str); 69 Appearance *app = LoadAppearance(str); 70 71 Shape3D *shape = new Shape3D(geom, app); 72 73 return shape; 74 } 75 76 77 Appearance *BinaryLoader::LoadAppearance(igzstream &str) 78 { 79 Appearance *app = new Appearance(); 80 72 Material *mat = LoadMaterial(str); 73 74 Matrix4x4 *m; 75 SceneEntity *sceneGeom = new SceneEntity(geom, m, mat); 76 77 return sceneGeom; 78 } 79 80 81 //Appearance *BinaryLoader::LoadMaterial(igzstream &str) 82 Material *BinaryLoader::LoadMaterial(ifstream &str) 83 { 84 Material *mat = new Material(); 85 /* 81 86 // texture 82 87 int texnameSize; … … 113 118 //str.read(reinterpret_cast<char *>(&spec), sizeof(Color3f)); 114 119 //str.read(reinterpret_cast<char *>(&shine), sizeof(float)); 115 #if 1116 Material *mat = new Material();117 120 118 121 mat->setAmbientColor(amb); … … 123 126 124 127 app->setMaterial(mat); 125 #endif 126 } 127 128 return app; 129 } 130 131 132 Geometry *BinaryLoader::LoadGeometry(igzstream &str) 133 { 128 } 129 130 return app;*/ 131 132 return mat; 133 } 134 135 136 //Geometry *BinaryLoader::LoadGeometry(igzstream &str) 137 Geometry *BinaryLoader::LoadGeometry(ifstream &str) 138 { 139 /* 134 140 int vertexCount; 135 141 int stripCount; … … 254 260 255 261 return geom; 256 } 257 258 259 BranchGroup *BinaryLoader::Load(const string &filename) 260 { 262 */ 263 return 0; 264 } 265 266 267 bool BinaryLoader::Load(const std::string &filename, SceneEntityContainer &geometry) 268 { 269 #if 0 261 270 clear_textures(); // clear the texture table 262 271 … … 320 329 321 330 return root; 322 }323 324 325 #if 0326 327 collectvertices328 {329 int newIndex = 0;330 331 for (int i = 0; i < numTriangles; ++ i)332 {333 Triangle tri = mTriangles[i];334 335 for (int j = 0; j < 3; ++ j)336 {337 const int index = tri.mVertexIndices[j];338 if (!mHashtable[index])339 {340 mHashTable[index] = newIndex;341 mNewVertices.push_back(mVertices[index];342 }343 }344 345 // now loop again, exchange indices;346 for (int i = 0; i < numTriangles; ++ i347 {348 Triangle tri = mTriangles[i];349 350 for (int j = 0; j < 3; ++ j)351 {352 const int index = tri.mVertexIndices[j];353 tri.mVertexIndices[j] = mHashTable[index];354 }355 }356 357 331 #endif 332 } 333 334 } -
GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.h
r2747 r2755 4 4 // note use forward declaration instead 5 5 #include <string> 6 #include <iostream> 7 #include <fstream> 8 #include "common.h" 6 9 7 10 11 namespace CHCDemo 12 { 13 8 14 class igzstream; 9 class Shape3D; 10 class BranchGroup; 11 class Appearance; 15 class SceneEntity; 16 class Material; 12 17 class Geometry; 13 18 … … 17 22 public: 18 23 19 BranchGroup *Load(const std::string &filename);24 bool Load(const std::string &filename, SceneEntityContainer &geometry); 20 25 21 26 protected: 27 28 SceneEntity *LoadShape(std::ifstream &str); 29 Material *LoadMaterial(std::ifstream &str); 30 Geometry *LoadGeometry(std::ifstream &str); 22 31 23 Shape3D *LoadShape(igzstream &str); 24 25 Appearance *LoadAppearance(igzstream &str); 26 32 /*SceneEntity *LoadShape(igzstream &str); 33 Material *LoadMaterial(igzstream &str); 27 34 Geometry *LoadGeometry(igzstream &str); 35 */ 28 36 }; 29 37 38 } 30 39 #endif -
GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.cpp
r2752 r2755 1 1 #include <queue> 2 2 #include <stack> 3 #include "Bvh.h"4 5 3 #include <fstream> 6 4 #include <iostream> 7 5 #include <iomanip> 8 6 7 #include "Bvh.h" 8 #include "Camera.h" 9 #include "Plane3.h" 10 #include "glInterface.h" 11 #include "Triangle3.h" 12 9 13 10 14 namespace CHCDemo 11 15 { 12 16 13 #if TOIMPLEMENT14 15 17 #define INVALID_TEST ((unsigned int)-1) 16 17 #define TYPE_INTERIOR -218 #define TYPE_LEAF -319 #define USE_TIGHTER_BOUNDS_FOR_ALL 020 18 21 19 const static bool useVbos = true; … … 62 60 */ 63 61 62 static Plane3 sNearPlane; 63 static Camera::Frustum sFrustum; 64 65 /// these values are valid for all nodes 66 static int sClipPlaneAABBVertexIndices[12]; 67 64 68 65 69 BvhNode::BvhNode(BvhNode *parent): … … 69 73 mPlaneMask(0), 70 74 mPreferredPlane(0), 71 mVizBox(NULL),72 75 mLastRenderedFrame(-999), 73 76 mFirst(-1), … … 75 78 mNumTestNodes(1), 76 79 mTestNodesIdx(-1), 77 mIndicesPtr(-1) 80 mIndicesPtr(-1), 81 mIndices(NULL), 82 mId(0) 78 83 { 79 84 } … … 83 88 { 84 89 mVisibility.Reset(); 85 mMeasurements.Reset();86 90 87 91 mLastRenderedFrame = -999; … … 91 95 BvhNode::~BvhNode() 92 96 { 93 if (mVizBox) mVizBox->unref();94 }95 96 97 Box *BvhNode::GetOrCreateVizBox()98 {99 if (!mVizBox)100 {101 mVizBox = new Box(mBox);102 mVizBox->ref();103 }104 105 return mVizBox;106 97 } 107 98 … … 110 101 { 111 102 mIsVisible = false; 112 mIsFullyVisible = false; 113 114 mVisiblePixels = 0; 103 115 104 mAssumedVisibleFrames = 0; 116 mRemainingVisibleFrames = 0;117 105 118 106 mLastVisitedFrame = -1; 119 mLastTestedFrame = -1; 120 mTurnedVisibleFrame = 0; 121 107 122 108 mTimesInvisible = 0; 123 mTimesTested = 0;124 mTimesChangedClassification = 0;125 mAvgChangedClassification = 0;126 109 mIsFrustumCulled = false; 127 110 128 mLastTestedVisibleFrame = 0;129 111 mIsNew = true; 130 112 } 131 113 132 114 133 void BvhNode::SetFullyVisible(const bool visible)134 {135 mVisibility.mIsFullyVisible = visible;136 }137 138 139 115 BvhLeaf::~BvhLeaf() 140 116 { 141 if (mTriangleBvh) delete mTriangleBvh;142 117 } 143 118 … … 148 123 149 124 150 125 Bvh::Bvh(): 126 mCamera(NULL), 127 mFrameId(-1), 128 mRoot(NULL), 129 mVertices(NULL), 130 mIndices(NULL), 131 mTestIndices(NULL), 132 mCurrentIndicesPtr(0) 133 {} 134 135 /* 151 136 Bvh::Bvh(const GeometryVector &geometry, 152 137 DistanceSortedRenderAction *const renderer): … … 156 141 mVertices(NULL), 157 142 mIndices(NULL), 158 mUseTighterBoundsOnlyForLeafTests(false),159 mRenderer(renderer),160 143 mTestIndices(NULL), 161 144 mCurrentIndicesPtr(0), 162 mCollectTighterBoundsWithMaxLevel(true)163 145 { 164 146 mGeometry = new NodeGeometry*[geometry.size()]; … … 203 185 204 186 mMaxDepthForTestingChildren = Settings::Global()->get_nvocc_bvh_max_depth_for_testing_children(); 205 mUseTighterBoundsOnlyForLeafTests = (Settings::Global()->get_nvocc_use_tighter_bounds() >= 1); 206 187 207 188 mAreaRatioThreshold = Settings::Global()->get_nvocc_area_ratio_threshold(); 208 189 mVolRatioThreshold = Settings::Global()->get_nvocc_vol_ratio_threshold(); 209 190 } 210 191 */ 211 192 212 193 Bvh::~Bvh() … … 221 202 222 203 223 void Bvh::Construct()224 {225 PerfTimer constructTimer;226 constructTimer.Entry();227 228 OUT1("Info: Constructing BVH");229 230 mRoot = SubdivideLeaf((BvhLeaf *)mRoot, 0);231 232 constructTimer.Exit();233 234 OUT1("Info: Bvh done in " << constructTimer.TotalCount() << " seconds.");235 OUT1("Info: Number Of BVH Nodes = " << mNumNodes);236 237 // update stats on leaf nodes238 UpdateNumLeaves(mRoot);239 240 mAvgDepth = 1.0f + log((float)GetNumLeaves()) / log(2.0f);241 242 BvhLeafContainer leaves;243 leaves.reserve(GetNumLeaves());244 CollectLeaves(mRoot, leaves);245 246 // compute tighter boundaries for the leaves247 PostProcessLeaves(leaves);248 // compute unique ids249 ComputeIds();250 /// pull up some data from the leaves251 UpdateInteriors(mRoot);252 // recompute the boundaries once253 RecomputeBounds();254 // do stats255 ComputeBvhStats();256 257 PrintBvhStats();258 }259 260 261 float Bvh::EvaluateSahCost(BvhLeaf *leaf, const int axis, const float position)262 {263 // count triangles on the left / right264 int left = 0;265 int right = 0;266 BoundingBox leftBox, rightBox;267 268 const int candidates = std::max(50, (int)(leaf->CountPrimitives() / 20));269 270 const float finc = leaf->CountPrimitives() / (float)candidates;271 272 int i = leaf->mFirst;273 float fi = leaf->mFirst + 0.5f;274 275 BoundingBox box;276 277 for (; i <= leaf->mLast;)278 {279 box = mGeometry[i]->GetBoundingBox();280 281 if (box.getCenter()[axis] < position)282 {283 ++ left;284 // update the box285 leftBox.combine(&box);286 }287 else288 {289 ++ right;290 rightBox.combine(&box);291 }292 293 fi += finc;294 i = (int)fi;295 }296 297 float bW = 1.0f;298 float leftRatio = left / (float)leaf->CountPrimitives();299 float rightRatio = right / (float)leaf->CountPrimitives();300 301 float saLeft = 0.0f;302 float saRight = 0.0f;303 304 // not a valid split305 if (!left || !right)306 return 1e25f;307 308 saLeft = leftBox.getSurface();309 saRight = rightBox.getSurface();310 311 312 return313 saLeft * ((1.0f - bW) + bW * leftRatio) +314 saRight * ((1.0f - bW) + bW * rightRatio);315 }316 317 318 float Bvh::SelectPlaneSah(BvhLeaf *leaf, int &axis, float &minCost)319 {320 minCost = MAXFLOAT;321 float bestPos = minCost;322 int bestAxis = 0;323 324 // cout<<"Evaluating axis..."<<endl<<flush;325 326 const int initialPlanes = 3;327 328 // initiate the costs329 for (axis = 0; axis < 3; ++ axis)330 {331 const float size = leaf->mBox.getUpper()[axis] - leaf->mBox.getLower()[axis];332 333 for (int i = 0; i < initialPlanes; ++ i)334 {335 const float pos = leaf->mBox.getLower()[axis] + (i + 1) * size / (initialPlanes + 1);336 const float cost = EvaluateSahCost(leaf, axis, pos);337 338 if (cost < minCost)339 {340 minCost = cost;341 bestPos = pos;342 bestAxis = axis;343 }344 }345 }346 347 axis = bestAxis;348 349 // cout<<axis<<endl<<flush;350 const float shrink = 0.5f;351 352 // now hierarchically refine the initial interval353 float size = shrink *354 (leaf->mBox.getUpper()[axis] - leaf->mBox.getLower()[axis]) / (initialPlanes + 1);355 356 const int steps = 4;357 float cost;358 359 for (int i = 0; i < steps; ++ i)360 {361 const float left = bestPos - size;362 const float right = bestPos + size;363 364 cost = EvaluateSahCost(leaf, axis, left);365 366 if (cost < minCost)367 {368 minCost = cost;369 bestPos = left;370 }371 372 cost = EvaluateSahCost(leaf, axis, right);373 374 if (cost < minCost)375 {376 minCost = cost;377 bestPos = right;378 }379 380 size = shrink * size;381 }382 383 //OUT1("best axis: " << axis << " " << bestPos << " " << minCost);384 385 return bestPos;386 }387 388 389 void Bvh::ResizeVisibilityBuffers(const int maxSize)390 {391 std::stack<BvhNode *> nodeStack;392 393 nodeStack.push(mRoot);394 395 while (!nodeStack.empty())396 {397 BvhNode *node = nodeStack.top();398 nodeStack.pop();399 400 static_cast<BvhLeaf *>(node)->mMeasurements.Reset();401 402 if (!node->IsLeaf())403 {404 BvhInterior *interior = static_cast<BvhInterior *>(node);405 406 nodeStack.push(interior->mBack);407 nodeStack.push(interior->mFront);408 }409 }410 }411 412 413 int Bvh::SortTriangles(BvhLeaf *leaf,414 const int axis,415 const float position)416 {417 int i = leaf->mFirst;418 int j = leaf->mLast;419 420 while (1)421 {422 while (mGeometry[i]->GetBoundingBox().getCenter()[axis] < position)423 ++ i;424 425 while (position < mGeometry[j]->GetBoundingBox().getCenter()[axis])426 -- j;427 428 if (i < j)429 {430 std::swap(mGeometry[i], mGeometry[j]);431 432 ++ i;433 -- j;434 }435 else436 {437 break;438 }439 }440 441 return j;442 }443 444 445 int Bvh::SortTrianglesSpatialMedian(BvhLeaf *leaf, const int axis)446 {447 // spatial median448 float x = leaf->mBox.getCenter()[axis];449 450 return SortTriangles(leaf, axis, x);451 }452 453 454 int Bvh::SortTrianglesObjectMedian(BvhLeaf *leaf, const int axis, float &pos)455 {456 // Now distribute the objects into the subnodes457 // Use QuickMedian sort458 int l = leaf->mFirst;459 int r = leaf->mLast;460 int k = (l + r) / 2;461 462 while (l < r)463 {464 int i = l;465 int j = r;466 467 // get some estimation of the pivot468 pos = mGeometry[(l + r) / 2]->GetBoundingBox().getCenter()[axis];469 470 while (1)471 {472 while ((i <= leaf->mLast) && (mGeometry[i]->GetBoundingBox().getCenter()[axis] < pos))473 ++ i;474 475 while((j >= leaf->mFirst) && (pos < mGeometry[j]->GetBoundingBox().getCenter()[axis]))476 -- j;477 478 if (i <= j)479 {480 std::swap(mGeometry[i], mGeometry[j]);481 ++ i;482 -- j;483 }484 else485 {486 break;487 }488 }489 490 // now check the extents491 if (i >= k)492 r = j;493 else494 l = i;495 }496 497 return k;498 }499 500 501 int Bvh::SortTrianglesSurfaceArea(BvhLeaf *leaf, const float sa)502 {503 int i = leaf->mFirst;504 int j = leaf->mLast;505 506 while(1)507 {508 while ((i <= j) && (mGeometry[i]->GetBoundingBox().getSurface() < sa))509 ++ i;510 511 while ((i <= j) && (sa < mGeometry[j]->GetBoundingBox().getSurface()))512 -- j;513 514 if (i < j)515 {516 swap(mGeometry[i], mGeometry[j]);517 ++ i;518 -- j;519 }520 else521 break;522 }523 524 return j;525 }526 527 528 bool Bvh::TerminationCriteriaMet(BvhLeaf *leaf) const529 {530 const bool terminationCriteriaMet =531 (leaf->mBox.getSurface() < mMinArea) ||532 (leaf->CountPrimitives() <= mMaxGeometry) ||533 (CountTriangles(leaf) <= mMaxTriangles) ||534 (leaf->mDepth > mMaxDepth);535 536 return terminationCriteriaMet;537 }538 539 540 BvhNode *Bvh::SubdivideLeaf(BvhLeaf *leaf, const int parentAxis)541 {542 if (TerminationCriteriaMet(leaf))543 return leaf;544 545 //int axis = leaf->mBox.MajorAxis();546 int axis = (parentAxis + 1) % 3;547 548 // position of the split in the partailly sorted array of triangles549 // corresponding to this leaf550 int split = -1;551 const int scale = 20;552 553 float pos = -1.0f;554 555 // Spatial median subdivision556 switch (mSplitType)557 {558 case SPATIAL_MEDIAN:559 split = SortTrianglesSpatialMedian(leaf, axis);560 561 if (562 ((split - leaf->mFirst) < leaf->CountPrimitives() / scale) ||563 ((leaf->mLast - split) < leaf->CountPrimitives() / scale) )564 {565 split = SortTrianglesObjectMedian(leaf, axis, pos);566 }567 568 pos = leaf->mBox.getCenter()[axis];569 break;570 case OBJECT_MEDIAN:571 // Object median subdivision: approximately the same number572 // of objects on the left of the the splitting point.573 split = SortTrianglesObjectMedian(leaf, axis, pos);574 break;575 case SAH:576 {577 float cost;578 pos = SelectPlaneSah(leaf, axis, cost);579 580 if (pos != MAXFLOAT)581 {582 split = SortTriangles(leaf, axis, pos);583 }584 585 if ((pos == MAXFLOAT) || (split == leaf->mLast))586 {587 split = -1;588 split = SortTrianglesObjectMedian(leaf, axis, pos);589 }590 }591 break;592 case SAH_OR_SIZE:593 {594 // split by size instead595 const float saThreshold = 0.2f * leaf->GetBox().getSurface();596 split = SortTrianglesSurfaceArea(leaf, saThreshold);597 598 if ((split == leaf->mLast) || (split == leaf->mFirst - 1))599 {600 // use SAH601 float cost;602 pos = SelectPlaneSah(leaf, axis, cost);603 604 if (pos != MAXFLOAT)605 split = SortTriangles(leaf, axis, pos);606 else607 split = SortTrianglesObjectMedian(leaf, axis, pos);608 }609 else610 {611 // note: no position is computed!!612 //OUT1("sorted by size");613 }614 }615 break;616 default:617 OUT1("should not come here");618 break;619 }620 621 if (1 && ((split == leaf->mLast)))622 {623 // no reduction: we should never come here624 OUT1("error: no reduction " << leaf->CountPrimitives() << " " << leaf->mFirst << " " << split << " " << leaf->mLast);625 return leaf;626 }627 628 // create two more nodes629 mNumNodes += 2;630 BvhInterior *parent = new BvhInterior(leaf->GetParent());631 BvhLeaf *front = new BvhLeaf(parent);632 633 parent->mAxis = axis;634 parent->mBox = leaf->mBox;635 parent->mDepth = leaf->mDepth;636 637 parent->mBack = leaf;638 parent->mFront = front;639 parent->mPosition = pos;640 641 // now assign the triangles to the subnodes642 front->mFirst = split + 1;643 front->mLast = leaf->mLast;644 front->mDepth = leaf->mDepth + 1;645 leaf->mLast = split;646 leaf->mDepth = front->mDepth;647 leaf->mParent = parent;648 649 // reset box650 leaf->mBox = BoundingBox();651 652 UpdateLeafBox(static_cast<BvhLeaf *>(parent->mBack));653 UpdateLeafBox(static_cast<BvhLeaf *>(parent->mFront));654 655 // some output656 const int n = 500;657 if ((GetNumLeaves() % n) == n - 1)658 OUT1("created " << GetNumLeaves() << " leaves");659 660 #if VERBOSE_OUTPUT661 OUT1("box: " << parent->mBox.getUpper() << " " << parent->mBox.getLower());662 OUT1("depth: " << (int)parent->mDepth);663 OUT1("axis: " << axis);664 OUT1("bc="<<((BvhLeaf *)parent->mBack)->Count());665 OUT1("fc="<<((BvhLeaf *)parent->mFront)->Count());666 OUT1("back: " << parent->mBack->mBox.getSurface());667 OUT1("front: " << parent->mFront->mBox.getSurface());668 #endif669 670 // recursively continue subdivision671 parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis);672 parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis);673 674 return parent;675 }676 677 678 void Bvh::UpdateLeafBox(BvhLeaf *leaf)679 {680 for (int i = leaf->mFirst; i <= leaf->mLast; ++ i)681 {682 leaf->mBox.combine(&mGeometry[i]->mBox);683 } // for684 }685 686 687 void Bvh::UpdateNumLeaves(BvhNode *node) const688 {689 if (node->IsLeaf())690 {691 node->mNumLeaves = 1;692 }693 else694 {695 BvhNode *f = static_cast<BvhInterior *>(node)->GetFront();696 BvhNode *b = static_cast<BvhInterior *>(node)->GetBack();697 698 UpdateNumLeaves(f);699 UpdateNumLeaves(b);700 701 node->mNumLeaves = f->mNumLeaves + b->mNumLeaves;702 }703 }704 705 706 void Bvh::UpdateBoxes(BvhNode *node)707 {708 if (node->IsLeaf())709 {710 UpdateLeafBox(static_cast<BvhLeaf *>(node));711 }712 else713 {714 BvhInterior *interior = static_cast<BvhInterior *>(node);715 716 UpdateBoxes(interior->mBack);717 UpdateBoxes(interior->mFront);718 719 node->mBox = interior->mBack->mBox;720 node->mBox.combine(&interior->mFront->mBox);721 }722 }723 724 725 void Bvh::UpdateFullVisibility(BvhNode *node) const726 {727 // node not visited in this frame => no change728 if (node->GetLastVisitedFrame() != mFrameId)729 return;730 731 // leaf node: terminate recursion732 if (node->IsLeaf())733 {734 node->SetFullyVisible(node->IsVisible());735 return;736 }737 738 BvhInterior *interior = static_cast<BvhInterior *>(node);739 740 // recursive traversal741 UpdateFullVisibility(interior->mBack);742 UpdateFullVisibility(interior->mFront);743 744 interior->SetFullyVisible(interior->mBack->IsFullyVisible() &&745 interior->mFront->IsFullyVisible());746 }747 748 749 204 void Bvh::PullUpLastVisited(BvhNode *node, const int frameId) const 750 205 { … … 823 278 typedef pair<BvhNode *, int> tPair; 824 279 825 void Bvh::CollectNodes(BvhNode *root, 826 const int depth, 827 HierarchyNodeContainer &nodes) 280 void Bvh::CollectNodes(BvhNode *root, BvhNodeContainer &nodes, int depth) 828 281 { 829 282 stack<tPair> tStack; … … 838 291 839 292 // found depth => take this node 840 if ( d == depth)293 if ((d == depth) || (node->IsLeaf())) 841 294 { 842 295 nodes.push_back(node); 843 296 } 844 else if (node->IsLeaf()) 845 { 846 // found leaf 847 BvhLeaf *leaf = static_cast<BvhLeaf *>(node); 848 849 // there is no further subdivision on triangle level 850 if (leaf->mTriangleBvh->GetNumNodes() == 1) 851 { 852 nodes.push_back(leaf); 853 } 854 else // more than a root => search in local bvh 855 { 856 leaf->mTriangleBvh-> 857 CollectNodes(leaf->mTriangleBvh->GetRoot(), depth - d, nodes); 858 } 859 } 860 else // interior 297 else 861 298 { 862 299 BvhInterior *interior = static_cast<BvhInterior *>(node); … … 869 306 870 307 871 void Bvh::CollectAllNodes(BvhNode *node, HierarchyNodeContainer &nodes) 872 { 873 BvhNodeContainer bvhNodes; 874 875 // collect nodes of geometry bvh 876 CollectNodes(mRoot, bvhNodes); 877 878 879 // first collect nodes of object bvh 880 BvhNodeContainer::const_iterator lit, lit_end = bvhNodes.end(); 881 882 for (lit = bvhNodes.begin(); lit != lit_end; ++ lit) 883 { 884 nodes.push_back(*lit); 885 } 886 887 // collect nodes of local bvh: all except roots, 888 // because they are equivalent to geometry bvh leaves 889 for (lit = bvhNodes.begin(); lit != lit_end; ++ lit) 890 { 891 if ((*lit)->IsLeaf()) 892 { 893 BvhLeaf *leaf = static_cast<BvhLeaf *>(*lit); 894 895 TriangleBvhNodeContainer hnodes; 896 leaf->mTriangleBvh->CollectNodes(leaf->mTriangleBvh->GetRoot(), hnodes); 897 898 TriangleBvhNodeContainer::const_iterator hit, hit_end = hnodes.end(); 899 900 for (hit = hnodes.begin(); hit != hit_end; ++ hit) 901 { 902 TriangleBvhNode *n = *hit; 903 904 // don't include root of local bvh - it has the same bounds as the leaves 905 if (n != leaf->mTriangleBvh->GetRoot()) 906 nodes.push_back(n); 907 } 908 } 909 } 910 } 911 912 913 void Bvh::CollectVisibleLeaves(BvhNode *node, BvhLeafContainer &leaves) 914 { 915 stack<BvhNode *> tStack; 916 tStack.push(node); 917 918 while (!tStack.empty()) 919 { 920 BvhNode *node = tStack.top(); 921 tStack.pop(); 922 923 if (IsWithinViewFrustum(node)) 924 { 925 if (!node->IsLeaf()) 926 { 927 BvhInterior *interior = static_cast<BvhInterior *>(node); 928 929 tStack.push(interior->mFront); 930 tStack.push(interior->mBack); 931 } 932 else 933 { 934 leaves.push_back(static_cast<BvhLeaf *>(node)); 935 } 936 } 937 } 938 } 939 940 941 BvhLeaf *Bvh::GetRandomLeaf(BvhNode *node) 942 { 943 stack<BvhNode *> nodeStack; 944 945 nodeStack.push(node); 946 947 int mask = rand(); 948 949 while (!nodeStack.empty()) 950 { 951 BvhNode *node = nodeStack.top(); 952 nodeStack.pop(); 953 954 if (node->IsLeaf()) 955 { 956 // random leaf 957 return static_cast<BvhLeaf *>(node); 958 } 959 else 960 { 961 BvhInterior *interior = static_cast<BvhInterior *>(node); 962 963 BvhNode *next; 964 965 // random decision 966 if (mask & 1) 967 next = interior->mBack; 968 else 969 next = interior->mFront; 970 971 mask = mask >> 1; 972 973 nodeStack.push(next); 974 } 975 } 976 977 // should never come here 978 return NULL; 979 } 980 981 982 BvhLeaf *Bvh::GetRandomVisibleLeaf(BvhNode *node) 983 { 984 BvhLeafContainer leaves; 985 leaves.reserve(node->GetNumLeaves()); 986 987 CollectVisibleLeaves(node, leaves); 988 989 if (leaves.empty()) 990 return NULL; 991 992 const int r = (int)(((float)rand() / RAND_MAX) * ((float)leaves.size() - 0.5f)); 993 994 return leaves[r]; 995 } 996 997 998 void Bvh::CollectGeometry(BvhNode *node, GeometryVector &geometry) 999 { 1000 //geometry.reserve(node->CountPrimitives()); 1001 1002 for (int i = node->mFirst; i <= node->mLast; ++ i) 1003 { 1004 geometry.push_back(mGeometry[i]); 1005 } 1006 } 1007 1008 1009 NodeGeometry **Bvh::GetGeometry(BvhNode *node, int &geometrySize) 308 SceneEntity **Bvh::GetGeometry(BvhNode *node, int &geometrySize) 1010 309 { 1011 310 geometrySize = node->CountPrimitives(); … … 1014 313 1015 314 1016 void Bvh::UpdateInteriors(BvhNode *node) 1017 { 1018 if (!node->IsLeaf()) 1019 { 1020 BvhInterior *interior = static_cast<BvhInterior *> (node); 1021 1022 // update the indices of the geometry so we can render interiors as well 1023 UpdateInteriors(interior->GetBack()); 1024 UpdateInteriors(interior->GetFront()); 1025 1026 // update area 1027 interior->mFirst = min(interior->GetBack()->mFirst, interior->GetFront()->mFirst); 1028 interior->mLast = max(interior->GetBack()->mLast, interior->GetFront()->mLast); 1029 1030 interior->mArea = interior->GetBack()->mArea + interior->GetFront()->mArea; 1031 } 1032 } 1033 1034 1035 int Bvh::IsWithinViewFrustumLocal(BvhNode *node) 315 int Bvh::IsWithinViewFrustum(BvhNode *node) 1036 316 { 1037 317 bool bIntersect = false; … … 1050 330 { 1051 331 //-- test the n-vertex 1052 if (node->mBox. getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f)332 if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 0], sFrustum.mClipPlanes[i]) > 0.0f) 1053 333 { 1054 334 //-- outside … … 1058 338 1059 339 //-- test the p-vertex 1060 if (node->mBox. getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)340 if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 1], sFrustum.mClipPlanes[i]) <= 0.0f) 1061 341 { 1062 342 //-- completely inside: children don't need to check against this plane no more … … 1079 359 { 1080 360 //-- test the n-vertex 1081 if (node->mBox. getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f)361 if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 0], sFrustum.mClipPlanes[i]) > 0.0f) 1082 362 { 1083 363 // outside … … 1087 367 1088 368 //-- test the p-vertex 1089 if (node->mBox. getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)369 if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 1], sFrustum.mClipPlanes[i]) <= 0.0f) 1090 370 { 1091 371 // completely inside: children don't need to check against this plane no more … … 1103 383 1104 384 1105 int Bvh::IsWithinViewFrustum(const BoundingBox &box, const int planeMask, const int preferredPlane) 1106 { 1107 bool bIntersect = false; 1108 1109 //////// 1110 //-- do the view frustum culling for the planes [mPreferredPlane - 5] 1111 1112 for (int i = preferredPlane; i < 6; ++ i) 1113 { 1114 //-- do the test only if necessary 1115 if (planeMask & (1 << i)) 1116 { 1117 //-- test the n-vertex 1118 if (box.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f) 1119 return 0; 1120 1121 //-- test the p-vertex 1122 if (!(box.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)) 1123 bIntersect = true; 1124 } 1125 } 1126 1127 ////////// 1128 //-- do the view frustum culling for the planes [0 - m_iPreferredPlane) 1129 1130 for (int i = 0; i < preferredPlane; ++ i) 1131 { 1132 // do the test only if necessary 1133 if (planeMask & (1 << i)) 1134 { 1135 //-- test the n-vertex 1136 if (box.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f) 1137 // outside 1138 return 0; 1139 1140 //-- test the p-vertex 1141 if (!(box.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)) 1142 bIntersect = true; 1143 } 1144 } 1145 1146 return bIntersect ? -1 : 1; 1147 } 1148 1149 1150 int Bvh::IsWithinViewFrustum(BvhNode *node) 1151 { 1152 if (node->mCache.mLastFrustumTestedFrameId == mFrameId) 1153 { 1154 return node->mCache.mFrustumCulled; 1155 } 1156 1157 node->mCache.mLastFrustumTestedFrameId = mFrameId; 1158 1159 timeViewFrustumCulling.Entry(); 1160 1161 if (Settings::Global()->get_nvocc_use_tighter_bounds_for_frustum_culling()) 1162 { 1163 const int intersect = IsWithinViewFrustumLocal(node); 1164 1165 if ((node->mNumTestNodes == 1) || (intersect != -1)) 1166 { 1167 //OUT1("x"); 1168 node->mCache.mFrustumCulled = intersect; 1169 } 1170 else 1171 { 1172 // maybe intersecting one of the tighter boxes 1173 node->mCache.mFrustumCulled = 0; 1174 1175 for (int i = 0; i < node->mNumTestNodes; ++ i) 1176 { 1177 RenderableHierarchyNode *n = mTestNodes[node->mTestNodesIdx + i]; 1178 1179 if (IsWithinViewFrustum(n->GetBox(), 1180 node->mPlaneMask, 1181 node->mPreferredPlane)) 1182 { 1183 node->mCache.mFrustumCulled = -1; 1184 break; 1185 } 1186 } 1187 } 1188 } 1189 else 1190 { 1191 //OUT1("y"); 1192 node->mCache.mFrustumCulled = IsWithinViewFrustumLocal(node); 1193 } 1194 1195 timeViewFrustumCulling.Exit(); 1196 1197 return node->mCache.mFrustumCulled; 1198 } 1199 1200 1201 void Bvh::InitFrame(Camera *camera, const int currentFrameId, Viewer *viewer) 385 void Bvh::InitFrame(Camera *camera, int currentFrameId) 1202 386 { 1203 387 // = 0011 1111 which means that at the beginning, all six planes have to frustum culled … … 1207 391 mFrameId = currentFrameId; 1208 392 1209 // to begin with, we must grab the plane equations of the six clipplanes of the viewfrustum 1210 Matrix4f matViewing, matProjectionView; 1211 Transform3D transform; 1212 1213 camera->GetTransform(transform); 1214 transform.get(matViewing); 1215 1216 camera->GetProjectionMatrix(matProjectionView); 1217 matProjectionView *= matViewing; 1218 1219 Vec3f vec; 1220 float fInvLength; 1221 1222 1223 ////////// 1224 //-- extract the plane equations 1225 1226 for (int i = 0; i < 4; ++ i) 1227 { 1228 mFrustum.mClipPlane[0][i] = matProjectionView[i][3] - matProjectionView[i][0]; // right plane 1229 mFrustum.mClipPlane[1][i] = matProjectionView[i][3] + matProjectionView[i][0]; // left plane 1230 mFrustum.mClipPlane[2][i] = matProjectionView[i][3] + matProjectionView[i][1]; // bottom plane 1231 mFrustum.mClipPlane[3][i] = matProjectionView[i][3] - matProjectionView[i][1]; // top plane 1232 mFrustum.mClipPlane[4][i] = matProjectionView[i][3] - matProjectionView[i][2]; // far plane 1233 mFrustum.mClipPlane[5][i] = matProjectionView[i][3] + matProjectionView[i][2]; // near plane 1234 } 1235 1236 //////////// 1237 //-- normalize the coefficients and find the indices of the n- and p-vertices 1238 1239 for (int i = 0; i < 6; ++ i) 1240 { 1241 // the clipping planes look outward the frustum, 1242 // so distances > 0 mean that a point is outside 1243 fInvLength = -1.0f / sqrt( mFrustum.mClipPlane[i][0] * mFrustum.mClipPlane[i][0] + 1244 mFrustum.mClipPlane[i][1] * mFrustum.mClipPlane[i][1] + 1245 mFrustum.mClipPlane[i][2] * mFrustum.mClipPlane[i][2]); 1246 1247 mFrustum.mClipPlane[i][0] *= fInvLength; 1248 mFrustum.mClipPlane[i][1] *= fInvLength; 1249 mFrustum.mClipPlane[i][2] *= fInvLength; 1250 mFrustum.mClipPlane[i][3] *= fInvLength; 1251 1252 vec.x = mFrustum.mClipPlane[i][0]; 1253 vec.y = mFrustum.mClipPlane[i][1]; 1254 vec.z = mFrustum.mClipPlane[i][2]; 1255 1256 // n-vertex 1257 mClipPlaneAABBVertexIndices[i][0] = BoundingBox::getIndexNearestVertex(vec); 1258 // p-vertex 1259 mClipPlaneAABBVertexIndices[i][1] = BoundingBox::getIndexFurthestVertex(vec); 1260 } 1261 1262 1263 const float aspect = mCamera->GetAspect(); 1264 const float fov = mCamera->GetFov(); 1265 1266 mScale = sqrt(aspect) * 2.0f * tan(fov * mypi / 180.0f); 1267 1268 mNearPlane = mCamera->GetRealViewDirection(); 1269 mNearPlaneD = - mNearPlane * (mCamera->GetPosition() - Origin3f); 393 mCamera->CalcFrustum(sFrustum); 394 sFrustum.CalcNPVertexIndices(sClipPlaneAABBVertexIndices); 395 396 // calc near plane 397 sNearPlane = Plane3(mCamera->GetDirection(), 398 -mCamera->GetDirection() * mCamera->GetPosition()); 1270 399 } 1271 400 … … 1273 402 float Bvh::CalcDistance(BvhNode *node) const 1274 403 { 1275 timeDistance.Entry(); 1276 1277 float distance; 1278 1279 #if USE_TIGHTER_BOUNDS_FOR_ALL 1280 float minDist = 1e25f; 1281 1282 //OUT1("testing " << mNumTestNodes << " nodes"); 1283 for (int i = 0; i < node->mNumTestNodes; ++ i) 1284 { 1285 RenderableHierarchyNode *hnode = mTestNodes[node->mTestNodesIdx + i]; 1286 1287 if(hnode->mCache.mLastDistanceTestedFrameId < mFrameId) 1288 { 1289 hnode->mCache.mDistance = 1290 hnode->GetBox().getMinVisibleDistance(mNearPlane, mNearPlaneD); 1291 hnode->mCache.mLastDistanceTestedFrameId = mFrameId; 1292 } 1293 1294 if (hnode->mCache.mDistance < minDist) 1295 minDist = hnode->mCache.mDistance; 1296 } 1297 1298 distance = minDist; 1299 1300 #else 1301 1302 if(node->mCache.mLastDistanceTestedFrameId != mFrameId) 1303 { 1304 //OUT1("z " << node->mLastDistanceTestedFrameId << " " << mFrameId); 1305 node->mCache.mDistance = node->GetBox().getMinVisibleDistance(mNearPlane, mNearPlaneD); 1306 node->mCache.mLastDistanceTestedFrameId = mFrameId; 1307 } 1308 1309 distance = node->mCache.mDistance; 1310 #endif 1311 1312 timeDistance.Exit(); 1313 1314 return distance; 1315 } 1316 1317 1318 float Bvh::GetSquareDistance(BvhNode *node) const 1319 { 1320 timeDistance.Entry(); 1321 1322 float distance; 1323 1324 #if USE_TIGHTER_BOUNDS_FOR_ALL 1325 const Vector3f nearplane = mCamera->GetRealViewDirection(); 1326 const float nearplaneD = - nearplane * (mCamera->GetPosition() - Origin3f); 1327 1328 float minDist = 1e25f; 1329 1330 //OUT1("testing " << mNumTestNodes << " nodes"); 1331 for (int i = 0; i < node->mNumTestNodes; ++ i) 1332 { 1333 RenderableHierarchyNode *hnode = mTestNodes[node->mTestNodesIdx + i]; 1334 const float dist = GetMinSquareDistance(hnode->GetBox()); 1335 1336 if (dist < minDist) 1337 minDist = dist; 1338 } 1339 1340 distance = minDist; 1341 #else 1342 distance = GetMinSquareDistance(node->GetBox()); 1343 #endif 1344 1345 timeDistance.Exit(); 1346 1347 return distance; 1348 } 1349 1350 1351 float Bvh::GetMinSquareDistance(const BoundingBox &box) const 1352 { 1353 float minDist = 1e25f; 1354 1355 const Point3f *pts = (const Point3f *)box.getVertexData(); 1356 const Point3f pos = mCamera->GetPosition(); 1357 1358 for (int i = 0; i < 8; ++ i) 1359 { 1360 const float newDist = DistanceSquared(pts[i], pos); 1361 1362 if (newDist < minDist) 1363 minDist = newDist; 1364 } 1365 1366 return minDist; 1367 } 1368 1369 1370 bool Bvh::ExportBinTree(const string &filename) 1371 { 1372 ofstream stream(filename.c_str(), ifstream::binary); 1373 1374 if (!stream.is_open()) return false; 1375 1376 OUT1("exporting bvh"); 1377 1378 std::queue<BvhNode *> tStack; 1379 tStack.push(mRoot); 1380 1381 while(!tStack.empty()) 1382 { 1383 BvhNode *node = tStack.front(); 1384 tStack.pop(); 1385 1386 if (node->IsLeaf()) 1387 { 1388 //OUT1("l"); 1389 ExportBinLeaf(stream, static_cast<BvhLeaf *>(node)); 1390 } 1391 else 1392 { 1393 //OUT1("i"); 1394 BvhInterior *interior = static_cast<BvhInterior *>(node); 1395 1396 ExportBinInterior(stream, interior); 1397 1398 tStack.push(interior->mFront); 1399 tStack.push(interior->mBack); 1400 } 1401 } 1402 1403 OUT1("... finished"); 1404 1405 return true; 1406 } 1407 1408 1409 void Bvh::ExportBinLeaf(ofstream &stream, BvhLeaf *leaf) 1410 { 1411 int type = TYPE_LEAF; 1412 int first = leaf->mFirst; 1413 int last = leaf->mLast; 1414 1415 stream.write(reinterpret_cast<char *>(&type), sizeof(int)); 1416 stream.write(reinterpret_cast<char *>(&first), sizeof(int)); 1417 stream.write(reinterpret_cast<char *>(&last), sizeof(int)); 1418 } 1419 1420 1421 void Bvh::ExportBinInterior(ofstream &stream, BvhInterior *interior) 1422 { 1423 int type = TYPE_INTERIOR; 1424 stream.write(reinterpret_cast<char *>(&type), sizeof(int)); 1425 stream.write(reinterpret_cast<char *>(&interior->mAxis), sizeof(char)); 1426 stream.write(reinterpret_cast<char *>(&interior->mPosition), sizeof(float)); 1427 } 1428 1429 1430 BvhLeaf *Bvh::ImportBinLeaf(ifstream &stream, BvhInterior *parent) 1431 { 1432 BvhLeaf *leaf = new BvhLeaf(parent); 1433 1434 int first, last; 1435 1436 stream.read(reinterpret_cast<char *>(&first), sizeof(int)); 1437 stream.read(reinterpret_cast<char *>(&last), sizeof(int)); 1438 1439 leaf->mFirst = first; 1440 leaf->mLast = last; 1441 1442 return leaf; 1443 } 1444 1445 1446 BvhInterior *Bvh::ImportBinInterior(ifstream &stream, BvhInterior *parent) 1447 { 1448 BvhInterior *interior = new BvhInterior(parent); 1449 1450 stream.read(reinterpret_cast<char *>(&interior->mAxis), sizeof(char)); 1451 stream.read(reinterpret_cast<char *>(&interior->mPosition), sizeof(float)); 1452 1453 return interior; 1454 } 1455 1456 1457 BvhNode *Bvh::LoadNextNode(ifstream &stream, BvhInterior *parent) 1458 { 1459 int nodeType; 1460 stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int)); 1461 1462 if (nodeType == TYPE_LEAF) 1463 { 1464 //OUT1("l"); 1465 return ImportBinLeaf(stream, static_cast<BvhInterior *>(parent)); 1466 } 1467 1468 if (nodeType == TYPE_INTERIOR) 1469 { 1470 //OUT1("i"); 1471 return ImportBinInterior(stream, static_cast<BvhInterior *>(parent)); 1472 } 1473 1474 return NULL; 1475 } 1476 1477 1478 Bvh *Bvh::LoadFromFile(const string &filename, const GeometryVector &geom) 1479 { 1480 // export binary version of mesh 1481 queue<BvhNode *> tStack; 1482 ifstream stream(filename.c_str(), ifstream::binary); 1483 1484 if (!stream.is_open()) return NULL; 1485 1486 OUT1("loading bvh"); 1487 Bvh *bvh = new Bvh(); 1488 1489 bvh->mGeometrySize = geom.size(); 1490 bvh->mGeometry = new NodeGeometry*[bvh->mGeometrySize]; 1491 1492 for (size_t i = 0; i < bvh->mGeometrySize; ++ i) 1493 bvh->mGeometry[i] = geom[i]; 1494 1495 bvh->mRoot = bvh->LoadNextNode(stream, NULL); 1496 1497 tStack.push(bvh->mRoot); 1498 bvh->mNumNodes = 1; 1499 1500 while(!tStack.empty()) 1501 { 1502 BvhNode *node = tStack.front(); 1503 tStack.pop(); 1504 1505 if (!node->IsLeaf()) 1506 { 1507 bvh->mNumNodes += 2; 1508 1509 BvhInterior *interior = static_cast<BvhInterior *>(node); 1510 1511 BvhNode *front = bvh->LoadNextNode(stream, interior); 1512 BvhNode *back = bvh->LoadNextNode(stream, interior); 1513 1514 interior->mFront = front; 1515 interior->mBack = back; 1516 1517 front->mDepth = interior->mDepth + 1; 1518 back->mDepth = interior->mDepth + 1; 1519 1520 tStack.push(front); 1521 tStack.push(back); 1522 } 1523 } 1524 1525 OUT1("... finished loading " << bvh->mNumNodes << " nodes, updating boxes"); 1526 1527 //adjust bounding boxes 1528 bvh->UpdateBoxes(bvh->mRoot); 1529 bvh->UpdateNumLeaves(bvh->mRoot); 1530 1531 // compute unique ids 1532 bvh->ComputeIds(); 1533 // update the indices of the geometry so we can render interiors as well 1534 bvh->UpdateInteriors(bvh->mRoot); 1535 // do this once so at least the current node bounding box is tested 1536 bvh->RecomputeBounds(); 1537 1538 return bvh; 1539 } 1540 1541 1542 float Bvh::ComputeScreenSpaceProjection(BvhNode *node) const 1543 { 1544 #if 0 1545 int projection = 0; 1546 1547 for (int i = 0; i < node->mNumTestNodes; ++ i) 1548 { 1549 RenderableHierarchyNode *n = mTestNodes[node->mTestNodesIdx + i]; 1550 1551 if(hnode->.mCache.mLastProjectionFrameId < mFrameId) 1552 { 1553 hnode->mCache.mProjection = 1554 ComputeScreenSpaceProjection(hnode->GetBox()); 1555 hnode->mCache.mLastProjectionFrameId = mCurrentFrameId; 1556 } 1557 1558 projection += hnode->mCache.mProjection; 1559 } 1560 1561 return projection; 1562 1563 #else 1564 1565 if(node->mCache.mLastProjectionFrameId < mFrameId) 1566 { 1567 node->mCache.mProjection = 1568 ComputeScreenSpaceProjection(node->GetBox()); 1569 node->mCache.mLastProjectionFrameId = mFrameId; 1570 } 1571 1572 return node->mCache.mProjection; 1573 #endif 1574 } 1575 1576 1577 float Bvh::ComputeScreenSpaceProjection(const BoundingBox &box) const 1578 { 1579 #if 0 1580 const float dist = CalcDistance(box); 1581 #else 1582 //const float dist = sqrt(GetMinSquareDistance(box)); 1583 const float dist = Distance(mCamera->GetPosition(), box.getCenter()); 1584 #endif 1585 1586 const float scale = dist ? dist * mScale : 1e-6; 1587 const float f = 1.0f / scale; 1588 const float coverage = f * f * box.getSurface() / 6.0f; 1589 1590 #if 0 1591 OUT1("scale: " << scale); 1592 OUT1("box: " << box.getSurface()); 1593 OUT1("aspect: " << aspect); 1594 OUT1("fov: " << fov); 1595 OUT1("tan: " << tan(fov * mypi / 180.0f)); 1596 //OUT1("w: " << w << " h: " << h); 1597 OUT1("cov: " << coverage << " pix: " << coverage * w * h << " f: " << f); 1598 #endif 1599 return coverage; 404 return node->GetBox().GetMinVisibleDistance(sNearPlane); 1600 405 } 1601 406 … … 1603 408 void Bvh::RenderBoundingBox(BvhNode *node) 1604 409 { 1605 #if 11606 410 static BvhNodeContainer dummy(1); 1607 411 dummy[0] = node; 1608 412 RenderBoundingBoxes(dummy); 1609 #else 1610 RenderBoxIndividual(node); 1611 #endif 1612 } 1613 1614 1615 void Bvh::RenderBoundingBoxImmediate(const BoundingBox &box, const bool restartStrip) 1616 { 1617 const Point3f *pU = box.getUpperPtr(); 1618 const Point3f *pL = box.getLowerPtr(); 1619 1620 /////////// 1621 //-- render AABB as triangle strips 1622 1623 glVertex3f(pL->x, pL->y, pU->z); 1624 glVertex3f(pU->x, pL->y, pU->z); 1625 glVertex3f(pL->x, pU->y, pU->z); 1626 glVertex3f(pU->x, pU->y, pU->z); 1627 glVertex3f(pL->x, pU->y, pL->z); 1628 glVertex3f(pU->x, pU->y, pL->z); 1629 glVertex3f(pL->x, pL->y, pL->z); 1630 glVertex3f(pU->x, pL->y, pL->z); 1631 1632 glPrimitiveRestartNV(); 1633 1634 //-- render second half of AABB 1635 glVertex3f(pL->x, pU->y, pU->z); 1636 glVertex3f(pL->x, pU->y, pL->z); 1637 glVertex3f(pL->x, pL->y, pU->z); 1638 glVertex3f(pL->x, pL->y, pL->z); 1639 glVertex3f(pU->x, pL->y, pU->z); 1640 glVertex3f(pU->x, pL->y, pL->z); 1641 glVertex3f(pU->x, pU->y, pU->z); 1642 glVertex3f(pU->x, pU->y, pL->z); 1643 1644 1645 // restart for all but last node 1646 if (restartStrip) 1647 { 1648 glPrimitiveRestartNV(); 1649 } 1650 } 1651 1652 1653 int Bvh::RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes) 1654 { 1655 timeSetup.Entry(); 1656 int renderedBoxes = 0; 1657 1658 glBegin(GL_TRIANGLE_STRIP); 1659 1660 BvhNodeContainer::const_iterator bit, bit_end = nodes.end(); 1661 1662 for (bit = nodes.begin(); bit != bit_end; ++ bit) 1663 { 1664 BvhNode *node = *bit; 1665 1666 renderedBoxes += node->mNumTestNodes; 1667 #if 0 1668 const bool restartStrip = false; 1669 RenderBoundingBoxImmediate(node->GetBox(), restartStrip); 1670 #else 1671 //OUT1("nodes: " << node->mTestNodes.size() << " l: " << node->IsLeaf()); 1672 for (int i = 0; i < node->mNumTestNodes; ++ i) 1673 { 1674 RenderableHierarchyNode *testNode = mTestNodes[node->mTestNodesIdx + i]; 1675 const BoundingBox &box = testNode->GetBox(); 1676 1677 // restart for all but last node 1678 const bool restartStrip = (bit != bit_end - 1) || (i != node->mNumTestNodes - 1); 1679 1680 RenderBoundingBoxImmediate(box, restartStrip); 1681 } 1682 #endif 1683 } 1684 glEnd(); 1685 timeSetup.Exit(); 413 } 414 415 416 417 int Bvh::RenderBoundingBoxes(const BvhNodeContainer &nodes) 418 { 419 int renderedBoxes = PrepareBoundingBoxesWithDrawArrays(nodes); 420 RenderBoundingBoxesWithDrawArrays(renderedBoxes); 1686 421 1687 422 return renderedBoxes; 1688 }1689 1690 1691 int Bvh::RenderBoundingBoxes(const BvhNodeContainer &nodes)1692 {1693 // always render in immediate mode if there is only one box to render1694 if (((nodes.size() == 1) && (nodes[0]->mNumTestNodes == 1)) ||1695 !Settings::Global()->get_nvocc_use_index_arrays())1696 {1697 // render bounding boxes individually1698 return RenderBoundingBoxesImmediate(nodes);1699 }1700 else1701 {1702 const int renderedBoxes =1703 PrepareBoundingBoxesWithDrawArrays(nodes);1704 RenderBoundingBoxesWithDrawArrays(renderedBoxes);1705 1706 return renderedBoxes;1707 }1708 423 } 1709 424 … … 1726 441 1727 442 /////////////// 1728 1729 timeSetup.Entry();1730 443 1731 444 int numNodes = 0; … … 1750 463 } 1751 464 1752 timeSetup.Exit();1753 1754 465 return numNodes; 1755 466 } 1756 467 1757 468 1758 void Bvh::RenderBoundingBoxesWithDrawArrays( constint numNodes)469 void Bvh::RenderBoundingBoxesWithDrawArrays(int numNodes) 1759 470 { 1760 471 ////// 1761 472 //-- Rendering the vbo 1762 1763 timeIssueDrawElements.Entry();1764 1765 473 if (useVbos) 1766 474 // set the vertex pointer to the vertex buffer … … 1774 482 // don't render first degenerate index 1775 483 glDrawElements(GL_TRIANGLE_STRIP, numElements, GL_UNSIGNED_INT, mIndices + 1); 1776 1777 timeIssueDrawElements.Exit();1778 484 } 1779 485 … … 1787 493 CollectNodes(mRoot, nodes); 1788 494 1789 OUT1("creating new indices");495 cout << "creating new indices" << endl; 1790 496 1791 497 int numMaxIndices = 0; … … 1804 510 1805 511 1806 OUT1("creating global indices buffer");512 cout << "creating global indices buffer" << endl; 1807 513 1808 514 if (mIndices) delete [] mIndices; … … 1831 537 for (int i = 0; i < node->mNumTestNodes; ++ i, numIndices += sNumIndicesPerBox) 1832 538 { 1833 RenderableHierarchyNode *testNode = mTestNodes[node->mTestNodesIdx + i];539 BvhNode *testNode = mTestNodes[node->mTestNodesIdx + i]; 1834 540 1835 541 // add indices to root node … … 1851 557 1852 558 559 /* 1853 560 void Bvh::ComputeIds() 1854 561 { … … 1856 563 // warning: root nodes local bvh are not in there, as they 1857 564 // are equivalent geometry bvh leaves 1858 HierarchyNodeContainer nodes;565 BvhNodeContainer nodes; 1859 566 CollectAllNodes(mRoot, nodes); 1860 567 … … 1868 575 } 1869 576 } 1870 577 */ 1871 578 1872 579 void Bvh::PrepareVertices() 1873 580 { 1874 // collect all nodes, also the nodes from local bvh 1875 // warning: root nodes local bvh are not in there, as they 1876 // are equivalent geometry bvh leaves 1877 HierarchyNodeContainer nodes; 581 // collect all nodes 582 BvhNodeContainer nodes; 1878 583 1879 584 nodes.reserve(GetNumNodes()); 1880 Collect AllNodes(mRoot, nodes);585 CollectNodes(mRoot, nodes); 1881 586 1882 587 const unsigned int bufferSize = 8 * (int)nodes.size(); 1883 mVertices = new Point3f[bufferSize];588 mVertices = new Vector3[bufferSize]; 1884 589 1885 590 int i = 0; 1886 591 1887 592 // store bounding box vertices 1888 HierarchyNodeContainer::const_iterator lit, lit_end = nodes.end();593 BvhNodeContainer::const_iterator lit, lit_end = nodes.end(); 1889 594 1890 595 for (lit = nodes.begin(); lit != lit_end; ++ lit, i += 8) 1891 596 { 1892 RenderableHierarchyNode *node = *lit; 1893 const Point3f *vertices = (const Point3f *)node->GetBox().getVertexData(); 597 BvhNode *node = *lit; 1894 598 1895 599 for (int j = 0; j < 8; ++ j) 1896 { 1897 ((Point3f *)mVertices)[node->GetId() * 8 + j] = vertices[j]; 1898 } 600 ((Vector3 *)mVertices)[node->GetId() * 8 + j] = node->GetBox().GetVertex(j); 1899 601 } 1900 602 … … 1906 608 1907 609 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1908 bufferSize * sizeof( Point3f),610 bufferSize * sizeof(Vector3), 1909 611 mVertices, 1910 612 GL_STATIC_DRAW_ARB); … … 1913 615 1914 616 // data handled by graphics driver from now on 1915 DEL APTR(mVertices);1916 1917 OUT1("***** created vbos *********");617 DEL_PTR(mVertices); 618 619 cout << "***** created vbos *********" << endl; 1918 620 } 1919 621 else … … 1922 624 glVertexPointer(3, GL_FLOAT, 0, mVertices); 1923 625 1924 OUT1("created vertices");1925 } 1926 } 1927 1928 1929 void Bvh::SetMaxDepthForTestingChildren( constint maxDepth)626 cout << "******* created vertex arrays ********" << endl; 627 } 628 } 629 630 631 void Bvh::SetMaxDepthForTestingChildren(int maxDepth) 1930 632 { 1931 633 if (maxDepth != mMaxDepthForTestingChildren) … … 1937 639 1938 640 1939 void Bvh::SetAreaRatioThresholdForTestingChildren( constfloat ratio)641 void Bvh::SetAreaRatioThresholdForTestingChildren(float ratio) 1940 642 { 1941 643 if (ratio != mAreaRatioThreshold) 1942 644 { 1943 645 mAreaRatioThreshold = ratio; 1944 RecomputeBounds();1945 }1946 }1947 1948 1949 void Bvh::SetVolRatioThresholdForTestingChildren(const float ratio)1950 {1951 if (ratio != mVolRatioThreshold)1952 {1953 mVolRatioThreshold = ratio;1954 RecomputeBounds();1955 }1956 }1957 1958 1959 void Bvh::SetUseTighterBoundsForTests(const bool tighterBoundsForTests)1960 {1961 if (mUseTighterBoundsOnlyForLeafTests != tighterBoundsForTests)1962 {1963 mUseTighterBoundsOnlyForLeafTests = tighterBoundsForTests;1964 RecomputeBounds();1965 }1966 }1967 1968 1969 void Bvh::SetCollectTighterBoundsWithMaxLevel(bool t)1970 {1971 if (mCollectTighterBoundsWithMaxLevel != t)1972 {1973 mCollectTighterBoundsWithMaxLevel = t;1974 646 RecomputeBounds(); 1975 647 } … … 1986 658 CollectNodes(mRoot, nodes); 1987 659 1988 OUT1("recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren); 1989 1990 if (mCollectTighterBoundsWithMaxLevel) 1991 OUT1("creating tighter bounds using max level"); 1992 else 1993 OUT1("creating tighter bounds using best set"); 660 cout << "recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren << endl; 1994 661 1995 662 int success = 0; … … 2000 667 BvhNode *node = *lit; 2001 668 2002 if (mCollectTighterBoundsWithMaxLevel) 2003 { 2004 //OUT1("creating tighter bounds using max level"); 2005 2006 // recreate list of nodes that will be tested as a proxy ... 2007 if (CreateNodeRenderList(node)) 2008 ++ success; 2009 } 2010 else 2011 { 2012 //OUT1("creating tighter bounds using best set"); 2013 2014 HierarchyNodeContainer hnodes; 2015 CollectBestNodes(node, hnodes); 2016 2017 // the new test nodes are added at the end of the vector 2018 node->mTestNodesIdx = mTestNodes.size(); 2019 2020 HierarchyNodeContainer::const_iterator cit; 2021 2022 // use the found nodes as nodes during the occlusion tests 2023 for (cit = hnodes.begin(); cit != hnodes.end(); ++ cit) 2024 { 2025 RenderableHierarchyNode *child = *cit; 2026 mTestNodes.push_back(child); 2027 } 2028 2029 node->mNumTestNodes = (int)hnodes.size(); 2030 } 2031 //OUT1("testnodes: " << node->mNumTestNodes); 2032 } 2033 2034 const float p = 100.0f * (float)success / nodes.size(); 2035 2036 OUT1("created tighter bounds for " << p << " percent of the nodes"); 669 // recreate list of nodes that will be tested as a proxy ... 670 if (CreateNodeRenderList(node)) 671 ++ success; 672 } 673 674 float p = 100.0f * (float)success / nodes.size(); 675 cout << "created tighter bounds for " << p << " percent of the nodes" << endl; 2037 676 2038 677 // recreate indices used for indirect mode rendering 2039 678 if (mIndices) 2040 {2041 679 CreateIndices(); 2042 }2043 680 } 2044 681 … … 2046 683 bool Bvh::CreateNodeRenderList(BvhNode *node) 2047 684 { 2048 HierarchyNodeContainer children; 2049 2050 if (mUseTighterBoundsOnlyForLeafTests && !node->IsLeaf()) 2051 { 2052 children.push_back(node); 2053 } 2054 else 2055 { 2056 // collect nodes that will be tested instead of the leaf node 2057 // in order to get a tighter bounding box test 2058 CollectNodes(node, mMaxDepthForTestingChildren, children); 2059 } 2060 685 BvhNodeContainer children; 686 687 // collect nodes that will be tested instead of the leaf node 688 // in order to get a tighter bounding box test 689 CollectNodes(node, children, mMaxDepthForTestingChildren); 690 2061 691 2062 692 // using the tighter bounds is not feasable in case … … 2068 698 float area = 0; 2069 699 2070 HierarchyNodeContainer::const_iterator cit;700 BvhNodeContainer::const_iterator cit; 2071 701 2072 702 for (cit = children.begin(); cit != children.end(); ++ cit) 2073 { 2074 RenderableHierarchyNode *c = *cit; 2075 2076 area += c->GetBox().getSurface(); 2077 vol += c->GetBox().getVolume(); 2078 } 2079 2080 const float volRatio = vol / node->GetBox().getVolume(); 2081 const float areaRatio = area / node->GetBox().getSurface(); 703 area += (*cit)->GetBox().SurfaceArea(); 704 705 const float areaRatio = area / node->GetBox().SurfaceArea(); 2082 706 2083 707 bool success; 2084 708 2085 if ((areaRatio < mAreaRatioThreshold) && 2086 (volRatio < mVolRatioThreshold)) 2087 { 709 if (areaRatio < mAreaRatioThreshold) 2088 710 success = true; 2089 }2090 711 else 2091 712 { … … 2098 719 2099 720 // the new test nodes are added at the end of the vector 2100 node->mTestNodesIdx = mTestNodes.size();721 node->mTestNodesIdx = (int)mTestNodes.size(); 2101 722 2102 723 // use the found nodes as nodes during the occlusion tests 2103 724 for (cit = children.begin(); cit != children.end(); ++ cit) 2104 725 { 2105 RenderableHierarchyNode *child = *cit;726 BvhNode *child = *cit; 2106 727 mTestNodes.push_back(child); 2107 728 } … … 2129 750 2130 751 2131 int Bvh::PostProcessLeaves(BvhLeafContainer &leaves)2132 {2133 OUT1("creating tighter bounds for leaves");2134 2135 BvhLeafContainer::const_iterator lit, lit_end = leaves.end();2136 2137 int i = 0;2138 int tighter = 0;2139 2140 for (lit = leaves.begin(); lit != lit_end; ++ lit, ++ i)2141 {2142 BvhLeaf *leaf = *lit;2143 2144 int triangleCount;2145 // collect the triangles from the stored geometry2146 Point3f *triangles = CollectTriangles(leaf, triangleCount);2147 2148 if (CreateTighterBoundsForLeaf(leaf, triangles, triangleCount))2149 ++ tighter;2150 2151 leaf->mArea = ComputeGeometryArea(leaf, triangles, triangleCount);2152 2153 delete [] triangles;2154 2155 if (i % 1000 == 999)2156 OUT1(i << " leaves processed ");2157 }2158 2159 const float p = 100.0f * tighter / leaves.size();2160 OUT1("created tighter bounds for " << p << " percent of the leaves");2161 2162 return tighter;2163 }2164 2165 2166 bool Bvh::CreateTighterBoundsForLeaf(BvhLeaf *leaf, Point3f *triangles, const int triangleCount)2167 {2168 // create a local bvh over the triangles2169 if (leaf->mTriangleBvh) delete leaf->mTriangleBvh;2170 2171 leaf->mTriangleBvh = new TriangleBvh((Triangle *)triangles, triangleCount);2172 2173 const int maxDepth = Settings::Global()->get_nvocc_local_bvh_max_depth();2174 const int maxTriangles = Settings::Global()->get_nvocc_local_bvh_max_triangles();2175 const int minArea = Settings::Global()->get_nvocc_local_bvh_min_area();2176 const int splitType = Settings::Global()->get_nvocc_local_bvh_split_type();2177 2178 leaf->mTriangleBvh->SetMaxDepth(maxDepth);2179 leaf->mTriangleBvh->SetMaxTriangles(maxTriangles);2180 leaf->mTriangleBvh->SetMinAreaRatio(minArea);2181 leaf->mTriangleBvh->SetSplitType(splitType);2182 2183 leaf->mTriangleBvh->SetVerboseOutput(false);2184 2185 // construct2186 leaf->mTriangleBvh->Construct();2187 2188 return true;2189 }2190 2191 2192 float Bvh::ComputeGeometryArea(BvhLeaf *leaf, Point3f *triangles, const int triangleCount) const2193 {2194 float area = 0;2195 2196 for (int i = 0; i < triangleCount; ++ i)2197 {2198 area += ((Triangle *)triangles)[i].GetArea();2199 }2200 2201 return area;2202 }2203 2204 2205 Point3f *Bvh::CollectTriangles(BvhLeaf *leaf, int &triangleCount)2206 {2207 // count triangles in the leaf2208 triangleCount = 0;2209 2210 for (int geomIdx = leaf->mFirst; geomIdx <= leaf->mLast; ++ geomIdx)2211 {2212 Shape3D *sh = static_cast<Shape3D *>(mGeometry[geomIdx]->GetNode());2213 IndexedTriangleStripArray *strips = static_cast<IndexedTriangleStripArray *>(sh->getGeometry());2214 2215 triangleCount += strips->getNumTriangles();2216 }2217 2218 Triangle *triangles = new Triangle[triangleCount];2219 //OUT1("The leaf contains " << triangleCount << " triangles in " << (int)geometry.size() << " nodes");2220 2221 int currentIdx = 0;2222 2223 for (int geomIdx = leaf->mFirst; geomIdx <= leaf->mLast; ++ geomIdx)2224 {2225 NodeGeometry *geom = mGeometry[geomIdx];2226 2227 Shape3D *sh = static_cast<Shape3D *>(geom->GetNode());2228 2229 IndexedTriangleStripArray *strips =2230 static_cast<IndexedTriangleStripArray *>(sh->getGeometry());2231 2232 // get indices of containted triangles (strips are converted before)2233 int *indices;2234 2235 int tCount = strips->getNumTriangles();2236 int indexCount = tCount * 3;2237 2238 // compute triangles from strips2239 Point3f *coordinates = (Point3f *)strips->getCoordRef3f();2240 strips->getTriangleCoordinateIndices(0, &indices, indexCount);2241 2242 for (int i = 0; i < tCount; ++ i)2243 {2244 triangles[i + currentIdx].mVertices[0] = coordinates[indices[i * 3 + 0]];2245 triangles[i + currentIdx].mVertices[1] = coordinates[indices[i * 3 + 1]];2246 triangles[i + currentIdx].mVertices[2] = coordinates[indices[i * 3 + 2]];2247 2248 if (geom->mMatId != NV_RenderPredictorRenderAction::NO_MAT)2249 {2250 const Matrix4f &m = mRenderer->app_mats[geom->mMatId];2251 Transform3D tf(m);2252 tf.transform(triangles[i + currentIdx].mVertices[0]);2253 tf.transform(triangles[i + currentIdx].mVertices[1]);2254 tf.transform(triangles[i + currentIdx].mVertices[2]);2255 }2256 }2257 2258 currentIdx += tCount;2259 }2260 2261 return (Point3f *)triangles;2262 }2263 2264 2265 752 int Bvh::CountTriangles(BvhLeaf *leaf) const 2266 753 { … … 2268 755 2269 756 for (int i = leaf->mFirst; i <= leaf->mLast; ++ i) 2270 { 2271 triangleCount += mGeometry[i]->mNumTriangles; 2272 } 2273 757 triangleCount += mGeometry[i]->GetGeometry()->CountTriangles(); 758 2274 759 return triangleCount; 2275 760 } … … 2290 775 BvhLeaf *leaf = static_cast<BvhLeaf *>(node); 2291 776 2292 mBvhStats.mLeafSA += leaf->mBox.getSurface(); 2293 mBvhStats.mLeafVol += leaf->mBox.getVolume(); 2294 2295 TriangleBvh::TriangleBvhStats tStats; 2296 leaf->mTriangleBvh->GetBvhStats(tStats); 2297 2298 mBvhStats.mBoundsLeafSA += tStats.mLeafSA; 2299 mBvhStats.mBoundsInteriorSA += tStats.mInteriorSA; 2300 2301 mBvhStats.mBoundsLeafVol += tStats.mLeafVol; 2302 mBvhStats.mBoundsInteriorVol += tStats.mInteriorVol; 2303 2304 mBvhStats.mBoundsLeavesCount += leaf->mTriangleBvh->GetNumLeaves(); 777 mBvhStats.mLeafSA += leaf->mBox.SurfaceArea(); 778 mBvhStats.mLeafVol += leaf->mBox.GetVolume(); 2305 779 } 2306 780 else 2307 781 { 2308 mBvhStats.mInteriorSA += node->mBox. getSurface();2309 mBvhStats.mInteriorVol += node->mBox. getVolume();782 mBvhStats.mInteriorSA += node->mBox.SurfaceArea(); 783 mBvhStats.mInteriorVol += node->mBox.GetVolume(); 2310 784 2311 785 BvhInterior *interior = static_cast<BvhInterior *>(node); … … 2323 797 void Bvh::PrintBvhStats() const 2324 798 { 2325 //OUT1("triangle bvh surface " << mBvhStats.mBoundsLeafSA); 2326 //OUT1("triangle bvh volume " << mBvhStats.mBoundsLeafVol); 2327 2328 OUT1("bvh stats:"); 2329 OUT1("interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.getSurface()); 2330 OUT1("leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.getSurface()); 2331 OUT1("interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.getVolume()); 2332 OUT1("leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.getVolume() << "\n"); 2333 2334 OUT1("boundsInteriorNodesSA = " << mBvhStats.mBoundsInteriorSA / mBvhStats.mLeafSA); 2335 OUT1("boundsLeafNodesSA = " << mBvhStats.mBoundsLeafSA / mBvhStats.mLeafSA); 2336 OUT1("boundsInteriorNodesVolume = " << mBvhStats.mBoundsInteriorVol / mBvhStats.mLeafVol); 2337 OUT1("boundsLeafNodesVolume = " << mBvhStats.mBoundsLeafVol / mBvhStats.mLeafVol << "\n"); 2338 2339 OUT1("boundsLeaves: " << (float)mBvhStats.mBoundsLeavesCount / (float)GetNumLeaves() << "\n"); 2340 OUT1("geometry per leaf: " << mBvhStats.mGeometryRatio); 2341 OUT1("triangles per leaf: " << mBvhStats.mTriangleRatio); 2342 OUT1(""); 2343 } 2344 2345 2346 static void RenderBoxForViz(const BoundingBox &box) 2347 { 2348 glBegin(GL_LINE_LOOP); 2349 glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 2350 glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 2351 glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 2352 glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 2353 glEnd(); 2354 2355 glBegin(GL_LINE_LOOP); 2356 glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 2357 glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 2358 glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 2359 glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 2360 glEnd(); 2361 2362 glBegin(GL_LINE_LOOP); 2363 glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 2364 glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 2365 glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 2366 glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 2367 glEnd(); 2368 2369 glBegin(GL_LINE_LOOP); 2370 glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 2371 glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 2372 glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 2373 glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 2374 glEnd(); 2375 2376 glBegin(GL_LINE_LOOP); 2377 glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 2378 glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 2379 glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 2380 glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 2381 glEnd(); 2382 2383 glBegin(GL_LINE_LOOP); 2384 glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 2385 glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 2386 glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 2387 glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 2388 2389 glEnd(); 2390 } 2391 2392 2393 void Bvh::RenderBoundingBoxesForViz(const int mode) 2394 { 2395 BvhLeafContainer leaves; 2396 leaves.reserve(mRoot->GetNumLeaves()); 2397 2398 CollectLeaves(mRoot, leaves); 2399 2400 BvhLeafContainer::const_iterator it, it_end = leaves.end(); 2401 2402 for (it = leaves.begin(); it != it_end; ++ it) 2403 { 2404 BvhLeaf *leaf = *it; 2405 2406 if ((mode == 0) || (mode == 2)) 2407 { 2408 glColor3f(1.0f, 1.0f, 1.0f); 2409 RenderBoxForViz(leaf->GetBox()); 2410 } 2411 2412 if ((mode == 1) || (mode == 2)) 2413 { 2414 glColor3f(1.0f, 0, 0); 2415 for (int i = 0; i < leaf->mNumTestNodes; ++ i) 2416 { 2417 RenderBoxForViz(mTestNodes[leaf->mTestNodesIdx + i]->GetBox()); 2418 } 2419 } 2420 } 799 cout << "bvh stats:" << endl; 800 cout << "interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.SurfaceArea() << endl; 801 cout << "leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.SurfaceArea() << endl; 802 cout << "interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.GetVolume() << endl; 803 cout << "leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.GetVolume() << endl; 804 805 cout << "boundsInteriorNodesSA = " << mBvhStats.mBoundsInteriorSA / mBvhStats.mLeafSA << endl; 806 cout << "boundsLeafNodesSA = " << mBvhStats.mBoundsLeafSA / mBvhStats.mLeafSA << endl; 807 cout << "boundsInteriorNodesVolume = " << mBvhStats.mBoundsInteriorVol / mBvhStats.mLeafVol << endl; 808 cout << "boundsLeafNodesVolume = " << mBvhStats.mBoundsLeafVol / mBvhStats.mLeafVol << "\n" << endl; 809 810 cout << "boundsLeaves: " << (float)mBvhStats.mBoundsLeavesCount / (float)GetNumLeaves() << "\n" << endl; 811 cout << "geometry per leaf: " << mBvhStats.mGeometryRatio << endl; 812 cout << "triangles per leaf: " << mBvhStats.mTriangleRatio << endl; 2421 813 } 2422 814 … … 2428 820 for (int i = node->mFirst; i <= node->mLast; ++ i) 2429 821 { 2430 numTriangles += mGeometry[i]-> mNumTriangles;822 numTriangles += mGeometry[i]->GetGeometry()->CountTriangles(); 2431 823 } 2432 824 … … 2440 832 } 2441 833 2442 2443 float Bvh::GetAvgDepth() const 2444 { 2445 return mAvgDepth; 2446 } 2447 2448 2449 static float GetNodePriority(RenderableHierarchyNode *node) 2450 { 2451 if (node->IsLeaf()) 2452 return 0.0f; 2453 2454 float result; 2455 2456 if (node->GetType() == BVH_NODE) 2457 { 2458 BvhInterior *interior = static_cast<BvhInterior *>(node); 2459 2460 // evaluate the priority of this node 2461 const float correctionFactor = 0.0f; 2462 // 1.0f*interior->box.FaceArea(node->axis); 2463 2464 result = 2465 interior->GetBox().getSurface() - 2466 (interior->GetBack()->GetBox().getSurface() + interior->GetFront()->GetBox().getSurface()) + 2467 correctionFactor; 2468 } 2469 else 2470 { 2471 TriangleBvhInterior *interior = static_cast<TriangleBvhInterior *>(node); 2472 2473 // evaluate the priority of this node 2474 const float correctionFactor = 0.0f; 2475 // 1.0f*interior->box.FaceArea(node->axis); 2476 2477 result = 2478 interior->GetBox().getSurface() - 2479 (interior->GetBack()->GetBox().getSurface() + interior->GetFront()->GetBox().getSurface()) + 2480 correctionFactor; 2481 } 2482 2483 return result; 2484 } 2485 2486 2487 struct NodeEntry 2488 { 2489 NodeEntry(RenderableHierarchyNode *node, float p): mNode(node), mPriority(p) 2490 {} 2491 2492 RenderableHierarchyNode *mNode; 2493 float mPriority; 2494 }; 2495 2496 2497 bool operator<(const NodeEntry &a, const NodeEntry &b) 2498 { 2499 return a.mPriority < b.mPriority; 2500 } 2501 2502 2503 void Bvh::CollectBestNodes(RenderableHierarchyNode *node, HierarchyNodeContainer &nodes) 2504 { 2505 int maxNodes = 32; 2506 priority_queue<NodeEntry> nodeStack; 2507 2508 nodeStack.push(NodeEntry(node, GetNodePriority(node))); 2509 nodes.clear(); 2510 2511 float SA = node->GetBox().getSurface(); 2512 float saThreshold = 1.1f * SA; 2513 int numNodes = 1; 2514 OUT1(numNodes << " " << SA); 2515 2516 while (!nodeStack.empty() && 2517 int(nodes.size() + nodeStack.size()) < maxNodes) 2518 { 2519 NodeEntry entry = nodeStack.top(); 2520 nodeStack.pop(); 2521 2522 RenderableHierarchyNode *current = entry.mNode; 2523 2524 if (current->IsLeaf()) 2525 { 2526 // check if there further subdivision on triangle level 2527 if ((current->GetType() == BVH_NODE) && (((BvhLeaf *)current)->mTriangleBvh->GetNumNodes() > 1)) 2528 { 2529 // push back the root of the local bvh 2530 nodeStack.push(NodeEntry(((BvhLeaf *)current)->mTriangleBvh->GetRoot(), entry.mPriority)); 2531 } 2532 else // terminate traversal 2533 { 2534 nodes.push_back(current); 2535 } 2536 } 2537 else // interior node 2538 { 2539 // surface area of child nodes 2540 SA -= entry.mPriority; 2541 2542 // finish the search if we have too much fillrate increase 2543 if (SA > saThreshold) 2544 { 2545 OUT1("break at " << SA << " > " << saThreshold); 2546 nodes.push_back(current); 2547 } 2548 else 2549 { 2550 ++ numNodes; 2551 2552 OUT1(numNodes << " " << SA << " " << entry.mPriority); 2553 2554 if (current->GetType() == BVH_NODE) 2555 { 2556 BvhInterior *interior = static_cast<BvhInterior *>(current); 2557 2558 nodeStack.push(NodeEntry(interior->GetBack(), 2559 GetNodePriority(interior->GetBack()))); 2560 nodeStack.push(NodeEntry(interior->GetFront(), 2561 GetNodePriority(interior->GetFront()))); 2562 } 2563 else 2564 { 2565 TriangleBvhInterior *interior = static_cast<TriangleBvhInterior *>(current); 2566 2567 nodeStack.push(NodeEntry(interior->GetBack(), 2568 GetNodePriority(interior->GetBack()))); 2569 nodeStack.push(NodeEntry(interior->GetFront(), 2570 GetNodePriority(interior->GetFront()))); 2571 } 2572 } 2573 } 2574 } 2575 2576 while (!nodeStack.empty()) 2577 { 2578 NodeEntry entry = nodeStack.top(); 2579 2580 nodeStack.pop(); 2581 RenderableHierarchyNode *current = entry.mNode; 2582 nodes.push_back(current); 2583 } 2584 } 2585 2586 #endif 2587 2588 } 834 } -
GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h
r2753 r2755 5 5 6 6 #include "Geometry.h" 7 //#include "FlexibleHeap.h"8 7 9 8 … … 14 13 // Forward declarations 15 14 16 class Scene Geometry;15 class SceneEntity; 17 16 class Camera; 18 17 … … 23 22 { 24 23 friend class Bvh; 24 friend class BvhLoader; 25 friend class myless; 25 26 26 27 public: … … 52 53 */ 53 54 BvhNode(BvhNode *parent); 54 55 55 /** Returns true if this node is a leaf. 56 56 */ … … 75 75 virtual void ResetVisibility(); 76 76 77 virtual int GetType() = 0; //{ return BVH_NODE; }78 79 80 //////////////// /////77 virtual bool IsLeaf() = 0; //{ return BVH_NODE; } 78 79 80 //////////////// 81 81 //-- visibility culling related functions 82 82 83 83 inline int GetLastVisitedFrame() const; 84 84 85 inline void SetLastVisitedFrame( constint lastVisited);85 inline void SetLastVisitedFrame(int lastVisited); 86 86 /** If this node is considered visible. 87 87 */ … … 89 89 /** Set visibility flag of the node. 90 90 */ 91 inline void SetVisible( constbool visible);91 inline void SetVisible(bool visible); 92 92 /** The assumed visible time span of this node. 93 93 */ 94 inline void SetAssumedVisibleFrames( constint t);94 inline void SetAssumedVisibleFrames(int t); 95 95 /** See set. 96 96 */ … … 108 108 109 109 inline int GetTimesInvisible() const; 110 inline void SetTimesInvisible( constint t);110 inline void SetTimesInvisible(int t); 111 111 112 112 inline int GetTurnedVisibleFrame() const; 113 inline void SetTurnedVisibleFrame( constint turnedVisibleFrame);113 inline void SetTurnedVisibleFrame(int turnedVisibleFrame); 114 114 115 115 inline int GetLastTestedFrame(); 116 inline void SetLastTestedFrame( constint lastTested);116 inline void SetLastTestedFrame(int lastTested); 117 117 118 118 inline bool IsViewFrustumCulled() const; 119 inline void SetViewFrustumCulled( constbool frustumCulled);119 inline void SetViewFrustumCulled(bool frustumCulled); 120 120 121 121 inline bool IsNew() const; 122 inline void SetIsNew(const bool isNew); 122 inline void SetIsNew(bool isNew); 123 124 125 /** Returns the bounding box of this node. 126 */ 127 inline const AxisAlignedBox3 &GetBox() { return mBox; } 128 /** Return index of this node. 129 */ 130 inline int GetId() const { return mId; } 131 /** See get 132 */ 133 inline void SetId(int id) { mId = id; } 123 134 124 135 … … 152 163 /// the parent node 153 164 BvhNode *mParent; 154 /// stores the visibility related parameters165 /// stores the visibility related info 155 166 VisibilityInfo mVisibility; 156 167 … … 181 192 /// these nodes can be tested instead of the current node 182 193 int mTestNodesIdx; 194 183 195 int mNumTestNodes; 196 184 197 int mIndicesPtr; 198 185 199 /// Area of this node 186 200 float mArea; 201 /// distance to the camera 202 float mDistance; 203 /// the index of this node 204 unsigned int mId; 205 /// indices used for draw array rendering 206 unsigned int *mIndices; 207 /// the bounding box 208 AxisAlignedBox3 mBox; 209 187 210 }; 188 211 … … 302 325 class BvhInterior: public BvhNode 303 326 { 304 friend class Bvh; 327 friend class Bvh; 328 friend class BvhLoader; 305 329 306 330 public: 331 307 332 BvhInterior(BvhNode *parent): mBack(NULL), mFront(NULL), BvhNode(parent) 308 333 {} … … 319 344 /** Returns split axis of this interior node. 320 345 */ 321 inline int GetAxis() { return (int)mAxis;}346 inline int GetAxis() { return (int)mAxis; } 322 347 /** Returns position of the split axis. 323 348 */ … … 337 362 class BvhLeaf: public BvhNode 338 363 { 339 friend class Bvh; 364 friend class Bvh; 365 friend class BvhLoader; 340 366 341 367 public: … … 347 373 348 374 virtual bool IsLeaf() { return true; } 375 }; 376 377 378 /** This class implements the compare operator for the priority queue. 379 a lower distance has a higher value in the queue 380 */ 381 class myless 382 { 383 public: 384 bool operator() (BvhNode *v1, BvhNode *v2) const 385 { 386 return (v1->mDistance > v2->mDistance); 387 } 349 388 }; 350 389 … … 354 393 class Bvh 355 394 { 395 friend class BvhLoader; 396 356 397 /** Bvh properties 357 398 */ … … 401 442 */ 402 443 inline int GetNumLeaves() const {return mNumNodes / 2 + 1;} 403 /** Constructs the bounding volume hierarchy.404 */405 void Construct();406 444 /** Returns root node of the bvh. 407 445 */ 408 BvhNode *GetRoot() { return mRoot;}446 BvhNode *GetRoot() { return mRoot; } 409 447 /** Counts the triangle in this leaf. 410 448 */ … … 412 450 413 451 452 void CollectNodes(BvhNode *node, BvhNodeContainer &nodes, int depth); 453 void CollectNodes(BvhNode *node, BvhNodeContainer &nodes); 454 void CollectLeaves(BvhNode *node, BvhLeafContainer &leaves); 455 456 414 457 ////////////////////// 415 458 416 459 /** Returns geometry by reference (faster). 417 460 */ 418 Scene Geometry **GetGeometry(BvhNode *node, int &size);461 SceneEntity **GetGeometry(BvhNode *node, int &size); 419 462 420 463 … … 442 485 */ 443 486 int IsWithinViewFrustum(BvhNode *node); 444 /** sets frame dependent values.445 */ 446 void InitFrame(Camera *camera, constint currentFrameId);447 /** this gives the orthogonal distance from the viewpoint to the nearest bounding box vertex487 /** Sets frame dependent values. 488 */ 489 void InitFrame(Camera *camera, int currentFrameId); 490 /** This gives the orthogonal distance from the viewpoint to the nearest bounding box vertex 448 491 note that negative values can appear because culling is done only afterwards 449 492 */ 450 493 float CalcDistance(BvhNode *node) const; 451 /** Sets maximal depth for taking the bounding boxes to test the452 visibility of a node. The deeper the more the box fits to the geometry.453 */454 void SetMaxDepthForTestingChildren(const int maxDepth);455 /** Pulls up the fully visible classification in the bvh.456 */457 void UpdateFullVisibility(BvhNode *node) const;458 494 /** Pulls up the last visited classification in the bvh. 459 495 */ 460 void PullUpLastVisited(BvhNode *node, constint frameId) const;496 void PullUpLastVisited(BvhNode *node, int frameId) const; 461 497 /** Resets the node classifications in the tree. 462 498 */ … … 465 501 wireframes for visualization purpose. 466 502 */ 467 void RenderBoundingBoxesForViz(const int mode); 468 /** Returns squared min distance to the view point. 469 */ 470 float GetSquareDistance(BvhNode *node) const; 503 //void RenderBoundingBoxesForViz(int mode); 471 504 /** Count triangles the node contains. 472 505 */ … … 477 510 478 511 479 //////////// 480 //-- functions that change the boundaries of the nodes 481 482 void SetUseTighterBoundsForTests(bool tighterBoundsForTests); 483 484 void SetAreaRatioThresholdForTestingChildren(const float ratio); 485 486 512 //////// 513 //-- functions influencing tighter bounds 514 515 516 /** Sets maximal depth for taking the bounding boxes to test the 517 visibility of a node. 518 Deeper => the bounds adapt more to the geometry. 519 */ 520 void SetMaxDepthForTestingChildren(int maxDepth); 521 522 void SetAreaRatioThresholdForTestingChildren(float ratio); 523 524 /** Returns stats. 525 */ 487 526 const BvhStats &GetBvhStats() const {return mBvhStats;} 488 489 void SetCollectTighterBoundsWithMaxLevel(bool t);490 491 492 //////////////493 494 static unsigned int sCurrentVboId;495 527 496 528 497 529 protected: 498 530 499 /** Small struct representing a frustum.500 */501 struct Frustum502 {503 /// the 6 clip planes504 float mClipPlane[6][4];505 };506 507 508 509 531 //////////////////// 510 532 511 /** Constructor loading the bvh from disc512 */513 Bvh(const std::string &filename);514 533 /** protected constructor: do nothing. 515 534 */ 516 //Bvh(): mCamera(NULL), mFrameId(-1), mVertices(NULL), mRenderer(NULL) {}535 Bvh(); 517 536 /** Destructor. 518 537 */ … … 534 553 void RenderBoundingBoxesWithDrawArrays(int numNodes); 535 554 536 int RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes);537 /** Renders a bounding box in immediate mode using index restart538 and restarts the strip only if wished.539 */540 void RenderBoundingBoxImmediate(const AxisAlignedBox3 &box, bool restartStrip);541 555 /** Create the indices that each node needs to use vbo rendering. 542 556 */ … … 550 564 */ 551 565 void UpdateInteriors(BvhNode *node); 552 /** Recomputes the boundaries of the nodes. This function is always called if553 566 /** Recomputes the boundaries of the nodes. 567 This function is always called if some boundary options are changed. 554 568 */ 555 569 void RecomputeBounds(); … … 558 572 */ 559 573 int PostProcessLeaves(BvhLeafContainer &leaves); 560 561 562 int IsWithinViewFrustumLocal(BvhNode *node); 563 564 int IsWithinViewFrustum(const AxisAlignedBox3 &box, int planeMask, int preferredPlane); 565 566 float GetMinSquareDistance(const AxisAlignedBox3 &box) const; 567 574 568 575 569 576 //////////////////////// … … 572 579 BvhNode *mRoot; 573 580 /// pointers to the geometry associated with this node 574 Scene Geometry **mGeometry;581 SceneEntity **mGeometry; 575 582 /// #of entities 576 583 size_t mGeometrySize; … … 579 586 //////////////// 580 587 581 582 /// these values are valid for all nodes583 char mClipPlaneAABBVertexIndices[6][2];584 /// the current view frustum585 Frustum mFrustum;586 588 /// the current camera 587 589 Camera *mCamera; … … 589 591 int mFrameId; 590 592 /// a vertex array used if working with indexed arrays (without vbo) 591 //Point3f*mVertices;593 Vector3 *mVertices; 592 594 /// indices used for draw array rendering 593 595 unsigned int *mIndices; … … 599 601 600 602 float mAreaRatioThreshold; 601 float mVolRatioThreshold; 603 602 604 603 605 BvhStats mBvhStats; 604 606 605 //HierarchyNodeContainer mTestNodes;607 BvhNodeContainer mTestNodes; 606 608 607 609 unsigned int *mTestIndices; … … 609 611 int mCurrentIndicesPtr; 610 612 611 float mScale;612 613 Vector3 mNearPlane;614 float mNearPlaneD;615 613 int mNumNodes; 614 615 616 ////////////// 617 618 static unsigned int sCurrentVboId; 616 619 }; 617 620 -
GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.cpp
r2753 r2755 1 1 #include "common.h" 2 2 #include "Camera.h" 3 3 #include "glInterface.h" 4 4 5 5 … … 70 70 } 71 71 72 73 void Camera::GetProjectionMatrix(Matrix4x4 &mat) 74 { 75 //float m[16]; 76 77 glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x); 78 //mat = Matrix4x4((const float *)m); 72 79 } 73 80 81 82 void Camera::GetModelViewMatrix(Matrix4x4 &mat) 83 { 84 //float m[16]; 85 86 glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mat.x); 87 //mat = Matrix4f((const float *)m); 88 } 89 90 91 void Camera::CalcFrustum(Frustum &frustum) 92 { 93 // we grab the plane equations of the six clipplanes of the viewfrustum 94 Matrix4x4 matViewing, matProjectionView; 95 96 GetModelViewMatrix(matViewing); 97 GetProjectionMatrix(matProjectionView); 98 99 matProjectionView *= matViewing; 100 101 102 float fInvLength; 103 104 float planes[6][4]; 105 106 ////////// 107 //-- extract the plane equations 108 109 for (int i = 0; i < 4; ++ i) 110 { 111 planes[0][i] = matProjectionView.x[i][3] - matProjectionView.x[i][0]; // right plane 112 planes[1][i] = matProjectionView.x[i][3] + matProjectionView.x[i][0]; // left plane 113 planes[2][i] = matProjectionView.x[i][3] + matProjectionView.x[i][1]; // bottom plane 114 planes[3][i] = matProjectionView.x[i][3] - matProjectionView.x[i][1]; // top plane 115 planes[4][i] = matProjectionView.x[i][3] - matProjectionView.x[i][2]; // far plane 116 planes[5][i] = matProjectionView.x[i][3] + matProjectionView.x[i][2]; // near plane 117 } 118 119 120 //////////// 121 //-- normalize the coefficients 122 123 for (int i = 0; i < 6; ++ i) 124 { 125 // the clipping planes look outward the frustum, 126 // so distances > 0 mean that a point is outside 127 fInvLength = -1.0f / sqrt(planes[i][0] * planes[i][0] + 128 planes[i][1] * planes[i][1] + 129 planes[i][2] * planes[i][2]); 130 131 planes[i][0] *= fInvLength; 132 planes[i][1] *= fInvLength; 133 planes[i][2] *= fInvLength; 134 planes[i][3] *= fInvLength; 135 136 Vector3 normal(planes[i][0], planes[i][1], planes[i][2]); 137 frustum.mClipPlanes[i] = Plane3(normal, planes[i][3]); 138 } 139 } 140 141 142 void Camera::Frustum::CalcNPVertexIndices(int *indices) 143 { 144 for (int i = 0; i < 6; ++ i) 145 { 146 // n-vertex 147 indices[i * 2 + 0] = AxisAlignedBox3::GetIndexNearestVertex(mClipPlanes[i].mNormal); 148 // p-vertex 149 indices[i * 2 + 1] = AxisAlignedBox3::GetIndexFarthestVertex(mClipPlanes[i].mNormal); 150 } 151 } 152 153 154 } 155 -
GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.h
r2753 r2755 4 4 #include "Vector3.h" 5 5 #include "AxisAlignedBox3.h" 6 #include "Plane3.h" 6 7 7 8 8 namespace CHCDemo { 9 namespace CHCDemo 10 { 9 11 10 12 … … 12 14 { 13 15 public: 16 17 /** Small struct representing a frustum. 18 */ 19 struct Frustum 20 { 21 /// the 6 clip planes 22 //float mClipPlane[6][4]; 23 Plane3 mClipPlanes[6]; 14 24 25 void CalcNPVertexIndices(int *indices); 26 }; 27 15 28 Camera(); 16 29 … … 34 47 inline float GetFov() const { return mFovy; } 35 48 inline void GetSize(int &width, int &height) const { width = mWidth; height = mHeight; } 49 inline float GetAspect() const { return (float) mWidth / mHeight; } 50 51 void GetProjectionMatrix(Matrix4x4 &mat); 52 void GetModelViewMatrix(Matrix4x4 &mat); 53 54 void CalcFrustum(Frustum &frustum); 55 36 56 37 57 protected: … … 50 70 int mWidth; 51 71 int mHeight; 52 53 72 }; 54 73 -
GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.cpp
r2751 r2755 1 #if 02 3 4 1 #include "Geometry.h" 5 #include "glInterface.h" 6 #include "stdio.h" 7 #include "teapot.h" 8 9 #include <math.h> 2 #include "Triangle3.h" 10 3 11 4 … … 13 6 { 14 7 15 #define NO_LIST -1 16 #define STRIP_END -1 8 Geometry::Geometry(const TriangleContainer &triangles) 9 {} 17 10 18 int Geometry::num_torus_indices;19 int Geometry::num_torus_vertices;20 int Geometry::num_torus_normals;21 11 22 const int Geometry::torus_precision = 24; 23 const int Geometry::sphere_precision = 24; 24 25 float *Geometry::torus_vertices; 26 float *Geometry::torus_normals; 27 int *Geometry::torus_indices; 28 29 // choose size so the glut-rendered sphere is approximately 30 // as big as the other objects 31 const float Geometry::sphere_radius = 1.0 / 9.0f; 32 const float Geometry::torus_inner_radius = 0.05; 33 const float Geometry::torus_outer_radius = 0.07; 34 35 int Geometry::sDisplayList[NUM_OBJECTS]; 36 37 bool Geometry::sIsInitialised = Init(); 38 39 Geometry::Geometry(): 40 mXRotation(0), mYRotation(0), mZRotation(0), mScale(1.0), mObjectType(TEAPOT) 12 SceneEntity::SceneEntity(Geometry *geometry, 13 Matrix4x4 *trafo, 14 Material *mat): 15 mGeometry(geometry), mTransform(trafo), mMaterial(mat) 41 16 { 42 copyVector3Values(mTranslation, 0, 0, 0);43 44 SetAmbientColor(0.1745, 0.01175, 0.01175);45 SetDiffuseColor(0.61424, 0.04136, 0.04136);46 SetSpecularColor(0.727811, 0.626959, 0.626959);47 48 CalcBoundingVolume();49 CalcTransform();50 GenerateList();51 }52 53 Geometry::Geometry(Vector3 translation, float xRot, float yRot, float zRot, float scale, int objectType):54 mXRotation(xRot), mYRotation(yRot), mZRotation(zRot), mScale(scale), mObjectType(objectType)55 {56 copyVector3(mTranslation, translation);57 58 SetAmbientColor(0.1745, 0.01175, 0.01175);59 SetDiffuseColor(0.61424, 0.04136, 0.04136);60 SetSpecularColor(0.727811, 0.626959, 0.626959);61 62 CalcBoundingVolume();63 CalcTransform();64 GenerateList();65 }66 67 void Geometry::ResetLists()68 {69 for(int i = 0; i < NUM_OBJECTS; i++)70 {71 if(sDisplayList[i] == NO_LIST)72 glDeleteLists(sDisplayList[i], 1);73 74 sDisplayList[i] = NO_LIST;75 }76 }77 78 void Geometry::CleanUp()79 {80 ResetLists();81 82 delete [] torus_vertices;83 delete [] torus_normals;84 delete [] torus_indices;85 17 } 86 18 87 19 88 bool Geometry::Init()20 void SceneEntity::Render() 89 21 { 90 for(int i=0; i < NUM_OBJECTS; i++)91 sDisplayList[i] = NO_LIST;92 93 // parameters chosen so torus is approximately as big as teapot94 CreateTorus(torus_inner_radius, torus_outer_radius, torus_precision);95 96 return true;97 22 } 98 23 99 24 100 void Geometry::GenerateList()25 void SceneEntity::SetGeometry(Geometry *geom) 101 26 { 102 if(sDisplayList[mObjectType] == NO_LIST) 103 { 104 sDisplayList[mObjectType] = glGenLists(1); 105 glNewList(sDisplayList[mObjectType], GL_COMPILE); 106 107 switch(mObjectType) 108 { 109 case TEAPOT: 110 RenderTeapot(); 111 break; 112 case TORUS: 113 RenderTorus(); 114 break; 115 case SPHERE: 116 RenderSphere(); 117 break; 118 119 default: 120 break; 121 } 122 123 glEndList(); 124 } 27 mGeometry = geom; 125 28 } 126 29 127 30 128 void Geometry::Render()31 void SceneEntity::SetTransformation(Matrix4x4 *trafo) 129 32 { 130 glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientColor); 131 glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseColor); 132 glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularColor); 133 134 glPushMatrix(); 135 136 Transform(); 137 138 glCallList(sDisplayList[mObjectType]); 139 140 glPopMatrix(); 33 mTransform = trafo; 141 34 } 142 35 143 36 144 //! sets rotations around the three axis: executed in the order specified here 145 void Geometry::SetRotations(float xRot, float yRot, float zRot) 37 void SceneEntity::SetMaterial(Material *mat) 146 38 { 147 mXRotation = xRot; 148 mYRotation = yRot; 149 mZRotation = zRot; 150 151 CalcBoundingVolume(); 152 CalcTransform(); 39 mMaterial = mat; 153 40 } 154 41 155 42 156 void Geometry::SetTranslation(Vector3 translation) 157 { 158 copyVector3(mTranslation, translation); 159 160 CalcBoundingVolume(); 161 CalcTransform(); 162 } 163 164 165 void Geometry::SetScale(float scale) 166 { 167 mScale = scale; 168 CalcTransform(); 169 170 CalcBoundingVolume(); 171 } 172 173 174 void Geometry::SetAmbientColor(float ambientR, float ambientG, float ambientB) 175 { 176 mAmbientColor[0] = ambientR; 177 mAmbientColor[1] = ambientG; 178 mAmbientColor[2] = ambientB; 179 } 180 181 182 void Geometry::SetDiffuseColor(float diffuseR, float diffuseG, float diffuseB) 183 { 184 mDiffuseColor[0] = diffuseR; 185 mDiffuseColor[1] = diffuseG; 186 mDiffuseColor[2] = diffuseB; 187 } 188 189 190 void Geometry::SetSpecularColor(float specularR, float specularG, float specularB) 191 { 192 mSpecularColor[0] = specularR; 193 mSpecularColor[1] = specularG; 194 mSpecularColor[2] = specularB; 195 } 196 197 198 float Geometry::GetScale() 199 { 200 return mScale; 201 } 202 203 204 void Geometry::GetTranslation(Vector3 translation) 205 { 206 copyVector3(translation, mTranslation); 207 } 208 209 210 void Geometry::GetRotations(float &xRot, float &yRot, float &zRot) 211 { 212 xRot = mXRotation; 213 yRot = mYRotation; 214 zRot = mZRotation; 215 } 216 217 218 const AABox &Geometry::GetBoundingVolume() 43 const AxisAlignedBox3& SceneEntity::GetBoundingVolume() 219 44 { 220 45 return mBoundingBox; … … 222 47 223 48 224 void Geometry::SetLastVisited(int lastVisited)49 void SceneEntity::SetLastVisited(int lastVisited) 225 50 { 226 51 mLastVisited = lastVisited; … … 228 53 229 54 230 int Geometry::GetLastVisited()55 int SceneEntity::GetLastVisited() const 231 56 { 232 57 return mLastVisited; … … 234 59 235 60 236 void Geometry::SetObjectType(int type)237 {238 mObjectType = type;239 GenerateList();240 61 } 241 242 243 void Geometry::RenderTeapot()244 {245 int i = 0;246 247 while(i < num_teapot_indices)248 {249 glBegin(GL_TRIANGLE_STRIP);250 251 while (teapot_indices[i] != STRIP_END)252 {253 int index = teapot_indices[i] * 3;254 255 glNormal3fv(teapot_normals + index);256 glVertex3fv(teapot_vertices + index);257 258 ++ i;259 }260 261 glEnd();262 263 ++ i; // skip strip end flag264 }265 }266 267 268 void Geometry::CalcBoundingVolume()269 {270 switch(mObjectType)271 {272 case TORUS:273 CalcBoundingVolume(torus_vertices, num_torus_vertices);274 break;275 case SPHERE:276 CalcSphereBoundingVolume();277 break;278 case TEAPOT:279 CalcBoundingVolume(teapot_vertices, num_teapot_vertices);280 break;281 default:282 break;283 }284 }285 286 287 void Geometry::CalcBoundingVolume(float *vertices, const int num_vertices)288 {289 Vector3 *rotatedPoints = new Vector3[num_vertices];290 291 for (int i = 0; i < num_vertices; ++ i)292 {293 copyVector3Values(rotatedPoints[i], vertices[i * 3],294 vertices[i * 3 + 1], vertices[i * 3 + 2]);295 296 rotateVectorZ(rotatedPoints[i], mZRotation * PI_180);297 rotateVectorY(rotatedPoints[i], mYRotation * PI_180);298 rotateVectorX(rotatedPoints[i], mXRotation * PI_180);299 }300 301 calcCubicHull(mBoundingBox.min, mBoundingBox.max, rotatedPoints, num_vertices);302 303 for (int i = 0; i < 3; ++ i)304 {305 mBoundingBox.min[i] *= mScale;306 mBoundingBox.max[i] *= mScale;307 }308 309 addVector3(mBoundingBox.min, mTranslation, mBoundingBox.min);310 addVector3(mBoundingBox.max, mTranslation, mBoundingBox.max);311 312 delete [] rotatedPoints;313 }314 315 316 void Geometry::CalcSphereBoundingVolume()317 {318 float len = mScale * sphere_radius;319 Vector3 size = {len, len, len};320 321 diffVector3(mBoundingBox.min, mTranslation, size);322 addVector3(mBoundingBox.max, mTranslation, size);323 }324 325 326 void Geometry::RenderTorus()327 {328 glVertexPointer(3, GL_FLOAT, sizeof(float), torus_vertices);329 glEnableClientState(GL_VERTEX_ARRAY);330 331 glNormalPointer(GL_FLOAT, sizeof(float), torus_normals);332 glEnableClientState(GL_NORMAL_ARRAY);333 334 glDrawElements(GL_TRIANGLES, num_torus_indices, GL_UNSIGNED_INT, torus_indices);335 336 glDisableClientState(GL_VERTEX_ARRAY);337 glDisableClientState(GL_NORMAL_ARRAY);338 }339 340 /* Creates a torus with specified radii, with number of rings and ring341 subdivision = precision.342 */343 void Geometry::CreateTorus(float innerRadius, float outerRadius, int precision)344 {345 num_torus_vertices = num_torus_normals = (precision + 1) * (precision + 1);346 num_torus_indices = 2 * precision * precision * 3;347 348 torus_vertices = new float[num_torus_vertices * 3];349 torus_normals = new float[num_torus_normals * 3];350 torus_indices = new int[num_torus_indices];351 352 for (int i = 0; i < precision + 1; ++ i)353 {354 int index = i * 3;355 356 Vector3 currentVertex = {innerRadius, 0.0f, 0.0f};357 rotateVectorZ(currentVertex, ((float)i * 2.0 * PI) / (float)precision);358 359 currentVertex[0] += outerRadius;360 361 Vector3 sTangent = {0.0f, 0.0f, -1.0f};362 Vector3 tTangent = {0, -1, 0};363 rotateVectorZ(tTangent, ((float)i * 2.0 * PI) / (float)precision);364 365 Vector3 currentNormal;366 367 cross(currentNormal, tTangent, sTangent);368 369 torus_normals[index + 0] = currentNormal[0];370 torus_normals[index + 1] = currentNormal[1];371 torus_normals[index + 2] = currentNormal[2];372 373 torus_vertices[index + 0] = currentVertex[0];374 torus_vertices[index + 1] = currentVertex[1];375 torus_vertices[index + 2] = currentVertex[2];376 }377 378 for (int i_rng = 1; i_rng < precision + 1; ++ i_rng)379 {380 for(int i = 0; i<precision + 1; ++ i)381 {382 int index = 3 * (i_rng * (precision + 1) + i);383 384 Vector3 currentVertex = {torus_vertices[i*3], torus_vertices[i*3+1], torus_vertices[i*3+2]};385 386 rotateVectorY(currentVertex, ((float)i_rng * 2.0 * PI) / (float)precision);387 388 Vector3 currentNormal = {torus_normals[i*3], torus_normals[i*3+1], torus_normals[i*3+2]};389 390 rotateVectorY(currentNormal, ((float)i_rng * 2.0 * PI) / (float)precision);391 392 torus_normals[index + 0] = currentNormal[0];393 torus_normals[index + 1] = currentNormal[1];394 torus_normals[index + 2] = currentNormal[2];395 396 torus_vertices[index + 0] = currentVertex[0];397 torus_vertices[index + 1] = currentVertex[1];398 torus_vertices[index + 2] = currentVertex[2];399 }400 }401 402 for (int i_rng = 0; i_rng < precision; ++ i_rng)403 {404 for (int i = 0; i < precision; ++ i)405 {406 int index = ((i_rng * precision + i) * 2) * 3;407 408 torus_indices[index+0] = (i_rng * (precision+1) + i)*3;409 torus_indices[index+1] = ((i_rng+1) * (precision+1) + i)*3;410 torus_indices[index+2] = (i_rng * (precision+1) + i + 1)*3;411 412 index = ((i_rng * precision + i) * 2 + 1) * 3;413 414 torus_indices[index+0] = (i_rng * (precision+1) + i + 1)*3;415 torus_indices[index+1] = ((i_rng+1) * (precision+1) + i)*3;416 torus_indices[index+2] = ((i_rng+1) * (precision+1) + i + 1)*3;417 }418 }419 }420 421 422 /** Counts the triangles of the teapot.423 traverses through all the triangle strips.424 */425 int Geometry::CountTeapotTriangles()426 {427 int result = 0;428 int i = 0;429 430 // n - 2 triangles are drawn for a strip431 while (i < num_teapot_indices)432 {433 while (teapot_indices[i] != STRIP_END)434 {435 result ++;;436 ++ i;437 }438 result -= 2;439 ++ i; // skip STRIP_END440 }441 442 return result;443 }444 445 446 /** Counts the triangles of the torus447 */448 int Geometry::CountTorusTriangles()449 {450 // every 3 indices specify one triangle451 return num_torus_indices / 3;452 }453 454 /**455 counts the triangles of the sphere.456 sphere_precision / 2 + 1 strips with sphere_precision * 2 - 2 triangles each457 */458 int Geometry::CountSphereTriangles()459 {460 return sphere_precision * sphere_precision;461 }462 463 464 int Geometry::CountTriangles(int objectType)465 {466 int result = 0;467 468 switch (objectType)469 {470 case TEAPOT:471 result = CountTeapotTriangles();472 break;473 case TORUS:474 result = CountTorusTriangles();475 break;476 case SPHERE:477 result = CountSphereTriangles();478 break;479 default:480 break;481 }482 483 return result;484 }485 486 487 void Geometry::Transform()488 {489 glMultMatrixd(mTransform);490 }491 492 void Geometry::CalcTransform()493 {494 Matrix4x4 scale;495 Matrix4x4 xrot;496 Matrix4x4 yrot;497 Matrix4x4 zrot;498 Matrix4x4 transl;499 500 makeScaleMtx(scale, mScale, mScale, mScale);501 makeTranslationMtx(transl, mTranslation);502 makeRotationXMtx(xrot, mXRotation * PI_180);503 makeRotationYMtx(yrot, mYRotation * PI_180);504 makeRotationZMtx(zrot, mZRotation * PI_180);505 506 copyMatrix(mTransform, IDENTITY);507 mult(mTransform, mTransform, transl);508 mult(mTransform, mTransform, xrot);509 mult(mTransform, mTransform, yrot);510 mult(mTransform, mTransform, zrot);511 mult(mTransform, mTransform, scale);512 }513 514 515 /** Renders a sphere with sphere_precision subdivisions.516 Note: works only for even sphere_precision517 */518 void Geometry::RenderSphere()519 {520 Vector3 vertex;521 522 // this algorithm renders the triangles clockwise523 glFrontFace(GL_CW);524 525 for (int j = 0; j < sphere_precision / 2; ++ j)526 {527 double alpha = j * PI * 2.0 / (double)sphere_precision - PI_2;528 double beta = (j + 1) * PI * 2.0 / (double)sphere_precision - PI_2;529 530 glBegin(GL_TRIANGLE_STRIP);531 532 for (int i = 0; i <= sphere_precision; ++ i)533 {534 double gamma = i * PI * 2.0 / (double)sphere_precision;535 536 vertex[0] = sphere_radius * cos(beta) * cos(gamma);537 vertex[1] = sphere_radius * sin(beta);538 vertex[2] = sphere_radius * cos(beta) * sin(gamma);539 540 glNormal3dv(vertex);541 glVertex3dv(vertex);542 543 vertex[0] = sphere_radius * cos(alpha) * cos(gamma);544 vertex[1] = sphere_radius * sin(alpha);545 vertex[2] = sphere_radius * cos(alpha) * sin(gamma);546 547 glNormal3dv(vertex);548 glVertex3dv(vertex);549 550 }551 glEnd();552 }553 554 glFrontFace(GL_CCW);555 }556 557 }558 559 #endif -
GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.h
r2752 r2755 4 4 #include "common.h" 5 5 #include "AxisAlignedBox3.h" 6 6 #include "Triangle3.h" 7 7 8 8 … … 23 23 Geometry(const TriangleContainer &triangles); 24 24 25 int CountTriangles() const { return (int)mTriangles.size(); } 26 27 25 28 protected: 26 29 … … 35 38 class SceneEntity 36 39 { 40 public: 41 37 42 /** Create scene entity. 38 43 */ … … 44 49 */ 45 50 void SetGeometry(Geometry *geom); 51 /** See set 52 */ 53 Geometry *GetGeometry() const { return mGeometry; } 46 54 /** Set pointer to the geometry 47 55 */ 48 void SetTransformation( constMatrix4x4 *trafo);56 void SetTransformation(Matrix4x4 *trafo); 49 57 /** Set pointer to the material 50 58 */ … … 59 67 */ 60 68 int GetLastVisited() const; 69 61 70 62 71 protected: -
GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp
r2751 r2755 8 8 { 9 9 return RgbColor(a + Random(b), a + Random(b), a + Random(b)); 10 } 11 12 13 14 Material::Material(): mId(0) 15 {} 16 17 18 Material::Material(const int id): mId(id) 19 { 20 } 21 22 23 Material::Material(const RgbColor &color):mDiffuseColor(color), 24 mAmbientColor(color), 25 mSpecularColor(0,0,0), mId(0) 26 { 27 } 28 29 30 int Material::GetId() const 31 { 32 return mId; 10 33 } 11 34 -
GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h
r2751 r2755 6 6 { 7 7 8 8 9 class RgbColor 9 10 { 11 10 12 public: 13 11 14 float r, g, b; 12 15 … … 44 47 { 45 48 public: 49 46 50 RgbColor mDiffuseColor; 47 51 RgbColor mSpecularColor; 48 52 RgbColor mAmbientColor; 49 53 50 Material(): mId(0) 51 { 52 } 54 Material(); 53 55 54 Material(const int id): mId(id) 55 { 56 } 56 Material(const int id); 57 57 58 Material(const RgbColor &color):mDiffuseColor(color), 59 mAmbientColor(color), 60 mSpecularColor(0,0,0), mId(0) 61 { 62 } 63 64 friend Material RandomMaterial(); 65 58 Material(const RgbColor &color); 66 59 /** Returns unique material id. 67 60 */ 68 int GetId() const 69 { 70 return mId; 71 } 61 int GetId() const; 62 63 friend Material RandomMaterial(); 72 64 73 65 protected: -
GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.cpp
r2751 r2755 8 8 Plane3::Plane3(const Vector3 &a, const Vector3 &b, const Vector3 &c) 9 9 { 10 Vector3 v1 =a-b, v2=c-b;11 mNormal = Normalize(CrossProd(v2, v1));10 Vector3 v1 = a - b, v2 = c - b; 11 mNormal = Normalize(CrossProd(v2, v1)); 12 12 mD = -DotProd(b, mNormal); 13 } 14 15 16 Plane3::Plane3(Vector3 &normal, float dist): 17 mNormal(normal), mD(dist) 18 { 13 19 } 14 20 … … 28 34 Vector3 sx(a.mNormal.x, b.mNormal.x, c.mNormal.x), 29 35 sy(a.mNormal.y, b.mNormal.y, c.mNormal.y), 30 31 36 sz(a.mNormal.z, b.mNormal.z, c.mNormal.z), 37 sd(a.mD, b.mD, c.mD); 32 38 33 39 Matrix4x4 md(a.mNormal, b.mNormal, c.mNormal), mx, my, mz; 34 40 35 mx.SetColumns(sd, sy, sz); 36 my.SetColumns(sx, sd, sz); 37 mz.SetColumns(sx, sy, sd); 38 39 const float det = md.Det3x3(); 41 mx.SetColumns(sd, sy, sz); 42 my.SetColumns(sx, sd, sz); 43 mz.SetColumns(sx, sy, sd); 40 44 41 if (fabs(det) < TRASH) 42 return false; 45 const float det = md.Det3x3(); 43 46 44 result.SetValue(mx.Det3x3()/det, 45 my.Det3x3()/det, 46 mz.Det3x3()/det); 47 48 return true; 47 if (fabs(det) < TRASH) 48 return false; 49 50 result.SetValue(mx.Det3x3()/det, 51 my.Det3x3()/det, 52 mz.Det3x3()/det); 53 54 return true; 49 55 } 50 56 51 57 52 53 54 55 56 57 58 59 58 bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2) 59 { 60 return 61 p1.mNormal.x != p2.mNormal.x || 62 p1.mNormal.y != p2.mNormal.y || 63 p1.mNormal.z != p2.mNormal.z || 64 p1.mD == p2.mD; 65 } 60 66 61 67 -
GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.h
r2751 r2755 1 #ifndef _ Plane3_H__2 #define _ Plane3_H__1 #ifndef __Plane3_H__ 2 #define __Plane3_H__ 3 3 4 4 #include "Vector3.h" 5 5 6 6 7 namespace CHCDemo … … 15 16 Plane3() {} 16 17 18 Plane3(Vector3 &normal, float dist); 19 17 20 Plane3(const Vector3 &a, const Vector3 &b, const Vector3 &c); 18 21 19 22 Plane3(const Vector3 &normal, const Vector3 &point); 20 23 21 void ReverseOrientation()24 inline void ReverseOrientation() 22 25 { 23 26 mNormal *= -1; 24 27 mD *= -1; 25 28 } 26 27 float Distance(const Vector3 &v) const 29 /** Get disance to point. 30 */ 31 inline float Distance(const Vector3 &v) const 28 32 { 29 33 return DotProd(v, mNormal) + mD; … … 31 35 32 36 enum {BACK_SIDE = -1, INTERSECTS = 0, FRONT_SIDE = 1}; 33 34 37 /** Returns 1 if v is on front side, -1 if on back side, 0 if on plane. 35 38 */ … … 52 55 53 56 54 /////////// ///////57 /////////// 55 58 //-- friends 56 59 … … 61 64 friend std::ostream &operator<<(std::ostream &s, const Plane3 &p) 62 65 { 63 s <<p.mNormal<<" "<<p.mD;66 s << p.mNormal << " " << p.mD; 64 67 return s; 65 68 } -
GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp
r2754 r2755 57 57 }*/ 58 58 59 #if 0 60 void RenderTraverser::TraverseNode(HierarchyNode *node) 61 { 62 if(node->IsLeaf()) 63 mNumRenderedGeometry += node->Render(); 59 void RenderTraverser::EnqueueNode(BvhNode *node) 60 { 61 mBvh->CalcDistance(node); 62 mDistanceQueue.push(node); 63 } 64 65 66 void RenderTraverser::TraverseNode(BvhNode *node) 67 { 68 if (node->IsLeaf()) 69 { 70 //mNumRenderedGeometry += node->Render(); 71 } 64 72 else 65 73 { 66 74 // for non leafs this renders only the bounding volume (if the flag is set) 67 75 //node->Render(); 68 mDistanceQueue.push(node->GetLeftChild()); 69 mDistanceQueue.push(node->GetRightChild()); 70 } 71 } 76 BvhInterior *interior = static_cast<BvhInterior *>(node); 77 78 EnqueueNode(interior->GetFront()); 79 EnqueueNode(interior->GetBack()); 80 } 81 } 82 83 #if 0 72 84 73 85 void RenderTraverser::RenderVisualization() -
GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h
r2754 r2755 5 5 #include <stack> 6 6 #include "glInterface.h" 7 7 #include "Bvh.h" 8 8 9 9 namespace CHCDemo 10 10 { 11 11 12 class BvhNode;13 class Bvh;14 12 class Camera; 15 13 class Matrix4x4; … … 44 42 45 43 //typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless<std::vector<BvhNode *>::value_type> > TraversalQueue; 44 typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless> TraversalQueue; 46 45 47 46 /** Abstract class implementing a scene traversal for rendering. … … 112 111 void Switch2GLQueryState(); 113 112 113 void EnqueueNode(BvhNode *node); 114 114 115 protected: 115 //////////// 116 //-- members 116 117 117 118 // /the current clip planes of the view frustum … … 126 127 Bvh *mBvh; 127 128 /// use a priority queue rather than a renderstack 128 //PriorityQueue mDistanceQueue;129 TraversalQueue mDistanceQueue; 129 130 130 131 int mFrameID; -
GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj
r2754 r2755 120 120 <Tool 121 121 Name="VCCLCompilerTool" 122 Optimization="3" 122 123 InlineFunctionExpansion="2" 123 124 EnableIntrinsicFunctions="true" … … 130 131 RuntimeTypeInfo="false" 131 132 UsePrecompiledHeader="0" 133 BrowseInformation="1" 132 134 WarningLevel="3" 133 135 Detect64BitPortabilityProblems="true" … … 205 207 </File> 206 208 <File 209 RelativePath=".\Material.cpp" 210 > 211 </File> 212 <File 207 213 RelativePath=".\OcclusionQuery.cpp" 208 214 > … … 247 253 </File> 248 254 <File 255 RelativePath=".\BinaryLoader.cpp" 256 > 257 </File> 258 <File 259 RelativePath=".\BinaryLoader.h" 260 > 261 </File> 262 <File 263 RelativePath=".\BvhLoader.cpp" 264 > 265 </File> 266 <File 267 RelativePath=".\BvhLoader.h" 268 > 269 </File> 270 <File 249 271 RelativePath=".\common.cpp" 250 272 > … … 256 278 <File 257 279 RelativePath=".\glInterface.h" 258 >259 </File>260 <File261 RelativePath=".\Material.cpp"262 280 > 263 281 </File> -
GTP/trunk/App/Demos/Vis/CHC_revisited/common.h
r2754 r2755 25 25 class BvhLeaf; 26 26 class OcclusionQuery; 27 class SceneEntity; 28 27 29 28 30 … … 465 467 466 468 typedef std::vector<BvhNode *> BvhNodeContainer; 469 typedef std::vector<SceneEntity *> SceneEntityContainer; 467 470 typedef std::vector<BvhLeaf *> BvhLeafContainer; 468 471 typedef std::vector<Triangle3> TriangleContainer;
Note: See TracChangeset
for help on using the changeset viewer.