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