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
00064 int j=0;
00065 while(j < count)
00066 {
00067
00068
00069 int tries = 100;
00070 int k;
00071 Vector2 p;
00072 do
00073 {
00074
00075 p = randInCircle();
00076
00077
00078 for(k=0;k<j;k++)
00079 {
00080 if( (p - points[k]).length() < threshold )
00081 {
00082 tries--;
00083 break;
00084 }
00085 }
00086 } while(k < j && tries > 0);
00087
00088 if( tries == 0 )
00089 {
00090
00091 threshold *= 0.98f;
00092 j = 0;
00093 }
00094 else
00095 {
00096
00097 points[j] = p;
00098 j++;
00099 }
00100 }
00101 }
00102
00103 float cumulativeGaussian[gausssamples];
00104
00105 void initCumulativeGaussian()
00106 {
00107
00108 float x = 0.0f;
00109 float xstep = prefiltercutoff / (float)gausssamples;
00110 x += xstep/2.0f;
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
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 }