Changeset 1500


Ignore:
Timestamp:
09/26/06 18:14:30 (18 years ago)
Author:
mattausch
Message:

worked on gvs sampling

Location:
GTP/trunk/Lib/Vis/Preprocessing/src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp

    r1489 r1500  
    12751275                 "0.00001"); 
    12761276 
     1277    RegisterOption("GvsPreprocessor.threshold", 
     1278                 optFloat, 
     1279                 "gvs_threshold", 
     1280                 "1.5"); 
     1281 
    12771282 
    12781283  /***********************************************************************************/ 
  • GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp

    r1492 r1500  
    66#include "Triangle3.h" 
    77#include "IntersectableWrapper.h" 
     8#include "Plane3.h" 
     9 
    810 
    911 
     
    1820        Environment::GetSingleton()->GetIntValue("GvsPreprocessor.samplesPerPass", mSamplesPerPass); 
    1921        Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.epsilon", mEps); 
    20                  
     22        Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.threshold", mThreshold);     
    2123 
    2224        Debug << "Gvs preprocessor options" << endl; 
     
    2931 
    3032 
    31 const bool GvsPreprocessor::DiscontinuityFound(const VssRay &ray,  
    32                                                                                            const VssRay &oldRay) const 
    33 { 
    34         //|predicted(x)-xp|-|hit(x)-xp| > ?, 
    35     //const Plane3 plane = tri->GetPlane(); 
     33bool GvsPreprocessor::CheckDiscontinuity(const VssRay &currentRay, 
     34                                                                                 const Triangle3 &hitTriangle, 
     35                                                                                 const VssRay &oldRay) 
     36{ 
     37        const float dist = Magnitude(oldRay.GetDir()); 
     38        const float newDist = Magnitude(currentRay.GetDir()); 
     39  
     40#if 0 
     41        if ((dist - newDist) > mThresHold) 
     42#else // rather take relative distance 
     43        if ((dist / newDist) > mThreshold) 
     44#endif 
     45        { 
     46                VssRay *newRay = ReverseSampling(currentRay, hitTriangle, oldRay); 
     47                HandleRay(*newRay); 
     48                return true; 
     49        } 
     50 
    3651        return false; 
    3752} 
    3853 
    3954 
    40 int GvsPreprocessor::HandleRay(const GvsRayInfo &gvsRay) 
    41 { 
    42         VssRay *ray = gvsRay.mRay; 
    43  
    44         if (!mViewCellsManager->ComputeSampleContribution(*ray, true, false)) 
    45                 return 1; 
    46  
    47         if (gvsRay.mFoundDiscontinuity) 
    48         { 
    49                 return ReverseSampling(*ray); 
    50         } 
    51         else 
    52         { 
    53                 return AdaptiveBorderSampling(*ray); 
    54         } 
    55 } 
    56  
    57 /** Hepler function for adaptive border sampling. It finds  
    58         new sample points around a triangle in a eps environment 
     55bool GvsPreprocessor::HandleRay(VssRay &vssRay) 
     56{ 
     57        if (!mViewCellsManager->ComputeSampleContribution(vssRay, true, false)) 
     58        { 
     59                mRayQueue.push(&vssRay); 
     60                return true; 
     61        } 
     62 
     63        return false; 
     64} 
     65 
     66 
     67/** Creates 3 new vertices for triangle vertex with specified index. 
    5968*/ 
    60 static void CreateNewRays(SimpleRayContainer &simpleRays,  
    61                                                   const Triangle3 &hitTriangle, 
    62                                                   const VssRay &ray,  
    63                                                   const int index, 
    64                                                   const float eps) 
     69static void CreateNewVertices(VertexContainer &vertices, 
     70                                                          const Triangle3 &hitTriangle, 
     71                                                          const VssRay &ray,  
     72                                                          const int index, 
     73                                                          const float eps) 
    6574{ 
    6675        const int indexU = (index + 1) % 3; 
     
    7584        const Vector3 dir1 = CrossProd(a, b); //N((pi-xp)×(pi+1- pi)); 
    7685        const Vector3 dir2 = CrossProd(a, c); // N((pi-xp)×(pi- pi-1)) 
    77         const Vector3 dir3 = DotProd(dir1, dir2) > 0 ?  
    78                 Normalize(dir2 + dir1) : Normalize(CrossProd(a, dir2) + CrossProd(dir1, a)); // N((pi-xp)×di,i-1+di,i+1×(pi-xp)) 
     86        const Vector3 dir3 = DotProd(dir1, dir2) > 0 ? // N((pi-xp)×di,i-1+di,i+1×(pi-xp)) 
     87                Normalize(dir2 + dir1) : Normalize(CrossProd(a, dir2) + CrossProd(dir1, a));  
    7988 
    8089        // compute the new three hit points 
    81         // pi, i + 1 
    82         const Vector3 pt1 = hitTriangle.mVertices[index] + eps * len * dir1; //pi+ e·|pi-xp|·di, j 
    83         // pi, i - 1 
    84     const Vector3 pt2 = hitTriangle.mVertices[index] + eps * len * dir2; //pi+ e·|pi-xp|·di, j 
    85         // pi, i 
    86         const Vector3 pt3 = hitTriangle.mVertices[index] + eps * len * dir3; //pi+ e·|pi-xp|·di, j 
    87          
    88         /// create simple rays and store them in container 
    89         Vector3 rayDir; 
    90         rayDir = Normalize(pt1 - ray.GetOrigin()); 
    91         simpleRays.push_back(SimpleRay(rayDir, ray.GetOrigin())); 
    92         rayDir = Normalize(pt2 - ray.GetOrigin()); 
    93         simpleRays.push_back(SimpleRay(rayDir, ray.GetOrigin())); 
    94         rayDir = Normalize(pt3 - ray.GetOrigin()); 
    95         simpleRays.push_back(SimpleRay(rayDir, ray.GetOrigin())); 
    96 } 
    97  
    98  
    99  
    100 int GvsPreprocessor::AdaptiveBorderSampling(const VssRay &prevRay) 
     90        // pi, i + 1:  pi+ e·|pi-xp|·di, j 
     91        const Vector3 pt1 = hitTriangle.mVertices[index] + eps * len * dir1; 
     92        // pi, i - 1:  pi+ e·|pi-xp|·di, j 
     93    const Vector3 pt2 = hitTriangle.mVertices[index] + eps * len * dir2; 
     94        // pi, i:  pi+ e·|pi-xp|·di, j 
     95        const Vector3 pt3 = hitTriangle.mVertices[index] + eps * len * dir3; 
     96         
     97        vertices.push_back(pt1); 
     98        vertices.push_back(pt2); 
     99        vertices.push_back(pt3); 
     100} 
     101 
     102 
     103void GvsPreprocessor::EnlargeTriangle(VertexContainer &vertices, 
     104                                                                          const Triangle3 &hitTriangle, 
     105                                                                          const VssRay &ray) 
     106{ 
     107        CreateNewVertices(vertices, hitTriangle, ray, 0, mEps); 
     108        CreateNewVertices(vertices, hitTriangle, ray, 1, mEps); 
     109        CreateNewVertices(vertices, hitTriangle, ray, 2, mEps); 
     110} 
     111 
     112 
     113static Vector3 CalcPredictedHitPoint(const VssRay &newRay,  
     114                                                                         const Triangle3 &hitTriangle, 
     115                                                                         const VssRay &oldRay) 
     116{ 
     117        Plane3 plane(hitTriangle.GetNormal(), hitTriangle.mVertices[0]); 
     118 
     119        const Vector3 hitPt =  
     120                plane.FindIntersection(newRay.mTermination, newRay.mOrigin); 
     121         
     122        return hitPt; 
     123} 
     124 
     125 
     126static bool EqualVisibility(const VssRay &a, const VssRay &b) 
     127{ 
     128        return a.mTerminationObject == b.mTerminationObject; 
     129} 
     130 
     131 
     132int GvsPreprocessor::SubdivideEdge(const Triangle3 &hitTriangle, 
     133                                                                   const Vector3 &p1,  
     134                                                                   const Vector3 &p2,  
     135                                                                   const VssRay &x,  
     136                                                                   const VssRay &y, 
     137                                                                   const VssRay &oldRay) 
     138{ 
     139        // the predicted hitpoint expects to hit the same mesh again 
     140        const Vector3 predictedHitX = CalcPredictedHitPoint(x, hitTriangle, oldRay); 
     141        const Vector3 predictedHitY = CalcPredictedHitPoint(y, hitTriangle, oldRay); 
     142 
     143        CheckDiscontinuity(x, hitTriangle, oldRay); 
     144        CheckDiscontinuity(y, hitTriangle, oldRay); 
     145 
     146        if (EqualVisibility(x, y)) 
     147        { 
     148                return 2; 
     149        } 
     150        else 
     151        { 
     152                const Vector3 p = (p1 + p2) * 0.5f; 
     153                SimpleRay sray(oldRay.mOrigin, p - oldRay.mOrigin); 
     154                VssRay *newRay = NULL; 
     155                //VssRay *newRay = CastSingleRay(sray); 
     156                HandleRay(*newRay); 
     157 
     158                const int s1 = SubdivideEdge(hitTriangle, p1, p, x, *newRay, oldRay); 
     159                const int s2 = SubdivideEdge(hitTriangle, p, p2, *newRay, y, oldRay); 
     160                                                                   
     161        return s1 + s2; 
     162        } 
     163} 
     164 
     165 
     166int GvsPreprocessor::AdaptiveBorderSampling(const VssRay &currentRay) 
    101167{ 
    102168        cout << "a"; 
    103         Intersectable *tObj = prevRay.mTerminationObject; 
     169        Intersectable *tObj = currentRay.mTerminationObject; 
    104170        Triangle3 hitTriangle; 
    105171 
     
    110176        } 
    111177 
     178        VertexContainer enlargedTriangle; 
     179         
     180        /// create 3 new hit points for each vertex 
     181        EnlargeTriangle(enlargedTriangle, hitTriangle, currentRay); 
     182         
     183        /// create rays from sample points and handle them 
    112184        SimpleRayContainer simpleRays; 
    113185        simpleRays.reserve(9); 
    114186 
    115         CreateNewRays(simpleRays, hitTriangle, prevRay, 0, mEps); 
    116         CreateNewRays(simpleRays, hitTriangle, prevRay, 1, mEps); 
    117         CreateNewRays(simpleRays, hitTriangle, prevRay, 2, mEps); 
    118  
     187        VertexContainer::const_iterator vit, vit_end = enlargedTriangle.end(); 
     188 
     189        for (vit = enlargedTriangle.begin(); vit != vit_end; ++ vit) 
     190        { 
     191                const Vector3 rayDir = (*vit) - currentRay.GetOrigin(); 
     192                simpleRays.push_back(SimpleRay(*vit, rayDir)); 
     193        } 
     194 
     195        // establish visibility 
    119196        VssRayContainer vssRays; 
    120          
    121197        CastRays(simpleRays, vssRays); 
    122198        // add to ray queue 
    123199        EnqueueRays(vssRays); 
    124200 
     201    // recursivly subdivide each edge 
     202        for (int i = 0; i < 9; ++ i) 
     203        { 
     204                SubdivideEdge( 
     205                        hitTriangle, 
     206                        enlargedTriangle[i],  
     207                        enlargedTriangle[(i + 1) % 9],  
     208                        *vssRays[i],  
     209                        *vssRays[(i + 1) % 9], 
     210                        currentRay); 
     211        } 
     212 
    125213        return (int)vssRays.size(); 
    126214} 
    127215 
    128216 
    129 int GvsPreprocessor::ReverseSampling(const VssRay &oldRay) 
     217static Vector3 GetPassingPoint(const VssRay &currentRay, 
     218                                                                                 const Triangle3 &hitTriangle, 
     219                                                                                 const VssRay &oldRay) 
     220{ 
     221        // intersect triangle plane with plane spanned by current samples 
     222        Plane3 plane(currentRay.GetOrigin(), currentRay.GetTermination(), oldRay.GetTermination()); 
     223        Plane3 triPlane(hitTriangle.GetNormal(), hitTriangle.mVertices[0]); 
     224 
     225        SimpleRay intersectLine = GetPlaneIntersection(plane, triPlane); 
     226 
     227        // Evaluate new hitpoint just outside the triangle 
     228        const float factor = 0.95f; 
     229        float t = triPlane.FindT(intersectLine); 
     230 
     231        const Vector3 newPoint = intersectLine.mOrigin + t * factor * intersectLine.mDirection; 
     232 
     233        return newPoint; 
     234} 
     235 
     236 
     237VssRay *GvsPreprocessor::ReverseSampling(const VssRay &currentRay, 
     238                                                                                 const Triangle3 &hitTriangle, 
     239                                                                                 const VssRay &oldRay) 
    130240{ 
    131241        cout << "r" << endl; 
    132         // TODO 
    133         return 1; 
     242         
     243         
     244        //-- The plane p = (xp, hit(x), hit(xold)) is intersected 
     245        //-- with the newly found triangle (xold is the previous ray from 
     246        //-- which x was generated). On the intersecting line, we select a point 
     247        //-- pnew which lies just outside of the new triangle so the ray 
     248        //-- just passes by inside the gap 
     249    const Vector3 newPoint = GetPassingPoint(currentRay, hitTriangle, oldRay); 
     250        const Vector3 predicted = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay); 
     251 
     252        //-- Construct the mutated ray with xnew,dir = predicted(x)- pnew  
     253        //-- as direction vector 
     254        const Vector3 newDir = predicted - newPoint ; 
     255        // take xnew,p = intersect(viewcell, line(pnew, predicted(x)) as origin ? 
     256        // difficult to say!! 
     257        const Vector3 newOrigin = newDir * -5000.0f; 
     258 
     259        return new VssRay(currentRay); 
    134260} 
    135261 
     
    157283 
    158284 
    159 void GvsPreprocessor::EnqueueRays(VssRayContainer &samples, VssRay *oldRay) 
     285void GvsPreprocessor::EnqueueRays(VssRayContainer &samples) 
    160286{ 
    161287        // add samples to ray queue 
    162288        VssRayContainer::const_iterator vit, vit_end = samples.end(); 
     289         
    163290        for (vit = samples.begin(); vit != vit_end; ++ vit) 
    164291        { 
    165                 /// if there is no old ray, no discontinuity 
    166                 const bool gap = oldRay ? DiscontinuityFound(*(*vit), *oldRay) : false; 
    167                 mRayQueue.push(GvsRayInfo(*vit, gap)); 
     292                HandleRay(*(*vit)); 
    168293        } 
    169294} 
     
    196321        { 
    197322                // handle next ray 
    198                 GvsRayInfo rayInfo = mRayQueue.top(); 
     323                VssRay *ray = mRayQueue.top(); 
    199324                mRayQueue.pop(); 
    200325                 
    201                 castSamples += HandleRay(rayInfo); 
     326                castSamples += HandleRay(*ray); 
    202327        } 
    203328 
     
    227352                castSamples += passSamples; 
    228353                 
    229                 ///////////// 
    230                 // -- stats 
     354                //////// 
     355                //-- stats 
    231356                cout << "+"; 
    232357                cout << "\nsamples cast " << passSamples << " (=" << castSamples << " of " << mTotalSamples << ")" << endl; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h

    r1492 r1500  
    2929 
    3030protected: 
    31  
    32         struct GvsRayInfo 
    33         { 
    34                 GvsRayInfo(VssRay *ray, const bool d) 
    35                         : mRay(ray), mFoundDiscontinuity(d)  
    36                 {} 
    37  
    38                 VssRay *mRay; 
    39                 bool mFoundDiscontinuity; 
    40         }; 
    41  
    42         typedef stack<GvsRayInfo> RayQueue; 
    43  
     31#if 0 
    4432        struct PendingRay 
    4533        { 
     
    5341 
    5442        typedef stack<PendingRay> PendingQueue; 
     43#endif 
     44        typedef stack<VssRay *> RayQueue; 
    5545 
    5646        /** Runs the adaptive sampling until the ray queue is empty.  
     
    8272                b) if triangle was found reverse sampling 
    8373        */ 
    84         int HandleRay(const GvsRayInfo &ray); 
     74        bool HandleRay(VssRay &ray); 
    8575 
    8676        /** The adaptive border sampling step. It aims to find neighbouring  
    87                 triangles of the one hit by the previous ray. 
     77                triangles of the one hit by the current ray. 
    8878        */       
    89         int AdaptiveBorderSampling(const VssRay &prevRay); 
     79        int AdaptiveBorderSampling(const VssRay &currentRay); 
    9080         
    9181        /** The reverse sampling step. It is started once the cast 
     
    9484                triangle passing through a gap. 
    9585        */ 
    96         int ReverseSampling(const VssRay &prevRay); 
     86        VssRay *ReverseSampling(const VssRay &currentRay, 
     87                                                        const Triangle3 &hitTriangle, 
     88                                                        const VssRay &oldRay); 
    9789 
    98         /** Returns true if we sampled a closer triangle than with the previous ray. 
     90        /** Returns true if we sampled a closer triangle than with the previous ray.  
     91                Does reverse sampling if gap found. 
    9992        */ 
    100         const bool DiscontinuityFound(const VssRay &ray, const VssRay &prevRay) const; 
     93        bool CheckDiscontinuity(const VssRay &currentRay,  
     94                                                        const Triangle3 &hitTriangle, 
     95                                                        const VssRay &oldRay); 
    10196 
    10297        /** Adds new samples to the ray queue and classifies them 
    10398                with respect to the previous ray. 
    10499        */ 
    105         void EnqueueRays(VssRayContainer &samples, VssRay *prevRay = NULL); 
    106          
     100        void EnqueueRays(VssRayContainer &samples); 
     101 
     102        /**  
     103                Hepler function for adaptive border sampling. It finds  
     104                new sample points around a triangle in a eps environment 
     105        */ 
     106        void EnlargeTriangle(VertexContainer &vertices, 
     107                                                 const Triangle3 &hitTriangle, 
     108                                                 const VssRay &ray); 
     109 
     110        int SubdivideEdge( 
     111                const Triangle3 &hitTriangle, 
     112                const Vector3 &p1,  
     113                const Vector3 &p2,  
     114                const VssRay &x,  
     115                const VssRay &y, 
     116                const VssRay &oldRay); 
     117 
    107118        ////////////////////// 
    108119 
     
    116127        AxisAlignedBox3 mViewSpaceBox; 
    117128        float mEps; 
     129        float mThreshold; 
    118130}; 
    119131 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.cpp

    r1076 r1500  
    11#include "Plane3.h" 
    22#include "Matrix4x4.h" 
     3#include "Ray.h" 
    34 
    45 
     
    5152 
    5253 
     54 bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2) 
     55 { 
     56         return  
     57                 p1.mNormal.x != p2.mNormal.x || 
     58                 p1.mNormal.y != p2.mNormal.y || 
     59                 p1.mNormal.z != p2.mNormal.z || 
     60                 p1.mD == p2.mD; 
     61 } 
     62 
     63 
     64/* 
     65If the planes are known to intersect then determine the origin and unit direction vector of a  
     66line formed by the intersection of two planes.  
     67The direction of that line is just the vector product of the normals of the planes.  
     68Finding a point along the intersection line is theoretically easy but numerical precision  
     69issues mean that we need to determine which axis it is best to do the calculation in. 
     70The point will lie on the axis that was used to determine the intersection. 
     71*/ 
     72SimpleRay GetPlaneIntersection(const Plane3 &plane1, const Plane3 &plane2) 
     73{ 
     74        Vector3 point, dir; 
     75        dir = CrossProd(plane1.mNormal, plane2.mNormal); 
     76     
     77        float abs; 
     78        const int index = dir.DrivingAxis(); 
     79    
     80        switch (index) 
     81        { 
     82        case 0: 
     83                point[0] = 0.0f; 
     84                point[1] = (plane1.mNormal[2] * plane2.mD - plane2.mNormal[2] * plane1.mD) / dir[0] ; 
     85                point[2] = (plane2.mNormal[1] * plane1.mD - plane1.mNormal[1] * plane2.mD) / dir[0] ; 
     86                break; 
     87        case 1: 
     88                point[0] = (plane2.mNormal[2] * plane1.mD - plane1.mNormal[2] * plane2.mD) / dir[1] ; 
     89                point[1] = 0.0f ; 
     90                point[2] = (plane1.mNormal[0] * plane2.mD - plane2.mNormal[0] * plane1.mD) / dir[1] ; 
     91                break; 
     92        case 2: 
     93                point[0] = (plane1.mNormal[1] * plane2.mD - plane2.mNormal[1] * plane1.mD) / dir[2] ; 
     94                point[1] = (plane2.mNormal[0] * plane1.mD - plane1.mNormal[0] * plane2.mD) / dir[2] ; 
     95                point[2] = 0.0f ; 
     96                break; 
     97        } 
     98 
     99        Normalize(dir); 
     100 
     101        return SimpleRay(point, dir); 
     102} 
     103 
     104 
    53105Vector3 Plane3::FindIntersection(const Vector3 &a,                                                  
    54106                                                                 const Vector3 &b, 
     
    62114        { 
    63115                if (coplanar)  
     116                { 
    64117                        (*coplanar) = true;      
     118                } 
    65119 
    66120                if (t)  
     121                { 
    67122                        (*t) = 0; 
     123                } 
    68124 
    69125                return a; 
     
    71127         
    72128        if (coplanar)  
     129        { 
    73130                (*coplanar) = false; 
     131        } 
    74132 
    75133    float u = - Distance(a) / dv; // TODO: could be done more efficiently 
    76134     
    77135        if (t)  
     136        { 
    78137                (*t) = u; 
    79          
     138        } 
     139 
    80140    return a + u * v; 
    81141} 
     
    94154     
    95155        // does not intersect or coincident 
    96  
    97156        if (signum(dv) == 0) 
    98157                return 0; 
     
    101160} 
    102161 
     162 
     163float Plane3::FindT(const SimpleRay &a) const  
     164{          
     165        const Vector3 v = a.mDirection; // line from A to B 
     166        const float dv = DotProd(v, mNormal); 
     167     
     168        // does not intersect or coincident 
     169        if (signum(dv) == 0) 
     170                return 0; 
     171         
     172        return - Distance(a.mOrigin) / dv; // TODO: could be done more efficiently 
    103173} 
     174 
     175} 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h

    r1418 r1500  
    66namespace GtpVisibilityPreprocessor { 
    77 
    8    
    9 /** 3D Plane */ 
     8struct SimpleRay; 
     9 
     10/** 3D Plane. 
     11*/ 
    1012class Plane3 { 
    1113public: 
     
    5860  float FindT(const Vector3 &a, const Vector3 &b) const; 
    5961 
     62  float FindT(const SimpleRay &a) const; 
     63 
    6064  friend bool 
    6165  PlaneIntersection(const Plane3 &a, const Plane3 &b, const Plane3 &c, Vector3 &result); 
    6266   
     67  friend bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2); 
     68 
     69  friend SimpleRay GetPlaneIntersection(const Plane3 &plane1, const Plane3 &plane2); 
     70 
    6371  friend ostream &operator<<(ostream &s, const Plane3 p) { 
    6472    s<<p.mNormal<<" "<<p.mD; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp

    r1328 r1500  
    633633          float sum = info.pvsBack*(info.position - minBox) + info.pvsFront*(maxBox - info.position); 
    634634          float newCost = ct_div_ci + sum/sizeBox; 
    635           float oldCost = pvsSize; 
     635          float oldCost = (float)pvsSize; 
    636636          info.costRatio = newCost/oldCost; 
    637637          break; 
Note: See TracChangeset for help on using the changeset viewer.