Changeset 176


Ignore:
Timestamp:
07/15/05 18:21:11 (19 years ago)
Author:
bittner
Message:

cosine sampling bug fixed

Location:
trunk/VUT/GtpVisibilityPreprocessor/src
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/VUT/GtpVisibilityPreprocessor/src/Camera.cpp

    r162 r176  
    3030    for (x = 0; x < mWidth; x++) { 
    3131      SetupRay(ray, x, y); 
    32       MeshInstance::NewMail(); 
    3332      if (tree->CastRay(ray)) 
    3433        if (ray.intersections.size()) { 
     
    5049   
    5150  long t2 = GetTime(); 
    52   cout<<"#RAY_CAST_TIME"<<endl<<TimeDiff(t1, t2)<<endl; 
    53  
    54   cerr<<"Saving image"<<endl; 
    55   image.save(filename, "PNG"); 
     51  cout<<"#RAY_CAST_TIME\n"; 
     52  cout<<TimeDiff(t1, t2)<<"\n"; 
     53   
     54  cout<<"Saving image"<<endl; 
     55  image.save(filename.c_str(), "PNG"); 
    5656 
    5757  Exporter *exporter = NULL; 
     
    7272        if (0) 
    7373        for (i= 0; i < ray->meshes.size(); i++) 
    74           exporter->ExportMeshInstance(ray->meshes[i]); 
     74          exporter->ExportIntersectable(ray->meshes[i]); 
    7575 
    7676      } 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h

    r162 r176  
    55using namespace std; 
    66 
    7 class Mesh; 
    8 class MeshInstance; 
    97class ViewCell; 
    108class HierarchyNode; 
    119class SceneGraphNode; 
     10class Intersectable; 
    1211 
    1312/** Container for Mesh pointers primarily for the use within the kDTree and 
    1413    BSP hierarchies */ 
    15 typedef vector<MeshInstance *> MeshContainer; 
     14typedef vector<Intersectable *> ObjectContainer; 
    1615 
    1716/** Container for ViewCell pointers primarily for the use within the kDTree and 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h

    r170 r176  
    66using namespace std; 
    77 
     8#include "Material.h" 
     9 
    810class KdTree; 
    911class SceneGraphNode; 
    1012class Ray; 
    1113class AxisAlignedBox3; 
    12 class MeshInstance; 
     14class Intersectable; 
    1315 
    1416class Exporter 
     
    1719  string mFilename; 
    1820  bool wireframe; 
     21  bool mUseForcedMaterial; 
     22  Material mForcedMaterial; 
    1923 
    2024public: 
    2125   
    22   Exporter(const string filename):mFilename(filename),wireframe(false) 
     26  Exporter(const string filename):mFilename(filename), 
     27                                  wireframe(false), 
     28                                  mUseForcedMaterial(false) 
    2329  { 
    2430  } 
     
    3440 
    3541  virtual bool 
    36   ExportRays(const vector<Ray> &rays, const float length=1000) = 0; 
     42  ExportRays(const vector<Ray> &rays, 
     43             const float length=1000, 
     44             const RgbColor &color = RgbColor(1,1,1) 
     45             ) = 0; 
     46   
    3747 
    3848  virtual void 
    39   ExportMeshInstance(MeshInstance *mesh) = 0; 
    40    
     49  ExportIntersectable(Intersectable *object) = 0; 
     50 
    4151  void SetWireframe() { wireframe = true; } 
    4252  void SetFilled() { wireframe = false; } 
    4353 
     54  void SetForcedMaterial(const Material &m) { 
     55    mForcedMaterial = m; 
     56    mUseForcedMaterial = true; 
     57  } 
     58  void ResetForcedMaterial() { 
     59    mUseForcedMaterial = false; 
     60  } 
     61     
    4462  static Exporter * 
    4563  GetExporter(const string filename); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h

    r162 r176  
    22#define __INTERSECTABLE_H 
    33 
     4#include "AxisAlignedBox3.h" 
     5#include "Pvs.h" 
     6 
    47 
    58class Intersectable { 
     9public: 
     10  static int mailID; 
     11  int mailbox; 
     12 
     13  KdPvs mKdPvs; 
    614   
     15  enum { MESH_INSTANCE, TRANSFORMED_MESH_INSTANCE, SPHERE }; 
    716   
     17  Intersectable():mailbox(0) {} 
     18   
     19  void Mail() { mailbox = mailID; } 
     20  static void NewMail() { mailID++; } 
     21  bool Mailed() const { return mailbox == mailID; } 
     22   
     23  virtual AxisAlignedBox3 GetBox() = 0; 
     24   
     25  virtual int CastRay(Ray &ray) = 0; 
     26   
     27  virtual bool IsConvex() = 0; 
     28  virtual bool IsWatertight() = 0; 
     29  virtual float IntersectionComplexity() = 0; 
     30   
     31  virtual int Type() const = 0; 
     32 
     33  virtual void GetRandomSurfacePoint(Vector3 &point, Vector3 &normal) = 0; 
     34 
    835}; 
    936 
  • trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp

    r170 r176  
    6060  mBox.Initialize(); 
    6161   
    62   MeshContainer::const_iterator mi; 
     62  ObjectContainer::const_iterator mi; 
    6363  for ( mi = leaf->mObjects.begin(); 
    6464        mi != leaf->mObjects.end(); 
     
    239239  frontBBox.SetMin(axis, position); 
    240240 
    241   MeshContainer::const_iterator mi; 
     241  ObjectContainer::const_iterator mi; 
    242242 
    243243  for ( mi = leaf->mObjects.begin(); 
     
    391391   
    392392  // insert all queries  
    393   for(MeshContainer::const_iterator mi = node->mObjects.begin(); 
    394       mi < node->mObjects.end(); 
     393  for(ObjectContainer::const_iterator mi = node->mObjects.begin(); 
     394      mi != node->mObjects.end(); 
    395395      mi++) { 
    396396    AxisAlignedBox3 box = (*mi)->GetBox(); 
    397397 
    398     splitCandidates->push_back(SortableEntry(SortableEntry::MESH_MIN, 
     398    splitCandidates->push_back(SortableEntry(SortableEntry::BOX_MIN, 
    399399                                             box.Min(axis), 
    400                                              (void *)*mi) 
     400                                             *mi) 
    401401                               ); 
    402402     
    403403     
    404     splitCandidates->push_back(SortableEntry(SortableEntry::MESH_MAX, 
     404    splitCandidates->push_back(SortableEntry(SortableEntry::BOX_MAX, 
    405405                                             box.Max(axis), 
    406                                              (void *)*mi) 
     406                                             *mi) 
    407407                               ); 
    408408  } 
     
    429429  // C = ct_div_ci  + (ol + or)/queries 
    430430 
    431   int totalFaces = 0; 
     431  float totalIntersections = 0.0f; 
    432432  vector<SortableEntry>::const_iterator ci; 
    433433 
     
    435435      ci < splitCandidates->end(); 
    436436      ci++)  
    437     if ((*ci).type == SortableEntry::MESH_MIN) { 
    438       Mesh *mesh = ((MeshInstance *)(*ci).data)->GetMesh(); 
    439       totalFaces += mesh->mFaces.size(); 
    440     } 
    441  
    442   int facesLeft = 0; 
    443   int facesRight = totalFaces; 
     437    if ((*ci).type == SortableEntry::BOX_MIN) { 
     438      totalIntersections += (*ci).intersectable->IntersectionComplexity(); 
     439    } 
     440 
     441  float intersectionsLeft = 0; 
     442  float intersectionsRight = totalIntersections; 
    444443 
    445444  int objectsLeft = 0, objectsRight = node->mObjects.size(); 
     
    457456      ci < splitCandidates->end(); 
    458457      ci++) { 
    459     Mesh *mesh = ((MeshInstance *)(*ci).data)->GetMesh(); 
    460458    switch ((*ci).type) { 
    461     case SortableEntry::MESH_MIN: 
     459    case SortableEntry::BOX_MIN: 
    462460      objectsLeft++; 
    463       facesLeft += mesh->mFaces.size(); 
     461      intersectionsLeft += (*ci).intersectable->IntersectionComplexity(); 
    464462      break; 
    465     case SortableEntry::MESH_MAX: 
     463    case SortableEntry::BOX_MAX: 
    466464      objectsRight--; 
    467       facesRight -= mesh->mFaces.size(); 
     465      intersectionsRight -= (*ci).intersectable->IntersectionComplexity(); 
    468466      break; 
    469467    } 
     
    477475      float sum; 
    478476      if (mSahUseFaces) 
    479         sum = facesLeft*lbox.SurfaceArea() + facesRight*rbox.SurfaceArea(); 
     477        sum = intersectionsLeft*lbox.SurfaceArea() + intersectionsRight*rbox.SurfaceArea(); 
    480478      else 
    481479        sum = objectsLeft*lbox.SurfaceArea() + objectsRight*rbox.SurfaceArea(); 
     
    494492  } 
    495493   
    496   float oldCost = mSahUseFaces ? totalFaces : node->mObjects.size(); 
     494  float oldCost = mSahUseFaces ? totalIntersections : node->mObjects.size(); 
    497495  float newCost = mCt_div_ci + minSum/boxArea; 
    498496  float ratio = newCost/oldCost; 
     
    518516  float mint = 0; 
    519517 
    520    
     518  Intersectable::NewMail(); 
     519 
    521520  if (!mBox.GetMinMaxT(ray, &mint, &maxt)) 
    522521    return 0; 
     
    574573      ray.leaves.push_back(leaf); 
    575574       
    576       MeshContainer::const_iterator mi; 
     575      ObjectContainer::const_iterator mi; 
    577576      for ( mi = leaf->mObjects.begin(); 
    578577            mi != leaf->mObjects.end(); 
    579578            mi++) { 
    580         MeshInstance *mesh = *mi; 
    581         if (!mesh->Mailed() ) { 
    582           mesh->Mail(); 
     579        Intersectable *object = *mi; 
     580        if (!object->Mailed() ) { 
     581          object->Mail(); 
    583582          //ray.meshes.push_back(mesh); 
    584           hits += mesh->CastRay(ray); 
     583          hits += object->CastRay(ray); 
    585584        } 
    586585      } 
     
    608607} 
    609608 
     609void 
     610KdTree::CollectObjects(KdNode *n, ObjectContainer &objects) 
     611{ 
     612  stack<KdNode *> nodeStack; 
     613 
     614  nodeStack.push(n); 
     615 
     616  while (!nodeStack.empty()) { 
     617    KdNode *node = nodeStack.top(); 
     618    nodeStack.pop(); 
     619    if (node->IsLeaf()) { 
     620      KdLeaf *leaf = (KdLeaf *)node; 
     621      for (int j=0; j < leaf->mObjects.size(); j++) { 
     622        Intersectable *object = leaf->mObjects[j]; 
     623        if (!object->Mailed()) { 
     624          object->Mail(); 
     625          objects.push_back(object); 
     626        } 
     627      } 
     628    } else { 
     629      KdInterior *interior = (KdInterior *)node; 
     630      nodeStack.push(interior->mFront); 
     631      nodeStack.push(interior->mBack); 
     632    } 
     633  } 
     634} 
  • trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.h

    r170 r176  
    1313class KdLeaf; 
    1414class KdInterior; 
     15class Intersectable; 
    1516 
    1617 
     
    156157 
    157158  /** pointers to occluders contained in this node */ 
    158   MeshContainer mObjects; 
     159  ObjectContainer mObjects; 
    159160   
    160161  /** pointers to viewcells contained in this node */ 
     
    220221  KdTree(); 
    221222   
    222   /** Insert occluder into the tree */ 
    223   virtual void InsertOccluder(Mesh *occluder) { 
    224     //      mRoot->mOccluders.push_back(occluder); 
    225   } 
    226  
    227   /** Insert occludee into the tree */ 
    228   virtual void InsertOccludee(Mesh *occludee) { 
    229     //      mRoot->mOccludees.push_back(occludee); 
    230   } 
    231223     
    232224  /** Insert view cell into the tree */ 
     
    266258  } 
    267259 
     260  void 
     261  CollectObjects(KdNode *n, ObjectContainer &objects); 
     262   
    268263    AxisAlignedBox3 GetBox(const KdNode *node) const { 
    269264    KdInterior *parent = node->mParent; 
     
    383378  { 
    384379    enum { 
    385       MESH_MIN, 
    386       MESH_MAX 
     380      BOX_MIN, 
     381      BOX_MAX 
    387382    }; 
    388383     
    389384    int type; 
    390385    float value; 
    391     void *data; 
     386    Intersectable *intersectable; 
    392387     
    393388    SortableEntry() {} 
    394     SortableEntry(const int t, const float v, void *d):type(t), 
    395                                                        value(v), 
    396                                                        data(d) {} 
     389    SortableEntry(const int t, const float v, Intersectable *i):type(t), 
     390                                                                value(v), 
     391                                                                intersectable(i) {} 
    397392     
    398393    bool operator<(const SortableEntry &b) const { 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Matrix4x4.cpp

    r162 r176  
    300300{ 
    301301  Vector3 vec = CrossProd(vecStart, vecTo); 
    302  
     302   
    303303  if (Magnitude(vec) > Limits::Small) { 
    304304    // vector exist, compute angle 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Matrix4x4.h

    r162 r176  
    4747  // create the rotation matrix that rotates 'vecFrom' to 'vecTo' 
    4848  friend Matrix4x4 RotationVectorsMatrix(const Vector3 &vecFrom, 
    49                                         const Vector3 &vecTo); 
     49                                         const Vector3 &vecTo); 
    5050   
    5151  friend Matrix4x4 ScaleMatrix(float X, float Y, float Z); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp

    r170 r176  
    88Mesh::Preprocess() 
    99{ 
    10   mBoundingBox.Initialize(); 
     10  mBox.Initialize(); 
    1111 
    1212  VertexContainer::const_iterator vi = mVertices.begin(); 
    1313  for (; vi != mVertices.end(); vi++) { 
    14     mBoundingBox.Include(*vi); 
    15   } 
    16    
     14    mBox.Include(*vi); 
     15  } 
     16   
     17  /** true if it is a watertight convex mesh */ 
    1718  mIsConvex = false; 
    18  
    19   if (mFaces.size() > 2*MeshKdTree::mTermMinCost) { 
     19   
     20  if (mFaces.size() > MeshKdTree::mTermMinCost) { 
    2021    mKdTree = new MeshKdTree(this); 
    2122    MeshKdLeaf *root = (MeshKdLeaf *)mKdTree->GetRoot(); 
     
    2425    cout<<"KD"; 
    2526    mKdTree->Construct(); 
     27 
     28    if (mKdTree->GetRoot()->IsLeaf()) { 
     29      cout<<"d"; 
     30      delete mKdTree; 
     31    } 
    2632  } 
    2733} 
     
    252258 
    253259 
     260void 
     261Mesh::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal) 
     262{ 
     263  int faceIndex = RandomValue(0, mFaces.size()-1); 
     264   
     265  // assume the face is convex and generate a convex combination 
     266  // 
     267  Face *face = mFaces[faceIndex]; 
     268  point = Vector3(0,0,0); 
     269  float sum = 0.0f; 
     270  for (int i = 0; i < face->mVertexIndices.size(); i++) { 
     271    float r = RandomValue(0,1); 
     272    sum += r; 
     273    point += mVertices[face->mVertexIndices[i]]*r; 
     274  } 
     275  point *= 1.0f/sum; 
     276  normal = GetFacePlane(faceIndex).mNormal; 
     277} 
     278 
     279 
    254280int 
    255281MeshInstance::CastRay( 
     
    271297 
    272298 
     299 
     300void 
     301MeshInstance::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal) 
     302{ 
     303  mMesh->GetRandomSurfacePoint(point, normal); 
     304} 
     305 
     306void 
     307TransformedMeshInstance::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal) 
     308{ 
     309  mMesh->GetRandomSurfacePoint(point, normal); 
     310  point = mWorldTransform*point; 
     311  normal = TransformNormal(mWorldTransform, normal); 
     312} 
     313 
    273314Plane3 
    274315Mesh::GetFacePlane(const int faceIndex) 
     
    281322 
    282323int 
    283 MeshTransformedInstance::CastRay( 
     324TransformedMeshInstance::CastRay( 
    284325                                 Ray &ray 
    285326                                 ) 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h

    r170 r176  
    5050class Mesh { 
    5151 
    52  
    5352public: 
    5453 
     
    5857  /// Constructor with container preallocation 
    5958  Mesh(const int vertices, 
    60        const int faces):mVertices(), 
    61                         mFaces(), 
    62                         mMaterial(NULL) 
     59       const int faces): 
     60    mFaces(), 
     61    mMaterial(NULL), 
     62    mKdTree(NULL), 
     63    mVertices(), 
     64    mIsConvex(false), 
     65    mIsWatertight(false) 
    6366  { 
    6467    mVertices.reserve(vertices); 
     
    7881  void Preprocess(); 
    7982 
    80   /** Axis aligned bounding box of the mesh */ 
    81   AxisAlignedBox3 mBoundingBox; 
     83  /** Axis aligned bounding box of the mesh in local mesh coordinates */ 
     84  AxisAlignedBox3 mBox; 
    8285   
    8386  /** Vertices forming the mesh */ 
     
    9295  /** true if the mesh is a convex mesh */ 
    9396  bool mIsConvex; 
     97 
     98  /** true if the mesh is a convex mesh */ 
     99  bool mIsWatertight; 
    94100 
    95101  MeshKdTree *mKdTree; 
     
    128134 
    129135  AxisAlignedBox3 GetFaceBox(const int faceIndex); 
    130    
     136 
     137  void GetRandomSurfacePoint(Vector3 &point, Vector3 &normal); 
     138 
    131139}; 
    132140 
    133141class MeshInstance : public Intersectable { 
    134142protected: 
    135   static int mailID; 
    136   int mailbox; 
    137   float mVisibility; 
    138143  Mesh *mMesh; 
    139144   
    140145public: 
    141   MeshInstance(Mesh *mesh):mMesh(mesh), mVisibility(1.0f), mailbox(0) 
    142   { 
    143   } 
    144    
    145   void Mail() { mailbox = mailID; } 
    146   static void NewMail() { mailID++; } 
    147   bool Mailed() const { return mailbox == mailID; } 
    148    
     146  MeshInstance(Mesh *mesh):Intersectable(), mMesh(mesh) 
     147  { 
     148  } 
     149 
     150  void GetRandomSurfacePoint(Vector3 &point, Vector3 &normal); 
     151 
    149152 
    150153  Mesh *GetMesh() { return mMesh; } 
    151154 
    152155  virtual AxisAlignedBox3 GetBox() { 
    153     return mMesh->mBoundingBox; 
     156    return mMesh->mBox; 
    154157  } 
    155158 
     
    158161          Ray &ray 
    159162          ); 
    160    
     163 
     164  virtual bool IsConvex() { return mMesh->mIsConvex; } 
     165  virtual bool IsWatertight() { return mMesh->mIsWatertight; } 
     166  virtual float IntersectionComplexity() {  return mMesh->mFaces.size(); } 
     167 
     168  virtual int Type() const { return MESH_INSTANCE; } 
     169 
    161170  virtual int 
    162171  CastRay( 
     
    169178 
    170179 
    171 class MeshTransformedInstance : public MeshInstance 
     180class TransformedMeshInstance : public MeshInstance 
    172181{ 
    173182public: 
    174   MeshTransformedInstance(Mesh *mesh):MeshInstance(mesh) 
     183  TransformedMeshInstance(Mesh *mesh):MeshInstance(mesh) 
    175184  { 
    176185    mWorldTransform = IdentityMatrix(); 
     
    178187   
    179188  virtual AxisAlignedBox3 GetBox() { 
    180     return Transform(mMesh->mBoundingBox, 
     189    return Transform(mMesh->mBox, 
    181190                     mWorldTransform); 
    182191  } 
    183  
     192   
    184193  virtual int 
    185194  CastRay( 
    186195          Ray &ray 
    187196          ); 
     197 
     198  virtual int Type() const { return TRANSFORMED_MESH_INSTANCE; } 
     199 
     200  void GetRandomSurfacePoint(Vector3 &point, Vector3 &normal); 
    188201 
    189202private: 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp

    r170 r176  
    5454  // add mesh instances of the scene graph to the root of the tree 
    5555  KdLeaf *root = (KdLeaf *)mKdTree->GetRoot(); 
    56   mSceneGraph->CollectMeshInstaces(&root->mObjects); 
     56  mSceneGraph->CollectObjects(&root->mObjects); 
    5757   
    5858  mKdTree->Construct(); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h

    r162 r176  
    8484   
    8585  /// list of all loaded occluders 
    86   MeshContainer mOccluders; 
     86  ObjectContainer mOccluders; 
    8787  /// list of all loaded occludees 
    88   MeshContainer mOccludees; 
     88  ObjectContainer mOccludees; 
    8989  /// list of all loaded/generated viewcells 
    9090  ViewCellContainer mViewcells; 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h

    r162 r176  
    2828    // the point of intersection 
    2929    float mT; 
     30 
    3031    // can be either mesh or a viewcell 
    3132    Intersectable *mObject; 
     33 
    3234    // the face of the intersectable 
    3335    int mFace; 
     36 
    3437    RayIntersection(const float t, 
    3538                    Intersectable *object, 
    3639                    const int face):mT(t), mObject(object), mFace(face) {} 
     40 
    3741    RayIntersection() {} 
    3842 
     
    4448        b.mT; 
    4549    } 
    46  
    47  
    4850     
    4951  }; 
     52   
     53  // I should have some abstract cell data type !!! here 
     54  // corresponds to the spatial elementary cell 
     55  /** intersection with the source object if any */ 
     56  RayIntersection sourceObject; 
    5057   
    5158  vector<RayIntersection> intersections; 
     
    6168    dir = Normalize(whichdir); 
    6269    mType = _type; 
    63     origin = _originCell; 
    64     termination = NULL; 
    6570    depth = 0; 
    6671    Init(); 
     
    7277  // Inititalize the ray again when already constructed 
    7378  void Init(const Vector3 &wherefrom, const Vector3 &whichdir, 
    74             const int _type, const void *_originCell = NULL, 
     79            const int _type,  
    7580            bool dirNormalized = false) { 
    7681    loc = wherefrom; 
    7782    dir = (dirNormalized) ? whichdir: Normalize(whichdir) ; 
    7883    mType = _type; 
    79     origin = _originCell; 
    80     termination = NULL; 
    8184    depth = 0; 
    8285    Init(); 
     
    146149  } 
    147150 
    148   // the cell in the ASDS, where ray starts from 
    149   void SetOrigin(const void *c) {origin = c;} 
    150   const void *GetOrigin() const  { return origin; } 
    151  
    152   // the cell in the ASDS, where ray finishes the walk 
    153   void SetTermination(const void *c) {termination = c; } 
    154   const void* GetTermination() const { return termination;} 
    155151 
    156152  // the object on which the ray starts at 
     
    183179  Vector3 loc, dir;             // Describes ray origin and vector 
    184180   
    185    
    186181  // The inverted direction of the ray components. It is computed optionally 
    187182  // by the ray traversal algorithm using function ComputeInvertedDir(); 
     
    191186  int mType; 
    192187  
    193   // I should have some abstract cell data type !!! here 
    194   // corresponds to the spatial elementary cell 
    195   const void *origin; 
    196   const void *termination; 
    197188   
    198189  // unique ID of a ray for the use in the mailboxes 
    199190  int ID; 
     191   
    200192  // unique ID of a ray for the use with a transformations - this one 
    201193  // never can be changed that allows the nesting of transformations 
  • trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp

    r162 r176  
     1#include "SceneGraph.h" 
     2#include "KdTree.h" 
    13#include "SamplingPreprocessor.h" 
     4#include "X3dExporter.h" 
    25 
     6SamplingPreprocessor::SamplingPreprocessor() 
     7{ 
     8  // this should increase coherence of the samples 
     9  mSamplesPerPass = 1; 
     10  mTotalSamples = 1e8; 
     11  mKdPvsDepth = 10; 
    312 
     13} 
     14 
     15void 
     16SamplingPreprocessor::SetupRay(Ray &ray, const Vector3 &point, const Vector3 &direction) 
     17{ 
     18  ray.intersections.clear(); 
     19  ray.leaves.clear(); 
     20  ray.meshes.clear(); 
     21  //  cout<<point<<" "<<direction<<endl; 
     22  ray.Init(point, direction, Ray::LOCAL_RAY); 
     23} 
     24 
     25KdNode * 
     26SamplingPreprocessor::GetNodeForPvs(KdLeaf *leaf) 
     27{ 
     28  KdNode *node = leaf; 
     29  while (node->mParent && node->mDepth > mKdPvsDepth) 
     30    node = node->mParent; 
     31  return node; 
     32} 
     33 
     34int 
     35SamplingPreprocessor::AddNodeSamples(Intersectable *object, const Ray &ray) 
     36{ 
     37  int contributingSamples = 0; 
     38 
     39  for (int j=0; j < ray.leaves.size(); j++) { 
     40    KdNode *node = GetNodeForPvs( ray.leaves[j] ); 
     41    contributingSamples += object->mKdPvs.AddNodeSample(node); 
     42  } 
    443   
     44  return contributingSamples; 
     45} 
     46 
    547bool 
    648SamplingPreprocessor::ComputeVisibility() 
    749{ 
    8   return true; 
    9 }; 
     50 
     51  // pickup an object 
     52  ObjectContainer objects; 
     53   
     54  mSceneGraph->CollectObjects(&objects); 
     55 
     56  Vector3 point, normal, direction; 
     57  Ray ray; 
     58 
     59  long startTime = GetTime(); 
     60   
     61  int i; 
     62  int pass = 0; 
     63  int totalSamples = 0; 
    1064 
    1165 
     66  int pvsOut = Min((int)objects.size(), 10); 
     67   
     68  vector<Ray> rays[10]; 
     69   
     70  while (totalSamples < mTotalSamples) { 
     71 
     72    int passContributingSamples = 0; 
     73    int passSampleContributions = 0; 
     74    int passSamples = 0; 
     75     
     76    for (i =0; i < objects.size(); i++) { 
     77      for (int k=0; k < mSamplesPerPass; k++) { 
     78        Intersectable *object = objects[i]; 
     79        object->GetRandomSurfacePoint(point, normal); 
     80        direction = UniformRandomVector(normal); 
     81        // construct a ray 
     82        SetupRay(ray, point, direction); 
     83        mKdTree->CastRay(ray); 
     84 
     85        if (i < pvsOut) 
     86          rays[i].push_back(ray); 
     87         
     88        int sampleContributions = 0; 
     89         
     90        if (ray.leaves.size()) { 
     91          sampleContributions += AddNodeSamples(object, ray); 
     92           
     93          if (ray.intersections.size()) { 
     94            sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray); 
     95            // check whether we can add this to the rays 
     96            for (int j = 0; j < pvsOut; j++) { 
     97              if (objects[j] == ray.intersections[0].mObject) { 
     98                rays[j].push_back(ray); 
     99              } 
     100            } 
     101          } 
     102          passSamples++; 
     103          if (sampleContributions) { 
     104            passContributingSamples++; 
     105            passSampleContributions += sampleContributions; 
     106          } 
     107        } 
     108      } 
     109    } 
     110    totalSamples += passSamples; 
     111    pass++; 
     112     
     113    int pvsSize = 0; 
     114    for (i=0; i < objects.size(); i++) { 
     115      Intersectable *object = objects[i]; 
     116      pvsSize += object->mKdPvs.mEntries.size(); 
     117    } 
     118     
     119    cout<<"pass "<<pass<<" : t = "<<TimeDiff(startTime, GetTime())*1e-3<<"s"<<endl; 
     120    cout<<"#totalSamples="<<totalSamples/1000<< 
     121      "k   #sampleContributions="<<passSampleContributions<< 
     122      " ("<<100*passContributingSamples/passSamples<<"%)"<< 
     123      " avgPVS="<<pvsSize/(float)objects.size()<<endl; 
     124  } 
     125  bool exportRays = false; 
     126  if (exportRays) { 
     127    Exporter *exporter = NULL; 
     128    exporter = Exporter::GetExporter("sample-rays.x3d"); 
     129    exporter->SetWireframe(); 
     130    exporter->ExportKdTree(*mKdTree); 
     131    for (i=0; i < pvsOut; i++)  
     132      exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0)); 
     133    exporter->SetFilled(); 
     134    delete exporter; 
     135  } 
     136 
     137  if (1) { 
     138    for (int k=0; k < pvsOut; k++) { 
     139      Intersectable *object = objects[k]; 
     140      char s[64]; 
     141      sprintf(s, "sample-pvs%04d.x3d", k); 
     142      Exporter *exporter = Exporter::GetExporter(s); 
     143      exporter->SetWireframe(); 
     144      KdPvsMap::iterator i = object->mKdPvs.mEntries.begin(); 
     145      Intersectable::NewMail(); 
     146        // avoid adding the object to the list 
     147      object->Mail(); 
     148      ObjectContainer visibleObjects; 
     149      for (; i != object->mKdPvs.mEntries.end(); i++) { 
     150        KdNode *node = (*i).first; 
     151        exporter->ExportBox(mKdTree->GetBox(node)); 
     152        mKdTree->CollectObjects(node, visibleObjects); 
     153      } 
     154       
     155      exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0)); 
     156      exporter->SetFilled(); 
     157 
     158      for (int j = 0; j < visibleObjects.size(); j++) 
     159        exporter->ExportIntersectable(visibleObjects[j]); 
     160         
     161      Material m; 
     162      m.mDiffuseColor = RgbColor(1, 0, 0); 
     163      exporter->SetForcedMaterial(m); 
     164      exporter->ExportIntersectable(object); 
     165       
     166      delete exporter; 
     167    } 
     168     
     169  } 
     170   
     171  return true; 
     172} 
     173 
     174   
     175 
     176     
  • trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h

    r162 r176  
    99class SamplingPreprocessor : public Preprocessor { 
    1010public: 
     11  int mSamplesPerPass; 
     12  int mTotalSamples; 
     13  int mKdPvsDepth; 
     14   
     15  SamplingPreprocessor(); 
     16 
    1117  virtual bool ComputeVisibility(); 
     18 
     19  void 
     20  SetupRay(Ray &ray, const Vector3 &point, const Vector3 &direction); 
     21 
     22  KdNode * 
     23  GetNodeForPvs(KdLeaf *leaf); 
     24 
     25  int 
     26  AddNodeSamples(Intersectable *object, const Ray &ray); 
     27 
    1228}; 
    1329 
  • trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp

    r162 r176  
    2626 
    2727int 
    28 SceneGraph::CollectMeshInstaces(MeshContainer *instances) 
     28SceneGraph::CollectObjects(ObjectContainer *instances) 
    2929{ 
    3030  int number = 0; 
    3131  stack<SceneGraphNode *> nodeStack; 
    32  
     32   
    3333  nodeStack.push(mRoot); 
    3434   
     
    3737    nodeStack.pop(); 
    3838 
    39     MeshContainer::const_iterator mi = node->mGeometry.begin(); 
     39    ObjectContainer::const_iterator mi = node->mGeometry.begin(); 
    4040    for (; mi != node->mGeometry.end(); mi++) 
    4141      instances->push_back(*mi); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.h

    r162 r176  
    1313class SceneGraphNode { 
    1414public: 
    15    
    16    
    17   MeshContainer mGeometry; 
     15  ObjectContainer mGeometry; 
    1816  SceneGraphNodeContainer mChildren; 
    1917  AxisAlignedBox3 mBox; 
     
    2826  bool Export(const string filename); 
    2927   
    30   int CollectMeshInstaces(MeshContainer *instances); 
     28  int CollectObjects(ObjectContainer *instances); 
    3129   
    3230protected: 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Vector3.cpp

    r162 r176  
     1#include "Matrix4x4.h" 
    12#include "Vector3.h" 
    23 
     
    188189  return;   
    189190} 
     191 
     192Vector3 
     193UniformRandomVector(const Vector3 &normal) 
     194{ 
     195  float r1 = RandomValue(0.0f, 1.0f); 
     196  float r2 = RandomValue(0.0f, 1.0f); 
     197  float cosTheta = 1.0f - r1; 
     198  float sinTheta = sqrt(1 - sqr(cosTheta)); 
     199  float fi = 2.0f*M_PI*r2; 
     200   
     201  Vector3 dir(sinTheta*sin(fi), 
     202              cosTheta, 
     203              sinTheta*cos(fi)); 
     204 
     205   
     206  //  return Normalize(dir); 
     207 
     208  Matrix4x4 m = RotationVectorsMatrix( 
     209                                      normal, 
     210                                      Vector3(0,1,0)); 
     211  Matrix4x4 mi = Invert(m); 
     212  m = m*RotationVectorsMatrix( 
     213                              Vector3(0,1,0), 
     214                              Normalize(dir))*mi; 
     215   
     216  return TransformNormal(m, normal); 
     217   
     218//    return TransformNormal( 
     219//                       RotationVectorsMatrix( 
     220//                                             Vector3(0,1,0), 
     221//                                             Normalize(dir) 
     222//                                             ), 
     223//                       normal 
     224//                       ); 
     225} 
  • trunk/VUT/GtpVisibilityPreprocessor/src/Vector3.h

    r162 r176  
    226226  friend inline int EpsilonEqualV3(const Vector3 &v1, const Vector3 &v2, float thr); 
    227227  friend inline int EpsilonEqualV3(const Vector3 &v1, const Vector3 &v2); 
     228 
     229  friend Vector3 UniformRandomVector(const Vector3 &normal); 
    228230}; 
    229231 
     
    411413{ 
    412414  return Vector3(A.y * B.z - A.z * B.y, 
    413                    A.z * B.x - A.x * B.z, 
    414                    A.x * B.y - A.y * B.x); 
     415                 A.z * B.x - A.x * B.z, 
     416                 A.x * B.y - A.y * B.x); 
    415417} 
    416418 
  • trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp

    r162 r176  
    2323} 
    2424 
     25 
    2526bool 
    26 X3dExporter::ExportRays(const vector<Ray> &rays, const float length) 
     27X3dExporter::ExportRays(const vector<Ray> &rays, 
     28                        const float length, 
     29                        const RgbColor &color) 
    2730{ 
    2831  vector<Ray>::const_iterator ri = rays.begin(); 
    2932  stream<<"<Shape>"<<endl; 
     33  stream<<"<Appearance>"<<endl; 
     34  stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<< 
     35    "\" />"<<endl; 
     36  stream<<"</Appearance>"<<endl; 
     37   
    3038  stream<<"<IndexedLineSet ccw=\"TRUE\" coordIndex=\""<<endl; 
    3139 
     
    4351  for (; ri != rays.end(); ri++) { 
    4452    Vector3 a = (*ri).GetLoc(); 
    45     Vector3 b = (*ri).GetLoc() + length*(*ri).GetDir(); 
     53     
     54    Vector3 b; 
     55    if (length < 0) 
     56      b = (*ri).GetLoc() - length*(*ri).GetDir(); 
     57    else 
     58      if ((*ri).intersections.size()==0) 
     59        b = (*ri).GetLoc() + length*(*ri).GetDir(); 
     60      else 
     61        b = (*ri).Extrap((*ri).intersections[0].mT); 
    4662     
    4763    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,"; 
     
    6682   
    6783   
    68   MeshContainer::const_iterator mi = node->mGeometry.begin(); 
     84  ObjectContainer::const_iterator mi = node->mGeometry.begin(); 
    6985  for (; mi != node->mGeometry.end(); mi++) { 
    7086    // export the transform... 
    71     ExportMesh((*mi)->GetMesh()); 
     87    ExportIntersectable(*mi); 
    7288  } 
    7389   
    7490  stream<<"</Group>"<<endl; 
    7591 
     92} 
     93void 
     94X3dExporter::ExportIntersectable(Intersectable *object) 
     95{ 
     96  switch (object->Type()) { 
     97  case Intersectable::MESH_INSTANCE: 
     98  case Intersectable::TRANSFORMED_MESH_INSTANCE: 
     99    ExportMeshInstance((MeshInstance *)object); 
     100    break; 
     101  default: 
     102    cerr<<"Sorry the export for object not yet defined"<<endl; 
     103    break; 
     104  } 
     105} 
     106 
     107void 
     108X3dExporter::ExportMeshInstance(MeshInstance *object) 
     109{ 
     110  // $$JB$$ 
     111  // in the future check whether the mesh was not already exportet 
     112  // and use a reference to the that mesh instead 
     113  ExportMesh(object->GetMesh()); 
    76114} 
    77115 
     
    82120  stream<<"<Shape>"<<endl; 
    83121  stream<<"<Appearance>"<<endl; 
    84  
     122   
    85123  // $$ tmp -> random material 
    86124   
    87125  float r, g, b; 
    88126 
    89   if (mesh->mMaterial) { 
    90     r = mesh->mMaterial->mDiffuseColor.r; 
    91     g = mesh->mMaterial->mDiffuseColor.g; 
    92     b = mesh->mMaterial->mDiffuseColor.b; 
    93   } else { 
    94     r = RandomValue(0.5, 1.0); 
    95     g = RandomValue(0.5, 1.0); 
    96     b = RandomValue(0.5, 1.0); 
    97   } 
     127  if (mUseForcedMaterial) { 
     128    r = mForcedMaterial.mDiffuseColor.r; 
     129    g = mForcedMaterial.mDiffuseColor.g; 
     130    b = mForcedMaterial.mDiffuseColor.b; 
     131     
     132  } else 
     133    if (mesh->mMaterial) { 
     134      r = mesh->mMaterial->mDiffuseColor.r; 
     135      g = mesh->mMaterial->mDiffuseColor.g; 
     136      b = mesh->mMaterial->mDiffuseColor.b; 
     137    } else { 
     138      r = RandomValue(0.5, 1.0); 
     139      g = RandomValue(0.5, 1.0); 
     140      b = RandomValue(0.5, 1.0); 
     141    } 
    98142  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<< 
    99143    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl; 
     
    205249 
    206250 
    207 void 
    208 X3dExporter::ExportMeshInstance(MeshInstance *mi) 
    209 { 
    210   ExportMesh(mi->GetMesh()); 
    211 } 
  • trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.h

    r162 r176  
    1212class SceneGraphNode; 
    1313class Mesh; 
    14  
    15  
     14class Intersectable; 
     15class MeshInstance; 
    1616 
    1717class X3dExporter : public Exporter 
     
    2727 
    2828  bool 
    29   ExportRays(const vector<Ray> &rays, const float length=1000); 
     29  ExportRays(const vector<Ray> &rays, 
     30             const float length=1000, 
     31             const RgbColor &color = RgbColor(1,1,1)); 
    3032 
    3133  bool 
     
    3941  } 
    4042   
    41   bool 
     43  virtual bool 
    4244  ExportBox(const AxisAlignedBox3 &box); 
    4345 
     
    4547  ExportMeshInstance(MeshInstance *mi); 
    4648 
    47   void 
     49  virtual void 
     50  ExportIntersectable(Intersectable *object); 
     51 
     52  virtual void 
    4853  ExportMesh(Mesh *mesh); 
    4954 
     55 
    5056protected: 
    51   void 
     57  virtual void 
    5258  ExportSceneNode(SceneGraphNode *node); 
    5359   
  • trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp

    r170 r176  
    2727#include "Mesh.h" 
    2828#include "SceneGraph.h" 
    29  
    30  
    3129 
    3230// --------------------------------------------------------------------------- 
     
    6260// --------------------------------------------------------------------------- 
    6361X3dParseHandlers::X3dParseHandlers(SceneGraphNode *root) : 
    64   fElementCount(0) 
    65   , fAttrCount(0) 
    66   , fCharacterCount(0) 
    67   , fSpaceCount(0) 
    68 { 
    69   currentNode = root; 
     62  mElementCount(0) 
     63  , mAttrCount(0) 
     64  , mCharacterCount(0) 
     65  , mSpaceCount(0) 
     66{ 
     67  mCurrentNode = root; 
    7068} 
    7169 
     
    8179{ 
    8280  StrX lname(name); 
    83   string element(lname.localForm()); 
     81  string element(lname.LocalForm()); 
    8482  if (element == "Shape") 
    8583    EndShape(); 
     
    8987X3dParseHandlers::EndShape() 
    9088{ 
    91   currentMesh->Preprocess(); 
    92   // make an instance of this mesh 
    93   MeshInstance *mi = new MeshInstance(currentMesh); 
    94   currentNode->mGeometry.push_back(mi);  
    95   currentMesh = NULL; 
     89  if (mCurrentMesh->mFaces.size()) { 
     90    mCurrentMesh->Preprocess(); 
     91    // make an instance of this mesh 
     92    MeshInstance *mi = new MeshInstance(mCurrentMesh); 
     93    mCurrentNode->mGeometry.push_back(mi); 
     94  } else { 
     95    cout<<"X"; 
     96    delete mCurrentMesh; 
     97  } 
     98  mCurrentMesh = NULL; 
    9699} 
    97100 
     
    105108   
    106109  for (i=0; i < len; i++) { 
    107     string attrName(StrX(attributes.getName(i)).localForm()); 
     110    string attrName(StrX(attributes.getName(i)).LocalForm()); 
    108111    if (attrName == "coordIndex") { 
    109112      StrX attrValue(attributes.getValue(i)); 
    110113      // handle coordIndex 
    111114      vertices.clear(); 
    112       const char *ptr = attrValue.localForm(); 
     115      const char *ptr = attrValue.LocalForm(); 
    113116      char *endptr; 
    114117      while(1) { 
     
    117120          if (vertices.size() > 2) { 
    118121            Face *face = new Face(vertices); 
    119             currentMesh->mFaces.push_back(face); 
     122            mCurrentMesh->mFaces.push_back(face); 
    120123          } 
    121124          vertices.clear(); 
     
    137140  int len = attributes.getLength(); 
    138141  int i; 
    139   if (!currentMesh->mMaterial) 
    140     currentMesh->mMaterial = new Material; 
     142  if (!mCurrentMesh->mMaterial) 
     143    mCurrentMesh->mMaterial = new Material; 
    141144  for (i=0; i < len; i++) { 
    142     string attrName(StrX(attributes.getName(i)).localForm()); 
     145    string attrName(StrX(attributes.getName(i)).LocalForm()); 
    143146    StrX attrValue(attributes.getValue(i)); 
    144     const char *ptr = attrValue.localForm(); 
     147    const char *ptr = attrValue.LocalForm(); 
    145148    if (attrName == "diffuseColor") { 
    146149      float r, g, b; 
    147150      if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3) 
    148         currentMesh->mMaterial->mDiffuseColor = RgbColor(r, g, b); 
     151        mCurrentMesh->mMaterial->mDiffuseColor = RgbColor(r, g, b); 
    149152    } 
    150153  } 
     
    159162  VertexContainer vertices; 
    160163  for (i=0; i < len; i++) { 
    161     string attrName(StrX(attributes.getName(i)).localForm()); 
     164    string attrName(StrX(attributes.getName(i)).LocalForm()); 
    162165    if (attrName == "point") { 
    163166      StrX attrValue(attributes.getValue(i)); 
    164       const char *ptr = attrValue.localForm(); 
     167      const char *ptr = attrValue.LocalForm(); 
    165168      char *endptr; 
    166169      while(1) { 
     
    182185        vertices.push_back(v); 
    183186      } 
    184       currentMesh->mVertices = vertices; 
     187      mCurrentMesh->mVertices = vertices; 
    185188    } 
    186189  } 
     
    193196{ 
    194197  StrX lname(name); 
    195   string element(lname.localForm()); 
     198  string element(lname.LocalForm()); 
    196199   
    197200  if (element == "IndexedFaceSet") { 
     
    202205  if (element == "Shape") { 
    203206    cout<<"+"; 
    204     currentMesh = new Mesh; 
     207    mCurrentMesh = new Mesh; 
    205208  } 
    206209   
    207210  if (element == "Coordinate") { 
    208     if (currentMesh) 
     211    if (mCurrentMesh) 
    209212      StartCoordinate(attributes); 
    210213  } 
     
    214217  } 
    215218 
    216   fElementCount++; 
    217   fAttrCount += attributes.getLength(); 
     219  mElementCount++; 
     220  mAttrCount += attributes.getLength(); 
    218221} 
    219222 
     
    222225                             const unsigned int length) 
    223226{ 
    224   fCharacterCount += length; 
     227  mCharacterCount += length; 
    225228} 
    226229 
     
    229232                                      const unsigned int length) 
    230233{ 
    231   fSpaceCount += length; 
     234  mSpaceCount += length; 
    232235} 
    233236 
     
    235238X3dParseHandlers::resetDocument() 
    236239{ 
    237   fAttrCount = 0; 
    238   fCharacterCount = 0; 
    239   fElementCount = 0; 
    240   fSpaceCount = 0; 
     240  mAttrCount = 0; 
     241  mCharacterCount = 0; 
     242  mElementCount = 0; 
     243  mSpaceCount = 0; 
    241244} 
    242245 
     
    345348        return false; 
    346349      } 
     350 
    347351     
    348352    // Print out the stats that we collected and time taken 
    349353    if (!errorCount) { 
    350354      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms (" 
    351                                 << handler.getElementCount() << " elems, " 
    352                                 << handler.getAttrCount() << " attrs, " 
    353                                 << handler.getSpaceCount() << " spaces, " 
    354                                 << handler.getCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl; 
     355                                << handler.GetElementCount() << " elems, " 
     356                                << handler.GetAttrCount() << " attrs, " 
     357                                << handler.GetSpaceCount() << " spaces, " 
     358                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl; 
    355359    } 
    356360  } 
  • trunk/VUT/GtpVisibilityPreprocessor/src/default.env

    r170 r176  
    66Scene { 
    77 
     8#       filename glasgow1.x3d 
     9#       filename vienna.x3d 
    810#       filename atlanta2.x3d 
    911        filename soda.dat 
     
    1921 
    2022Unigraphics { 
    21                 meshGrouping 1000 
     23                meshGrouping 1 
    2224} 
    2325 
     
    4850        splitBorder 0.01 
    4951} 
     52 
     53 
     54SamplingPreprocessor { 
     55 
     56 
     57} 
  • trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp

    r170 r176  
    3131 
    3232  //  p->mSceneGraph->Export("soda.x3d"); 
    33   if (1) { 
     33  if (0) { 
    3434    p->Export(filename + "-out.x3d", true, false); 
    3535    p->Export(filename + "-kdtree.x3d", false, true); 
     
    3737   
    3838  //  p->LoadViewcells("viewcells.wrl"); 
    39   p->ComputeVisibility(); 
    40   p->ExportPreprocessedData("scene.vis"); 
     39  if (1) { 
     40    p->ComputeVisibility(); 
     41    p->ExportPreprocessedData("scene.vis"); 
     42  } 
    4143   
    42   if (1) { 
     44  if (0) { 
    4345    Camera camera; 
    4446    camera.LookAtBox(p->mKdTree->GetBox()); 
  • trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro

    r170 r176  
    3131UnigraphicsParser.cpp X3dExporter.cpp SceneGraph.cpp Material.cpp \ 
    3232Matrix4x4.cpp Vector3.cpp AxisAlignedBox3.cpp Ray.cpp main.cpp Mesh.cpp \ 
    33 Exporter.cpp Camera.cpp X3dParser.cpp MeshKdTree.cpp 
     33Exporter.cpp Camera.cpp X3dParser.cpp MeshKdTree.cpp Pvs.cpp 
    3434 
    3535 
Note: See TracChangeset for help on using the changeset viewer.