Changeset 2743 for GTP/trunk/Lib/Vis/Preprocessing/src
- Timestamp:
- 06/09/08 10:36:36 (17 years ago)
- Location:
- GTP/trunk/Lib/Vis/Preprocessing/src
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h
r2176 r2743 39 39 protected: 40 40 std::string mFilename; 41 bool mWire frame;41 bool mWireFrame; 42 42 bool mUseForcedMaterial; 43 43 Material mForcedMaterial; … … 49 49 Exporter(const std::string filename): 50 50 mFilename(filename), 51 mWire frame(false),51 mWireFrame(false), 52 52 mUseForcedMaterial(false), 53 53 mExportRayDensity(false), … … 139 139 void SetExportRayDensity(const bool d) { mExportRayDensity = d; } 140 140 141 void SetWireframe() { mWire frame = true; }142 void SetFilled() { mWire frame = false; }141 void SetWireframe() { mWireFrame = true; } 142 void SetFilled() { mWireFrame = false; } 143 143 144 144 void SetForcedMaterial(const Material &m) -
GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp
r2742 r2743 432 432 } 433 433 } 434 434 435 435 436 void GlRenderer::InitGL() … … 465 466 466 467 for (; ni != interior->mChildren.end(); ni++) 467 {468 468 CreateVertexArrays(static_cast<SceneGraphLeaf *>(*ni)); 469 }470 469 } 471 470 … … 474 473 GlRenderer::SetupProjection(const int w, const int h, const float angle) 475 474 { 476 477 478 479 gluPerspective(angle, 1.0, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));480 475 glViewport(0, 0, w, h); 476 glMatrixMode(GL_PROJECTION); 477 glLoadIdentity(); 478 gluPerspective(angle, 1.0, 1.0f, 2.0 * Magnitude(mSceneGraph->GetBox().Diagonal())); 479 glMatrixMode(GL_MODELVIEW); 481 480 } 482 481 … … 592 591 ++ mCurrentFrame; 593 592 594 Intersectable::NewMail();593 //Intersectable::NewMail(); 595 594 596 595 Preprocessor *p = mViewCellsManager->GetPreprocessor(); … … 600 599 601 600 for (dit = p->mDynamicObjects.begin(); dit != dit_end; ++ dit) 602 {603 601 _RenderDynamicObject(*dit); 604 }605 602 606 603 _RenderSceneTrianglesWithDrawArrays(); … … 1676 1673 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 1677 1674 glDepthMask(GL_TRUE); 1678 glEnable( GL_CULL_FACE);1675 glEnable(GL_CULL_FACE); 1679 1676 1680 1677 // int wait = 0; … … 1704 1701 void GlRenderer::RenderViewPoint() 1705 1702 { 1706 mWireFrame = true;1703 //mWireFrame = true; 1707 1704 glPushMatrix(); 1708 1705 glTranslatef(mViewPoint.x, mViewPoint.y, mViewPoint.z); … … 1714 1711 glPopAttrib(); 1715 1712 glPopMatrix(); 1716 mWireFrame = false;1713 //mWireFrame = false; 1717 1714 } 1718 1715 … … 1801 1798 glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3)); 1802 1799 1803 glDrawElements(GL_TRIANGLES, leaf->mIndexBufferSize, GL_UNSIGNED_INT, mIndices + leaf->mIndexBufferStart); 1800 glDrawElements(GL_TRIANGLES, leaf->mIndexBufferSize, GL_UNSIGNED_INT, 1801 mIndices + leaf->mIndexBufferStart); 1804 1802 } 1805 1803 1806 1804 #endif 1807 1808 1805 1809 1806 -
GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h
r2736 r2743 247 247 248 248 Preprocessor *GetPreprocessor(); 249 249 /** quick hack in order to be able to render gvs based triangle pvs. 250 */ 251 void RenderTrianglePvs(); 252 253 void RenderVisTriangles(); 254 255 256 /////////////////// 250 257 251 258 vector<PvsErrorEntry> mPvsErrorBuffer; -
GTP/trunk/Lib/Vis/Preprocessing/src/GtpVisibility05.vcproj
r2729 r2743 318 318 </Filter> 319 319 <Filter 320 Name=" Renderer"320 Name="renderer" 321 321 > 322 322 <File … … 342 342 </Filter> 343 343 <Filter 344 Name=" Loader"344 Name="loader" 345 345 > 346 346 <File … … 438 438 </Filter> 439 439 <Filter 440 Name=" Preprocessors"440 Name="preprocessors" 441 441 > 442 442 <File … … 502 502 </Filter> 503 503 <Filter 504 Name=" Exporters"504 Name="exporters" 505 505 > 506 506 <File -
GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
r2742 r2743 22 22 { 23 23 24 #define GVS_DEBUG 024 #define GVS_DEBUG 1 25 25 #define NOT_ACCOUNTED_OBJECT 0 26 26 #define ACCOUNTED_OBJECT 2 27 28 29 static const float MIN_DIST = 0.001f; 27 #define USE_REVERSE_SAMPLING 1 28 #define USE_SUBDIVISION 1 29 30 static const float MIN_DIST = 1e-8f; 30 31 31 32 static ObjectContainer myobjects; 32 33 static int sInvalidSamples = 0; 33 34 static VizStruct currentViz; 34 35 35 36 … … 53 54 54 55 55 /** Visualization structure for the GVS algorithm.56 */57 struct VizStruct58 {59 Polygon3 *enlargedTriangle;60 Triangle3 originalTriangle;61 VssRay *ray;62 };63 64 static vector<VizStruct> vizContainer;65 66 56 67 57 … … 216 206 217 207 218 int GvsPreprocessor::CheckDiscontinuity2(const VssRay ¤tRay, 219 const Triangle3 &hitTriangle, 220 const VssRay &oldRay) 208 bool GvsPreprocessor::CheckDiscontinuity2(const VssRay ¤tRay, 209 const Triangle3 &hitTriangle, 210 const VssRay &oldRay, 211 SimpleRay &reverseRay) 221 212 { 222 213 // the predicted hitpoint is the point where the ray would have intersected the hit triangle … … 229 220 // => this is likely to be a discontinuity 230 221 if (fabs(predictedLen - len) < mThreshold) 231 return 0; 232 233 static SimpleRayContainer simpleRays; 234 simpleRays.clear(); 235 236 CreateRandomizedReverseRays(currentRay, predictedHit, simpleRays, 16, hitTriangle); 237 238 static VssRayContainer reverseRays; 239 reverseRays.clear(); 240 CastRays(simpleRays, reverseRays, false, false); 241 242 mGvsStats.mReverseSamples += (int)reverseRays.size(); 243 244 EnqueueRays(reverseRays); 245 246 return (int)reverseRays.size(); 222 return false; 223 224 return CreateRandomizedReverseRay(currentRay, predictedHit, reverseRay, hitTriangle); 247 225 } 248 226 … … 353 331 } 354 332 355 if (0 && GVS_DEBUG) 356 mVssRays.push_back(new VssRay(*vssRay)); 333 if (GVS_DEBUG) 334 { 335 if (mVssRays.size() < 1000) 336 mVssRays.push_back(new VssRay(*vssRay)); 337 } 357 338 358 339 // add new ray to ray queue … … 361 342 ++ mGvsStats.mTotalContribution; 362 343 363 if (mRayQueue.size() % 10000 == 0)344 if (mRayQueue.size() % 50000 == 0) 364 345 cout << "ray queue size: " << mRayQueue.size() << endl; 365 346 … … 376 357 const Triangle3 &hitTriangle, 377 358 const VssRay &ray, 378 constint index) const359 int index) const 379 360 { 380 361 const int indexU = (index + 1) % 3; 381 const int indexL = (index == 0) ? 2 : index - 1; 382 383 const Vector3 a = hitTriangle.mVertices[index] - ray.GetOrigin(); 384 const Vector3 b = hitTriangle.mVertices[indexU] - hitTriangle.mVertices[index]; 385 const Vector3 c = hitTriangle.mVertices[index] - hitTriangle.mVertices[indexL]; 362 const int indexL = (index - 1) % 3; //(index == 0) ? 2 : index - 1; 363 364 const Vector3 v = hitTriangle.mVertices[index]; 365 const Vector3 vu = hitTriangle.mVertices[indexU]; 366 const Vector3 vl = hitTriangle.mVertices[indexL]; 367 368 const Vector3 a = v - ray.GetOrigin(); 369 const Vector3 b = vu - v; 370 const Vector3 c = v - vl; 386 371 387 372 const float len = Magnitude(a); 388 389 const Vector3 dir1 = Normalize(CrossProd(a, b)); //N((pi-xp)×(pi+1- pi)); 390 const Vector3 dir2 = Normalize(CrossProd(a, c)); // N((pi-xp)×(pi- pi-1)) 373 //if (len > Limits::Small) a /= len; 374 375 const Vector3 dir1 = Normalize(CrossProd(a, b)); // N((pi-xp)×(pi+1 - pi)); 376 const Vector3 dir2 = Normalize(CrossProd(a, c)); // N((pi-xp)×(pi - pi-1)) 391 377 const Vector3 dir3 = DotProd(dir2, dir1) > 0 ? // N((pi-xp)×di,i-1+di,i+1×(pi-xp)) 392 378 Normalize(dir2 + dir1) : Normalize(CrossProd(a, dir1) + CrossProd(dir2, a)); 379 #if 1 393 380 394 381 // compute the new three hit points 395 // pi, i + 1: pi+ e·|pi-xp|·di, j 396 const Vector3 pt1 = hitTriangle.mVertices[index] + mEps * len * dir1; 397 // pi, i - 1: pi+ e·|pi-xp|·di, j 398 const Vector3 pt2 = hitTriangle.mVertices[index] + mEps * len * dir2; 399 // pi, i: pi+ e·|pi-xp|·di, j 400 const Vector3 pt3 = hitTriangle.mVertices[index] + mEps * len * dir3; 401 382 // pi, i + 1: pi + e·|pi-xp|·di, j 383 const Vector3 pt1 = v + mEps * len * dir1; 384 // pi, i - 1: pi + e·|pi-xp|·di, j 385 const Vector3 pt2 = v + mEps * len * dir2; 386 // pi, i: pi + e·|pi-xp|·di, j 387 const Vector3 pt3 = v + mEps * len * dir3; 388 389 #else 390 391 const Vector3 pt1 = v + mEps * dir1; 392 // pi, i - 1: pi + e·|pi-xp|·di, j 393 const Vector3 pt2 = v + mEps * dir2; 394 // pi, i: pi + e·|pi-xp|·di, j 395 const Vector3 pt3 = v + mEps * dir3; 396 397 #endif 398 402 399 vertices.push_back(pt2); 403 400 vertices.push_back(pt3); … … 431 428 432 429 433 staticbool EqualVisibility(const VssRay &a, const VssRay &b)430 bool EqualVisibility(const VssRay &a, const VssRay &b) 434 431 { 435 432 return a.mTerminationObject == b.mTerminationObject; … … 442 439 const VssRay &ray1, 443 440 const VssRay &ray2, 444 const VssRay &oldRay )445 { 446 //cout <<"y"<<Magnitude(p1 - p2) << " "; 441 const VssRay &oldRay, 442 int level) 443 { 447 444 int castRays = 0; 448 449 if (EqualVisibility(ray1, ray2) || (SqrMagnitude(p1 - p2) <= MIN_DIST)) 445 446 if (EqualVisibility(ray1, ray2) || (SqrDistance(p1, p2) <= MIN_DIST) || (level ++ > 10)) 447 { 448 //if (SqrMagnitude(p1 - p2) <= MIN_DIST) 449 // cerr << "min dist reached!! " << SqrMagnitude(p1 - p2) << " " << MIN_DIST << " " << ray1.mTerminationObject << " " << ray2.mTerminationObject << " level: " << level << " " << EqualVisibility(ray1, ray2) << endl; 450 450 451 return castRays; 451 452 } 452 453 453 454 // the new subdivision point 454 455 const Vector3 p = (p1 + p2) * 0.5f; 455 //cout << "p: " << p << " " << p1 << " " << p2 << endl; 456 456 457 457 SimpleRay sray(oldRay.mOrigin, p - oldRay.mOrigin, SamplingStrategy::GVS, 1.0f); 458 458 … … 469 469 470 470 if (!newRay) 471 { 472 //cout<<"w"; 471 473 return castRays; 474 } 472 475 473 476 //newRay->mFlags |= VssRay::BorderSample; 474 477 475 478 // cast reverse rays if necessary 476 castRays += CheckDiscontinuity(*newRay, hitTriangle, oldRay); 477 479 if (USE_REVERSE_SAMPLING) castRays += CheckDiscontinuity(*newRay, hitTriangle, oldRay); 480 481 if (GVS_DEBUG) 482 currentViz.enlargedTriangle.push_back(p); 483 478 484 // subdivide further 479 castRays += SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay );480 castRays += SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay );485 castRays += SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay, level); 486 castRays += SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay, level); 481 487 482 488 rayTimer.Entry(); … … 526 532 527 533 SimpleRay sr(currentRay.GetOrigin(), rayDir, SamplingStrategy::GVS, 1.0f); 528 simpleRays.AddRay(sr); 529 } 534 simpleRays.AddRay(sr); 535 } 536 537 //if (rand() < RAND_MAX / 10) cout << "o: " << currentRay.GetOrigin() << endl; 530 538 531 539 ////////// … … 560 568 int castRays = (int)simpleRays.size(); 561 569 562 if (0) 563 { 564 // visualize enlarged triangles 565 VizStruct dummy; 566 dummy.enlargedTriangle = new Polygon3(enlargedTriangle); 567 dummy.originalTriangle = hitTriangle; 568 569 vizContainer.push_back(dummy); 570 570 if (GVS_DEBUG) 571 { 572 /*visTriangles.push_back(tObj); 573 574 for (int i = 0; i < 3; ++ i) 575 { 576 Triangle3 t1(hitTriangle.mVertices[i], enlargedTriangle[3 * i + 0], enlargedTriangle[3 * i + 1]); 577 Triangle3 t2(hitTriangle.mVertices[i], enlargedTriangle[3 * i + 1], enlargedTriangle[3 * i + 2]); 578 579 TriangleIntersectable *to1 = new TriangleIntersectable(t1); to1->SetId(tObj->GetId()); 580 TriangleIntersectable *to2 = new TriangleIntersectable(t2); to2->SetId(tObj->GetId()); 581 582 visTriangles.push_back(to1); 583 visTriangles.push_back(to2); 584 } 585 571 586 // set flags 572 587 VssRayContainer::const_iterator rit, rit_end = vssRays.end(); 573 588 574 589 for (rit = vssRays.begin(); rit != rit_end; ++ rit) 575 590 (*rit)->mFlags |= VssRay::BorderSample; 576 } 577 #if 0 578 // recursivly subdivide each edge 579 for (int i = 0; i < numBorderSamples; ++ i) 580 { 581 castRays += CheckDiscontinuity(*vssRays[i], hitTriangle, currentRay); 582 583 castRays += SubdivideEdge(hitTriangle, 584 enlargedTriangle[i], 585 enlargedTriangle[(i + 1) % numBorderSamples], 586 *vssRays[i], 587 *vssRays[(i + 1) % numBorderSamples], 588 currentRay); 589 } 590 #endif 591 */ 592 593 // visualize enlarged triangles 594 currentViz.enlargedTriangle = enlargedTriangle; 595 currentViz.originalTriangle = static_cast<TriangleIntersectable *>(tObj); 596 } 597 598 if (USE_SUBDIVISION) 599 { 600 //int oldsize = mTrianglePvs.size(); 601 602 // recursivly subdivide each edge 603 for (int i = 0; i < numBorderSamples; ++ i) 604 { 605 if (USE_REVERSE_SAMPLING) 606 castRays += CheckDiscontinuity(*vssRays[i], hitTriangle, currentRay); 607 608 castRays += SubdivideEdge(hitTriangle, 609 enlargedTriangle[i], 610 enlargedTriangle[(i + 1) % numBorderSamples], 611 *vssRays[i], 612 *vssRays[(i + 1) % numBorderSamples], 613 currentRay, 614 0); 615 } 616 617 //int newsize = mTrianglePvs.size();if(newsize - oldsize) mcout<<"found with subdiv: " << newsize - oldsize << endl; 618 } 619 620 if (GVS_DEBUG) 621 visTriangles.push_back(currentViz); 622 591 623 mGvsStats.mBorderSamples += castRays; 592 624 … … 652 684 653 685 #endif 686 654 687 ////////// 655 688 //-- fill up simple rays with random rays so we can cast 16 rays at a time 656 689 657 const int numRandomRays = 1 6 - ((int)simpleRays.size() % 16);690 const int numRandomRays = 128;//16 - ((int)simpleRays.size() % 16); 658 691 659 692 GenerateImportanceSamples(currentRay, hitTriangle, numRandomRays, simpleRays); … … 687 720 int castRays = (int)simpleRays.size(); 688 721 689 #if 0 690 for (size_t i = 0; i < vssRays.size(); ++ i) 691 { 692 // check for discontinuity and cast reverse rays if necessary 693 castRays += CheckDiscontinuity2(*vssRays[i], hitTriangle, currentRay); 694 } 695 #endif 722 mGvsStats.mBorderSamples += castRays; 723 724 if (USE_REVERSE_SAMPLING) 725 { 726 static SimpleRayContainer simpleRays; 727 simpleRays.clear(); 728 729 SimpleRay simpleRay; 730 for (size_t i = 0; i < vssRays.size(); ++ i) 731 { 732 // check for discontinuity and cast reverse rays if necessary 733 //castRays += CheckDiscontinuity2(*vssRays[i], hitTriangle, currentRay); 734 if (CheckDiscontinuity2(*vssRays[i], hitTriangle, currentRay, simpleRay)) 735 simpleRays.push_back(simpleRay); 736 } 737 738 static VssRayContainer reverseRays; 739 reverseRays.clear(); 740 CastRays(simpleRays, reverseRays, false, false); 741 742 mGvsStats.mReverseSamples += (int)reverseRays.size(); 743 744 castRays +=(int)reverseRays.size(); 745 } 746 696 747 #if 0 697 748 … … 704 755 *vssRays[i], 705 756 *vssRays[(i + 1) % numBorderSamples], 706 currentRay );757 currentRay, 0); 707 758 } 708 759 709 760 #endif 710 711 712 mGvsStats.mBorderSamples += castRays;713 761 714 762 // handle cast rays … … 886 934 887 935 castTimer.Exit(); 936 //for (int i = 0; i< simpleRays.size();++ i) 937 // if (rand() < RAND_MAX / 10) cout << "o: " << simpleRays[i].mOrigin << endl; 888 938 889 939 // add to ray queue … … 922 972 while (!mRayQueue.empty()) 923 973 { 974 size_t oldContri = mTrianglePvs.size(); 924 975 // handle next ray 925 976 VssRay *ray = mRayQueue.top(); … … 927 978 928 979 if (mUseDeterministicGvs) 980 { 929 981 castSamples += AdaptiveBorderSampling(*ray); 982 mRayCaster->SheduleRayForDeletion(ray); 983 } 930 984 else 985 { 931 986 castSamples += AdaptiveBorderSamplingOpt(*ray); 987 988 // ray still gives contribution => enqeue again 989 if ((mTrianglePvs.size() - oldContri) > 0) 990 { 991 mRayQueue.push(ray); 992 } 993 else 994 { 995 mRayCaster->SheduleRayForDeletion(ray); 996 } 997 } 998 999 932 1000 } 933 1001 … … 1374 1442 // provide list of view cells to compute 1375 1443 CompileViewCellsList(); 1376 1377 1444 // start per view cell gvs 1378 1445 PerViewCellComputation(); … … 1391 1458 if (GVS_DEBUG) 1392 1459 { 1393 Visualize();1394 1460 CLEAR_CONTAINER(mVssRays); 1395 1461 } … … 1411 1477 // store triangle directly 1412 1478 mViewCellsManager->DeterminePvsObjects(rays, true); 1413 }1414 1415 1416 void GvsPreprocessor::Visualize()1417 {1418 Exporter *exporter = Exporter::GetExporter("gvs.wrl");1419 1420 if (!exporter)1421 return;1422 1423 vector<VizStruct>::const_iterator vit, vit_end = vizContainer.end();1424 1425 for (vit = vizContainer.begin(); vit != vit_end; ++ vit)1426 {1427 exporter->SetWireframe();1428 exporter->ExportPolygon((*vit).enlargedTriangle);1429 //Material m;1430 exporter->SetFilled();1431 Polygon3 poly = Polygon3((*vit).originalTriangle);1432 exporter->ExportPolygon(&poly);1433 }1434 1435 VssRayContainer::const_iterator rit, rit_end = mVssRays.end();1436 1437 for (rit = mVssRays.begin(); rit != rit_end; ++ rit)1438 {1439 Intersectable *obj = (*rit)->mTerminationObject;1440 exporter->ExportIntersectable(obj);1441 }1442 1443 ExportVssRays(exporter, mVssRays);1444 1445 delete exporter;1446 1479 } 1447 1480 … … 1545 1578 if (passSamples >= mGvsSamplesPerPass) 1546 1579 { 1547 if ( GVS_DEBUG) VisualizeViewCell(mTrianglePvs);1580 if (0 && GVS_DEBUG) VisualizeViewCell(mTrianglePvs); 1548 1581 1549 1582 //const bool convertPerPass = true; … … 2049 2082 2050 2083 2084 void GvsPreprocessor::CollectProbablyVisibleItems(ProbablyVisibleQueue &vqueue) 2085 { 2086 ObjectPvsIterator pit = mCurrentViewCell->GetPvs().GetIterator(); 2087 static ObjectContainer tmpTriangles; 2088 2089 while (pit.HasMoreEntries()) 2090 { 2091 tmpTriangles.clear(); 2092 2093 Intersectable::NewMail(); 2094 2095 ProbablyVisibleItem *item = new ProbablyVisibleItem(); 2096 2097 KdIntersectable *kdObj = static_cast<KdIntersectable *>(pit.Next()); 2098 mKdTree->CollectObjects(kdObj->GetItem(), tmpTriangles); 2099 item->mNode = kdObj->GetItem(); 2100 2101 ObjectContainer::const_iterator oit, oit_end = tmpTriangles.end(); 2102 2103 for (oit = tmpTriangles.begin(); oit != oit_end; ++ oit) 2104 { 2105 TriangleIntersectable *triObj = static_cast<TriangleIntersectable *>(*oit); 2106 2107 // find objects which are not yet accounted for yet contained in kd pvs objects 2108 if (triObj->mCounter < ACCOUNTED_OBJECT) 2109 { 2110 item->mTriangles.push_back(triObj); 2111 } 2112 } 2113 } 2114 } 2115 2116 2051 2117 void GvsPreprocessor::CreateRandomizedReverseRays(const VssRay &ray, 2052 2118 const Vector3 &predictedPoint, -
GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h
r2742 r2743 99 99 100 100 101 struct ProbablyVisible TriangleContainer101 struct ProbablyVisibleItem 102 102 { 103 KdNode * node;103 KdNode *mNode; 104 104 ObjectContainer mTriangles; 105 105 }; 106 106 107 107 108 typedef FlexibleHeap<ProbablyVisible TriangleContainer *> ProbablyVisibleTriangleQueue;108 typedef FlexibleHeap<ProbablyVisibleItem *> ProbablyVisibleQueue; 109 109 110 110 … … 172 172 Does reverse sampling if gap found. 173 173 */ 174 int CheckDiscontinuity2(const VssRay ¤tRay, 175 const Triangle3 &hitTriangle, 176 const VssRay &oldRay); 174 bool CheckDiscontinuity2(const VssRay ¤tRay, 175 const Triangle3 &hitTriangle, 176 const VssRay &oldRay, 177 SimpleRay &simpleRay); 177 178 /** Adds new samples to the ray queue and classifies them 178 179 with respect to the previous ray. … … 191 192 const VssRay &ray1, 192 193 const VssRay &ray2, 193 const VssRay &oldRay); 194 195 void Visualize(); 194 const VssRay &oldRay, 195 int level); 196 196 197 197 void CreateDisplacedVertices(VertexContainer &vertices, … … 310 310 inline bool IntersectsViewCell(Vector3 &origin, const Vector3 &dir) const; 311 311 312 void DeleteOldRays(); 313 314 312 void CollectProbablyVisibleItems(ProbablyVisibleQueue &vqueue); 315 313 316 314 ////////////////////// -
GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp
r2729 r2743 120 120 { 121 121 //cout << "intel ray" << endl; 122 VssRay *vssRay 122 VssRay *vssRay = NULL; 123 123 int hits = 0; 124 124 int hittriangle; … … 126 126 127 127 float dist; 128 float dist1, dist2;129 128 double normal[3]; 130 129 … … 138 137 139 138 rawCastTimer.Exit(); 140 dist1 = dist;139 141 140 142 141 if (hittriangle != -1 ) { … … 145 144 if (intersect) 146 145 { 147 hitA.mObject = intersect; 148 hitA.mNormal = Vector3(normal[0], normal[1], normal[2]); 149 // Get the normal of that face 150 // Mesh *mesh = ((MeshInstance *)objectA)->GetMesh(); 151 // normalA = mesh->GetFacePlane(mFaceParents[forward_hit_triangles[i]].mFaceIndex).mNormal; 152 //-rays[index+i].mDirection; // $$ temporary 153 hitA.mPoint = simpleRay.Extrap(dist); 146 hitA.mObject = intersect; 147 hitA.mNormal = Vector3(normal[0], normal[1], normal[2]); 148 149 // Get the normal of that face 150 // Mesh *mesh = ((MeshInstance *)objectA)->GetMesh(); 151 // normalA = mesh->GetFacePlane(mFaceParents[forward_hit_triangles[i]].mFaceIndex).mNormal; 152 // -rays[index+i].mDirection; // $$ temporary 153 hitA.mPoint = simpleRay.Extrap(dist); 154 154 } 155 155 } … … 169 169 rawCastTimer.Exit(); 170 170 171 dist2 = dist; 172 173 Intersectable *intersect = mPreprocessor.GetParentObject(hittriangle); 171 Intersectable *intersect = mPreprocessor.GetParentObject(hittriangle); 174 172 175 173 if (intersect) 176 174 { 177 178 179 180 //Mesh *mesh = ((MeshInstance *)objectB)->GetMesh();181 //normalA = mesh->GetFacePlane(mFaceParents[forward_hit_triangles[i]].mFaceIndex).mNormal;182 183 184 } 185 } 186 175 hitB.mObject = intersect; 176 hitB.mNormal = Vector3(normal[0], normal[1], normal[2]); 177 // Get the normal of that face 178 // Mesh *mesh = ((MeshInstance *)objectB)->GetMesh(); 179 // normalA = mesh->GetFacePlane(mFaceParents[forward_hit_triangles[i]].mFaceIndex).mNormal; 180 //-rays[index+i].mDirection; // $$ temporary 181 hitB.mPoint = simpleRay.Extrap(dist); 182 } 183 } 184 /* 187 185 if (saveRays && preprocessor->mTotalRaysCast > saveRaysStart) { 188 186 if (castDoubleRay) … … 221 219 } 222 220 } 223 221 */ 224 222 return ProcessRay( 225 223 simpleRay, -
GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
r2736 r2743 9 9 #include "SimpleRay.h" 10 10 11 #define USE_RAY_POOL 11 12 12 13 namespace GtpVisibilityPreprocessor { … … 34 35 class GlRendererWidget; 35 36 class IntersectableGroup; 37 class TriangleIntersectable; 38 39 40 /** Hack: Visualization structure for the GVS algorithm. 41 */ 42 struct VizStruct 43 { 44 VertexContainer enlargedTriangle; 45 TriangleIntersectable *originalTriangle; 46 VssRay *ray; 47 }; 36 48 37 49 … … 299 311 // out here for visualization purpose 300 312 ObjectContainer mTrianglePvs; 313 vector<VizStruct> visTriangles; 301 314 302 315 // generic stats vector that can be used for anything -
GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlRenderer.cpp
r2741 r2743 128 128 KdTree *tree): 129 129 QGLPixelBuffer(QSize(w, h), 130 QGLFormat(QGL::SampleBuffers) 131 /*,| 132 QGL::StencilBuffer | 130 QGLFormat(QGL::StencilBuffer | 133 131 QGL::DepthBuffer | 134 132 QGL::DoubleBuffer | 135 133 QGL::Rgba) 136 */),134 ), 137 135 GlRendererBuffer(sceneGraph, viewcells, tree) 138 136 { … … 172 170 173 171 174 void QtGlRendererBuffer::RenderTrianglePvs() 175 { 176 //Intersectable::NewMail; 177 178 ObjectContainer::const_iterator oit, oit_end = 179 mViewCellsManager->GetPreprocessor()->mTrianglePvs.end(); 180 181 //int sz = mViewCellsManager->GetPreprocessor()->mDummyBuffer.size(); 182 183 for (oit = mViewCellsManager->GetPreprocessor()->mTrianglePvs.begin(); 184 oit != oit_end; ++ oit) 172 void GlRenderer::RenderVisTriangles() 173 { 174 DisableDrawArrays(); 175 176 vector<VizStruct>::const_iterator oit, oit_end = GetPreprocessor()->visTriangles.end(); 177 int currentId = 0; 178 //glEnable(GL_POINT_SMOOTH); 179 for (oit = GetPreprocessor()->visTriangles.begin(); oit != oit_end; ++ oit) 180 { 181 VizStruct viz = *oit; 182 TriangleIntersectable *triObj = viz.originalTriangle; 183 184 glColor3f(RandomValue(0.3f, 1.0f), RandomValue(0.3f, 1.0f), RandomValue(0.3f, 1.0f)); 185 RenderIntersectable(triObj); 186 187 glColor3f(1, 0, 0); 188 glPointSize(1.0); 189 190 glBegin(GL_POINTS); 191 192 VertexContainer::const_iterator vit, vit_end = viz.enlargedTriangle.end(); 193 194 for (vit = viz.enlargedTriangle.begin(); vit != vit_end; ++ vit) 195 { 196 Vector3 v = *vit; 197 glVertex3f(v.x, v.y, v.z); 198 } 199 200 glEnd(); 201 } 202 } 203 204 205 #if 0 206 207 void GlRenderer::RenderTrianglePvs() 208 { 209 DisableDrawArrays(); 210 211 ObjectContainer::const_iterator oit, oit_end = GetPreprocessor()->mTrianglePvs.end(); 212 213 for (oit = GetPreprocessor()->mTrianglePvs.begin(); oit != oit_end; ++ oit) 185 214 { 186 215 TriangleIntersectable *triObj = static_cast<TriangleIntersectable *>(*oit); 187 188 //int dum = mViewCellsManager->GetPreprocessor()->mDummyBuffer[i]; 189 //glColor3f(0, (float)dum / 20.0f, 1); 216 glColor3f(RandomValue(0.3f, 1.0f), RandomValue(0.3f, 1.0f), RandomValue(0.3f, 1.0f)); 190 217 if (mUseFalseColors) SetupFalseColor(triObj->mId); 191 218 192 219 RenderIntersectable(triObj); 193 194 /*if (!triObj->Mailed()) 195 triObj->Mail(); 196 else 197 cerr << "böser fehler" << endl; 198 */ 199 } 200 } 201 202 220 } 221 } 222 223 #else 224 225 void GlRenderer::RenderTrianglePvs() 226 { 227 if (GetPreprocessor()->mTrianglePvs.empty()) 228 return; 229 230 EnableDrawArrays(); 231 232 if (mUseVbos) 233 glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId); 234 235 unsigned int bufferSize = GetPreprocessor()->mTrianglePvs.size() * 3; 236 unsigned int *indices = new unsigned int[bufferSize]; 237 238 for (unsigned int i = 0; i < GetPreprocessor()->mTrianglePvs.size(); ++ i) 239 { 240 const int id = GetPreprocessor()->mTrianglePvs[i]->GetId() * 3; 241 242 indices[i * 3 + 0] = id + 0; 243 indices[i * 3 + 1] = id + 1; 244 indices[i * 3 + 2] = id + 2; 245 } 246 247 size_t offset = mObjects.size() * 3; 248 char *arrayPtr = mUseVbos ? NULL : (char *)mData; 249 250 glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr); 251 glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3)); 252 253 glDrawElements(GL_TRIANGLES, bufferSize, GL_UNSIGNED_INT, indices); 254 255 DisableDrawArrays(); 256 delete [] indices; 257 } 258 259 #endif 203 260 204 261 // reimplemented here so that we can snap the error windows … … 247 304 return 0.0f; 248 305 306 //mTopView = false; 307 SetupProjection(GetWidth(), GetHeight()); 249 308 SetupCamera(); 250 309 … … 257 316 GLfloat mat_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f}; 258 317 GLfloat mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; 259 GLfloat mat_specular[] = {0. 5f, 0.5f, 0.5f, 1.0f};260 GLfloat mat_shininess[] = { 1.0f};318 GLfloat mat_specular[] = {0.3f, 0.3f, 0.3f, 1.0f}; 319 GLfloat mat_shininess[] = {8.0f}; 261 320 262 321 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); … … 266 325 267 326 GLfloat light_ambient[] = {0.3, 0.3, 0.3, 1.0}; 268 //GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0};269 327 GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0}; 270 GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0};328 GLfloat light_specular[] = {0.6, 0.6, 0.6, 1.0}; 271 329 272 330 glEnable(GL_LIGHTING); … … 293 351 glDisable(GL_ALPHA_TEST); 294 352 353 glClearDepth(1.0f); 354 295 355 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 296 356 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); … … 302 362 glDepthMask(GL_TRUE); 303 363 glEnable(GL_DEPTH_TEST); 304 364 365 if (mDetectEmptyViewSpace) 366 glEnable(GL_CULL_FACE); 367 else 368 glDisable(GL_CULL_FACE); 369 305 370 glFrontFace(GL_CCW); 306 371 glCullFace(GL_BACK); … … 308 373 glStencilFunc(GL_EQUAL, 0x0, 0x1); 309 374 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 375 glDisable(GL_STENCIL_TEST); 310 376 311 377 KdNode::NewMail2(); 312 //Intersectable::NewMail(); 313 378 379 DisableDrawArrays(); 380 314 381 //mUseFalseColors = true; 315 382 // hack for gvs … … 322 389 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 323 390 324 glEnable(GL_STENCIL_TEST);391 //glEnable(GL_STENCIL_TEST); 325 392 326 393 // errors in red … … 332 399 333 400 KdNode::NewMail2(); 334 //Intersectable::NewMail(); 335 401 336 402 query->BeginQuery(); 337 403 … … 340 406 341 407 RenderScene(); 342 343 408 glFlush(); 344 409 345 410 query->EndQuery(); 411 346 412 glDisable(GL_STENCIL_TEST); 347 413 … … 396 462 // render pvs once 397 463 //RenderPvs(pvs); 398 EnableDrawArrays();399 464 //EnableDrawArrays(); 465 //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 400 466 // prepare pvs for rendering 401 PreparePvs(pvs); 402 _RenderColoredPvs(pvs); 467 //PreparePvs(pvs); 468 //_RenderColoredPvs(pvs); 469 //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 403 470 // hack for gvs visualization 404 471 //RenderTrianglePvs(); 472 RenderVisTriangles(); 405 473 406 474 glFlush(); … … 591 659 #if 0 592 660 for (dit = mDynamicPvsObjects.begin(); dit != dit_end; ++ dit) 593 {594 661 _RenderDynamicObject(*dit); 595 }596 662 #endif 597 663 //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 598 664 599 665 // show placed dynamic objects as wireframe 600 Preprocessor *p = mViewCellsManager->GetPreprocessor();666 Preprocessor *p = GetPreprocessor(); 601 667 dit_end = p->mDynamicObjects.end(); 602 668 … … 722 788 if (mRenderFilter) 723 789 { 790 bool oldWireFrame = mWireFrame; 724 791 mWireFrame = true; 725 792 RenderIntersectable(viewcell); 726 793 727 mWireFrame = false;794 mWireFrame = oldWireFrame; 728 795 } 729 796 } … … 1013 1080 { 1014 1081 glColor3f(0.6f, 0.6f, 0.6f); 1082 1083 if (mWireFrame) 1084 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 1085 else 1086 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 1087 1015 1088 VisualizePvs(); 1089 1090 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 1016 1091 } 1017 1092 … … 1068 1143 1069 1144 void 1070 QtGlRendererWidget::keyPressEvent ( QKeyEvent * e)1145 QtGlRendererWidget::keyPressEvent(QKeyEvent *e) 1071 1146 { 1072 1147 switch (e->key()) … … 1077 1152 break; 1078 1153 case Qt::Key_R: 1079 mUseRandomColorPerPvsObject = !mUseRandomColorPerPvsObject;; 1154 mUseRandomColorPerPvsObject = !mUseRandomColorPerPvsObject; 1155 updateGL(); 1156 break; 1157 case Qt::Key_W: 1158 mWireFrame = !mWireFrame; 1080 1159 updateGL(); 1081 1160 break; … … 1094 1173 updateGL(); 1095 1174 break; 1096 case Qt::Key_S: { 1097 // set view poitn and direction 1098 QString text; 1099 bool ok; 1100 text.sprintf("%f %f %f", mViewPoint.x, mViewPoint.y, mViewPoint.z); 1101 text = QInputDialog::getText(this, 1102 "Enter a view point", 1103 "", 1104 QLineEdit::Normal, 1105 text, 1106 &ok); 1107 if (!ok) 1108 break; 1109 1110 if (sscanf_s(text.toAscii(), "%f %f %f", &mViewPoint.x, &mViewPoint.y, &mViewPoint.z) == 3) { 1111 text.sprintf("%f %f %f", mViewDirection.x, mViewDirection.y, mViewDirection.z); 1175 case Qt::Key_S: 1176 { 1177 // set view poitn and direction 1178 QString text; 1179 bool ok; 1180 text.sprintf("%f %f %f", mViewPoint.x, mViewPoint.y, mViewPoint.z); 1112 1181 text = QInputDialog::getText(this, 1113 "Enter a direction",1182 "Enter a view point", 1114 1183 "", 1115 1184 QLineEdit::Normal, 1116 1185 text, 1117 1186 &ok); 1187 1118 1188 if (!ok) 1119 1189 break; 1120 if (sscanf_s(text.toAscii(), "%f %f %f", &mViewDirection.x, 1121 &mViewDirection.y, &mViewDirection.z) == 3) { 1122 updateGL(); 1190 1191 if (sscanf_s(text.toAscii(), "%f %f %f", &mViewPoint.x, &mViewPoint.y, &mViewPoint.z) == 3) 1192 { 1193 text.sprintf("%f %f %f", mViewDirection.x, mViewDirection.y, mViewDirection.z); 1194 text = QInputDialog::getText(this, 1195 "Enter a direction", 1196 "", 1197 QLineEdit::Normal, 1198 text, 1199 &ok); 1200 if (!ok) 1201 break; 1202 if (sscanf_s(text.toAscii(), "%f %f %f", &mViewDirection.x, 1203 &mViewDirection.y, &mViewDirection.z) == 3) { 1204 updateGL(); 1205 } 1206 break; 1123 1207 } 1124 break; 1125 } 1126 } 1208 1209 } 1127 1210 default: 1128 1211 cerr << "unknown key" << endl; … … 1156 1239 //mRenderVisibilityEstimates = true; 1157 1240 1241 mWireFrame = false; 1158 1242 mComputeGVS = false; 1159 1243 mUseRandomColorPerPvsObject = false; … … 1312 1396 { 1313 1397 cerr<<"stop computation called!\n"<<endl; 1314 mViewCellsManager->GetPreprocessor()->mStopComputation = true;1398 GetPreprocessor()->mStopComputation = true; 1315 1399 } 1316 1400 … … 1787 1871 } 1788 1872 1789 //mWireFrame = true;1790 1873 1791 // normalrendering1874 // default rendering 1792 1875 //if (!mShowPvsSizes && !mShowPiercingRays && !mShowWeightedRays && !mShowWeightedCost && !mShowComparison) 1793 1876 if (mUseStandardColors) … … 1835 1918 1836 1919 mUseFalseColors = false; 1837 mWireFrame = false;1920 //mWireFrame = false; 1838 1921 1839 1922 glPopAttrib(); … … 2711 2794 int QtGlRendererWidget::FindDynamicObject(float x, float y) 2712 2795 { 2713 2714 2796 if (GetPreprocessor()->mDynamicObjects.empty()) 2715 2797 return -1; -
GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlRenderer.h
r2736 r2743 76 76 int ComputePvs(ObjectContainer &objects, ObjectContainer &pvs) const; 77 77 78 /** quick hack in order to be able to render gvs based triangle pvs.79 */80 void RenderTrianglePvs();81 78 82 79 -
GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlViewer.cpp
r2709 r2743 28 28 { 29 29 scale = 1.0f; 30 mWire frame = false;30 mWireFrame = false; 31 31 mModelMatrix = IdentityMatrix(); 32 32 … … 235 235 236 236 case Qt::Key_W: 237 mWire frame = !mWireframe;237 mWireFrame = !mWireFrame; 238 238 updateGL(); 239 239 break; -
GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlViewer.h
r2657 r2743 45 45 void keyPressEvent(QKeyEvent * e); 46 46 47 bool mWireframe; 47 48 /////////////// 49 50 bool mWireFrame; 48 51 49 52 int timerId; -
GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp
r2742 r2743 32 32 { 33 33 VssRayContainer rays; 34 CastRay(simpleRay, rays, box, castDoubleRay, true); 34 //CastRay(simpleRay, rays, box, castDoubleRay, true); 35 CastRay(simpleRay, rays, box, castDoubleRay, false); 35 36 36 37 if (!rays.empty()) … … 409 410 410 411 411 /*void RayCaster::DeleteOldRays()412 {413 CLEAR_CONTAINER(mOldRays);414 }*/415 416 417 412 int 418 413 RayCaster::ProcessRay(const SimpleRay &simpleRay, … … 443 438 444 439 // regardless of the pruneInvalidRays setting reject 445 // rays whic degenerate to a point440 // rays which degenerate to a point 446 441 if (EpsilonEqualV3(hitA.mPoint, hitB.mPoint, Limits::Small)) { 447 442 #if DEBUG_PROCESS_RAY … … 462 457 // reset both contributions 463 458 if (!validA || !validB) { 464 if ( 0 ||pruneInvalidRays)459 if (pruneInvalidRays) 465 460 return 0; 466 461 -
GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
r2742 r2743 830 830 { 831 831 //mViewCell->GetRandomEdgePoint(origin, normal); 832 //origin = mViewCell->GetBox().GetRandomSurfacePoint();833 origin = mViewCell->GetBox().GetRandomPoint();834 //origin = Vector3(680.682, 189.552, -278.177);832 origin = mViewCell->GetBox().GetRandomSurfacePoint(); 833 //origin = mViewCell->GetBox().GetRandomPoint(); 834 //origin = Vector3(680.682, 189.552, -278.177); 835 835 // move a little bit back to avoid piercing through walls 836 836 // that bound the view cell -
GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp
r2601 r2743 296 296 297 297 // wireframe modes => set indexed lines 298 if (mWire frame)298 if (mWireFrame) 299 299 { 300 300 stream << "geometry IndexedLineSet {" << endl; … … 324 324 } 325 325 326 if (mWire frame) // final line to finish polygon326 if (mWireFrame) // final line to finish polygon 327 327 { 328 328 stream << (*face->mVertexIndices.begin()) << " "; … … 390 390 391 391 // wireframe modes => set indexed lines 392 if (mWire frame)392 if (mWireFrame) 393 393 { 394 394 stream << "geometry IndexedLineSet {" << endl; … … 413 413 } 414 414 415 if (mWire frame) // final line to finish polygon415 if (mWireFrame) // final line to finish polygon 416 416 { 417 417 stream << "0 "; … … 470 470 471 471 // wireframe modes => set indexed lines 472 if (mWire frame)472 if (mWireFrame) 473 473 { 474 474 stream << "geometry IndexedLineSet {" << endl; … … 562 562 } 563 563 564 bool savedWireframe = mWire frame;564 bool savedWireframe = mWireFrame; 565 565 566 566 SetWireframe(); -
GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp
r2601 r2743 311 311 312 312 313 if (mWire frame)313 if (mWireFrame) 314 314 stream<<"<IndexedLineSet coordIndex=\""<<endl; 315 315 else … … 326 326 for (; vi != face->mVertexIndices.end(); vi++) 327 327 stream<<*vi<<" "; 328 if (mWire frame) // final line to finish polygon328 if (mWireFrame) // final line to finish polygon 329 329 stream << (*face->mVertexIndices.begin()) << " "; 330 330 … … 344 344 stream<<"</Coordinate>"<<endl; 345 345 346 if (mWire frame)346 if (mWireFrame) 347 347 stream<<"</IndexedLineSet>"<<endl; 348 348 else … … 388 388 389 389 //-- create and write indices 390 if (mWire frame)390 if (mWireFrame) 391 391 stream<<"<IndexedLineSet coordIndex=\""<<endl; 392 392 else … … 400 400 stream << index << " "; 401 401 402 if (mWire frame) // final line to finish polygon402 if (mWireFrame) // final line to finish polygon 403 403 stream << "0 "; 404 404 … … 417 417 stream << "</Coordinate>" << endl; 418 418 419 if (mWire frame)419 if (mWireFrame) 420 420 stream << "</IndexedLineSet>" << endl; 421 421 else … … 456 456 457 457 //-- create and write indices 458 if (mWire frame)458 if (mWireFrame) 459 459 stream<<"<IndexedLineSet coordIndex=\""<<endl; 460 460 else … … 496 496 stream << "</Coordinate>" << endl; 497 497 498 if (mWire frame)498 if (mWireFrame) 499 499 stream << "</IndexedLineSet>" << endl; 500 500 else … … 539 539 } 540 540 541 bool savedWireframe = mWire frame;541 bool savedWireframe = mWireFrame; 542 542 543 543 SetWireframe(); -
GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
r2718 r2743 333 333 // NOTE: render texture should be power of 2 and square 334 334 // renderer must be initialised 335 const float w = 1024;336 const float h = 1024;335 const float w = 2048;//1024; 336 const float h = 2048;//1024; 337 337 338 338 QtGlRendererBuffer *glbuf =
Note: See TracChangeset
for help on using the changeset viewer.