00001 #include <iostream.h>
00002 #include <math.h>
00003 #include "vuSimpleTypes.h"
00004 #include "SplatSlicer.h"
00005
00006 #ifdef WIN32
00007
00008 float erf (float x = 0.0, float y = 0.0)
00009
00010 {
00011 return 0.0;
00012 }
00013 #ifndef M_SQRT2
00014 #define M_SQRT2 1.4142135624
00015 #endif
00016 #endif
00017
00018 SplatSlicer::SplatSlicer()
00019 {
00020 m_Slices = NULL;
00021 }
00022
00023 SplatSlicer::~SplatSlicer()
00024 {
00025 removeSlices();
00026 }
00027
00028 bool SplatSlicer::createSlices(int nslices, int xsize, int ysize)
00029 {
00030 if(!removeSlices()) return false;
00031 if (!nslices || !xsize || !ysize) return false;
00032 m_Slices = new AlphaMask[nslices];
00033 if(!m_Slices) return false;
00034 int i;
00035 for(i=0;i<nslices;i++) {
00036 m_Slices[i].setSize(xsize, ysize);
00037 }
00038 m_NSlices = nslices;
00039 m_XSize = xsize;
00040 m_YSize = ysize;
00041 return true;
00042
00043
00044 }
00045
00046 bool SplatSlicer::removeSlices()
00047 {
00048 if(!m_Slices) return true;
00049 delete [] m_Slices;
00050 m_Slices = NULL;
00051 m_NSlices = 0;
00052 return true;
00053 }
00054
00055
00056
00057
00058
00059
00060
00061 bool SplatSlicer::buildSplat(float radius, int xsize, int ysize, int slices)
00062 {
00063 if(!createSlices(slices, xsize, ysize)) return false;
00064 m_Radius = radius;
00065 m_Diameter = 2*radius;
00066
00067 cout<<"building splats "<<xsize<<"x"<<ysize<<endl;
00068 dword index;
00069 dword i;
00070 dword j;
00071 double x;
00072 double y;
00073 double d;
00074
00075 index = 0;
00076 int s;
00077 for(s=0;s<(int)m_NSlices;s++) {
00078 fbtype *data = m_Slices[s].getData();
00079 for(j=0;j<m_YSize;++j)
00080 {
00081 for(i=0;i<m_XSize;++i)
00082 {
00083 x = 0.5 - (double)i/(double)(m_XSize-1);
00084 y = 0.5 - (double)j/(double)(m_YSize-1);
00085 d = sqrt(x*x+y*y);
00086
00087 #ifdef FB_FLOAT
00088 *(data++) = integrate(radius*d,
00089 radius*(float(s)-float(m_NSlices/2))/m_NSlices);
00090 #else
00091 *(data++) = (word)(integrate(radius*d,
00092 radius*(float(s)-float(m_NSlices/2))/m_NSlices)
00093 *P2_16);
00094 #endif
00095 }
00096 }
00097 }
00098 return true;
00099 }
00100
00101 float SplatSlicer::integrate(float r, float u)
00102 {
00103 return float((0.223 * erf(M_SQRT2 * u) + 0.223) * exp(-2*r*r));
00104
00105
00106 }
00107
00108 AlphaMask& SplatSlicer::getSpla(float t)
00109 {
00110 int slice = int((m_NSlices>>1) + ((t*m_NSlices)/(m_Diameter)));
00111 if(slice<0) slice = 0;
00112 else if(slice>=(int)m_NSlices) slice = m_NSlices-1;
00113 return m_Slices[slice];
00114 }
00115