- Main Page
- Namespaces
- Classes
- Files

# VCRA-SZCZERBACKI-PointBasedRendering/splatting.cpp

    00001
    00018 #include "splatting.h"
    00019
    00020 #include "analytic.inl"
    00021
    00022 extern Mesh    *lwo;
    00023 extern Color   *buffer;
    00024 extern ABuffer *abuffer;
    00025
    00026 extern std::vector<Splat>       splats;
    00027
    00028 void loadLwoFile(char *filename)
    00029 {
    00030   glutSetCursor(GLUT_CURSOR_WAIT);
    00031
    00032   lwo = new Mesh( filename );
    00033         lwo->setParametrization();
    00034         lwo->subdivide( subdivision );
    00035         splats.resize(lwo->getVertexCount());
    00036         for(int i=0;i<splats.size();++i)
    00037         {
    00038                 float maxl = 0.0f,l;
    00039                 int valence, left, right;
    00040                 bool boundary;
    00041                 const std::vector<Mesh::ventry> &vertexlist = lwo->get1Neighbourhood( i, valence, boundary, left, right );
    00042                 for(int j=0;j<vertexlist.size();++j)
    00043                 {
    00044                         l = (lwo->getVertex(vertexlist[j].m_vertex).m_position - lwo->getVertex(i).m_position).length();
    00045                         maxl = max2(l,maxl);
    00046                 }
    00047
    00048                 splats[i].m_position = lwo->getVertex(i).m_position;
    00049                 splats[i].m_normal = lwo->getVertex(i).m_normal;
    00050                 splats[i].m_size = maxl;
    00051     splats[i].m_color.set(1.0f,0.85f,0.65f, 1.0f);
    00052         }
    00053
    00054   glutSetCursor(GLUT_CURSOR_INHERIT);
    00055 }
    00056
    00057 void poissonDiscDistribution( Vector2 *points, int count )
    00058 {
    00059         SS_ASSERT(count > 0);
    00060
    00061         float threshold = 1.0f;
    00062
    00063         //repeat until we have all subpixels distributed
    00064         int j=0;
    00065         while(j < count)
    00066         {
    00067                 //try to place a random sample in a unit circle so that it is not closer
    00068                 // to earlier samples than the threshold
    00069                 int tries = 100;
    00070                 int k;
    00071                 Vector2 p;
    00072                 do
    00073                 {
    00074                         //make a random sample inside unit circle
    00075                         p = randInCircle();
    00076
    00077                         //test whether the sample is closer to points already placed than the threshold
    00078                         for(k=0;k<j;k++)
    00079                         {
    00080                                 if( (p - points[k]).length() < threshold )
    00081                                 {       //too close, break
    00082                                         tries--;
    00083                                         break;
    00084                                 }
    00085                         }
    00086                 } while(k < j && tries > 0);
    00087
    00088                 if( tries == 0 )
    00089                 {
    00090                         //if did not succeed, lower the threshold and redistribute all points
    00091                         threshold *= 0.98f;     //the closer the number is to 1, the slower the convergence
    00092                         j = 0;
    00093                 }
    00094                 else
    00095                 {
    00096                         //if succeeded, add the sample
    00097                         points[j] = p;
    00098                         j++;
    00099                 }
    00100         }
    00101 }
    00102
    00103 float cumulativeGaussian[gausssamples];
    00104
    00105 void initCumulativeGaussian()
    00106 {
    00107         //init cumulative gaussian
    00108         float x = 0.0f;
    00109         float xstep = prefiltercutoff / (float)gausssamples;
    00110         x += xstep/2.0f;        //calculate x at the center of each slice
    00111         cumulativeGaussian[0] = exp(-0.5f*x*x)*xstep;
    00112         for(int i=1;i<gausssamples;i++)
    00113         {
    00114                 x += xstep;
    00115                 cumulativeGaussian[i] = cumulativeGaussian[i-1] + exp(-0.5f*x*x)*xstep;
    00116         }
    00117         //normalize
    00118         for(int i=0;i<gausssamples;i++)
    00119         {
    00120                 cumulativeGaussian[i] /= cumulativeGaussian[gausssamples-1];
    00121         }
    00122 }
    00123
    00124 float inverseCumulativeGaussian( float r )
    00125 {
    00126         int i;
    00127         for(i=0;i<gausssamples-1;i++)
    00128         {
    00129                 if( r > cumulativeGaussian[i] && r < cumulativeGaussian[i+1] )
    00130                         break;
    00131         }
    00132         return (float)i/(float)gausssamples;
    00133 }
    00134
    00135 void makeJitter(int subpixels)
    00136 {
    00137         SS_ASSERT(subpixels > 0);
    00138
    00139         if( prefilterJitter ) delete[] prefilterJitter;
    00140         if( lensJitter) delete[] lensJitter;
    00141
    00142         prefilterJitter = new Vector2[subpixels*jitterPatterns];
    00143         lensJitter = new Vector2[subpixels*jitterPatterns];
    00144
    00145         svPrint("poisson disk distribution with %d points.",subpixels);
    00146         Timer t;
    00147         t.sample();
    00148         initCumulativeGaussian();
    00149         for(int p=0;p<jitterPatterns;p++)
    00150         {
    00151                 poissonDiscDistribution(&prefilterJitter[p*subpixels],subpixels);
    00152                 for(int j=0;j<subpixels;j++)
    00153                 {
    00154                         Vector2 jit = prefilterJitter[p*subpixels+j];
    00155                         float r = jit.length();
    00156                         if( r > 0.0f ) jit *= 1.0f/r;
    00157                         jit *= inverseCumulativeGaussian(r) * prefiltersize;
    00158                         prefilterJitter[p*subpixels+j] = jit;
    00159                 }
    00160
    00161                 poissonDiscDistribution(&lensJitter[p*subpixels],subpixels);
    00162                 for(int j=0;j<subpixels;j++)
    00163                 {
    00164                         lensJitter[p*subpixels+j] *= lensRadius;
    00165                 }
    00166         }
    00167         t.sample();
    00168         svPrint(" took %f seconds\n",t.getDelta());
    00169 }