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

worked on gvs sampling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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; 
Note: See TracChangeset for help on using the changeset viewer.