00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llpatchvertexarray.h"
00035 #include "llsurfacepatch.h"
00036 
00037 
00038 
00039 LLPatchVertexArray::LLPatchVertexArray() :
00040         mSurfaceWidth(0),
00041         mPatchWidth(0),
00042         mPatchOrder(0),
00043         mRenderLevelp(NULL),
00044         mRenderStridep(NULL)
00045 {
00046 }
00047 
00048 LLPatchVertexArray::LLPatchVertexArray(U32 surface_width, U32 patch_width, F32 meters_per_grid) :
00049         mRenderLevelp(NULL),
00050         mRenderStridep(NULL)
00051 {
00052         create(surface_width, patch_width, meters_per_grid);
00053 }
00054 
00055 
00056 LLPatchVertexArray::~LLPatchVertexArray() 
00057 {
00058         destroy();
00059 }
00060 
00061 
00062 void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_per_grid) 
00063 {
00064         
00065         
00066         if (patch_width > surface_width) 
00067         {
00068                 U32 temp = patch_width;
00069                 patch_width = surface_width;
00070                 surface_width = temp;
00071         }
00072 
00073         
00074         
00075         
00076         U32 power_of_two = 1;
00077         U32 surface_order = 0;
00078         while (power_of_two < (surface_width-1))
00079         {
00080                 power_of_two *= 2;
00081                 surface_order += 1;
00082         }
00083 
00084         if (power_of_two == (surface_width-1))
00085         {
00086                 mSurfaceWidth = surface_width;
00087 
00088                 
00089                 U32 ratio = (surface_width - 1) / patch_width;
00090                 F32 fratio = ((float)(surface_width - 1)) / ((float)(patch_width));
00091                 if ( fratio == (float)(ratio))
00092                 {
00093                         
00094                         power_of_two = 1;
00095                         U32 patch_order = 0;
00096                         while (power_of_two < patch_width)
00097                         {
00098                                 power_of_two *= 2;
00099                                 patch_order += 1;
00100                         }
00101                         if (power_of_two == patch_width)
00102                         {
00103                                 mPatchWidth = patch_width;
00104                                 mPatchOrder = patch_order;
00105                         }
00106                         else 
00107                         {
00108                                 mPatchWidth = 0;
00109                                 mPatchOrder = 0;
00110                         }
00111                 }
00112                 else 
00113                 {
00114                         mPatchWidth = 0;
00115                         mPatchOrder = 0;
00116                 }
00117         }
00118         else 
00119         {
00120                 mSurfaceWidth = 0;
00121                 mPatchWidth = 0;
00122                 mPatchOrder = 0;
00123         }
00124 
00125         
00126         if (mPatchWidth > 0) 
00127         {
00128                 mRenderLevelp = new U32 [2*mPatchWidth + 1];
00129                 mRenderStridep = new U32 [mPatchOrder + 1];
00130         }
00131 
00132         if (NULL == mRenderLevelp || NULL == mRenderStridep)
00133         {
00134                 
00135                 
00136                 llerrs << "mRenderLevelp or mRenderStridep was NULL; we'd crash soon." << llendl;
00137                 return;
00138         }
00139 
00140         
00141         
00142         init();
00143 }
00144 
00145 
00146 void LLPatchVertexArray::destroy()
00147 {
00148         if (mPatchWidth == 0)
00149         {
00150                 return;
00151         }
00152 
00153         delete [] mRenderLevelp;
00154         delete [] mRenderStridep;
00155         mSurfaceWidth = 0;
00156         mPatchWidth = 0;
00157         mPatchOrder = 0;
00158 }
00159 
00160 
00161 void LLPatchVertexArray::init() 
00162 
00163 {
00164         U32 j;
00165         U32 level, stride;
00166         U32 k;
00167 
00168         
00169 
00170         
00171         
00172         
00173         
00174         
00175         
00176         
00177         
00178         stride = mPatchWidth;
00179         for (level=0; level<mPatchOrder + 1; level++)
00180         {
00181                 mRenderStridep[level] = stride;
00182                 stride /= 2;
00183         }
00184 
00185         
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221         
00222         level = mPatchOrder;
00223         k = 2;
00224         mRenderLevelp[0] = mPatchOrder;
00225         mRenderLevelp[1] = mPatchOrder;
00226         stride = 2;
00227         while(stride < 2*mPatchWidth)
00228         {
00229                 for (j=0; j<k  &&  stride<2*mPatchWidth; j++)
00230                 {
00231                         mRenderLevelp[stride++] = level;
00232                 }
00233                 k *= 2;
00234                 level--;        
00235         }
00236         mRenderLevelp[2*mPatchWidth] = 0;
00237 }
00238 
00239 
00240 std::ostream& operator<<(std::ostream &s, const LLPatchVertexArray &va)
00241 {
00242         U32 i;
00243         s << "{ \n";
00244         s << "  mSurfaceWidth = " << va.mSurfaceWidth << "\n";
00245         s << "  mPatchWidth = " << va.mPatchWidth << "\n";
00246         s << "  mPatchOrder = " << va.mPatchOrder << "\n";
00247         s << "  mRenderStridep = \n";
00248         for (i=0; i<va.mPatchOrder+1; i++)
00249         {
00250                 s << "    " << i << "    " << va.mRenderStridep[i] << "\n";
00251         }
00252         s << "  mRenderLevelp = \n";
00253         for (i=0; i < 2*va.mPatchWidth + 1; i++)
00254         {
00255                 s << "    " << i << "    " << va.mRenderLevelp[i] << "\n";
00256         }
00257         s << "}";       
00258         return s;
00259 }
00260 
00261 
00262