00001
00032
00033
00034
00035
00036
00037
00038 #include "llviewerprecompiledheaders.h"
00039 #include "indra_constants.h"
00040
00041 #include "llwind.h"
00042
00043
00044 #include "llgl.h"
00045 #include "patch_dct.h"
00046 #include "patch_code.h"
00047
00048
00049 #include "noise.h"
00050 #include "v4color.h"
00051 #include "viewer.h"
00052 #include "llagent.h"
00053 #include "llworld.h"
00054
00055
00056 const F32 CLOUD_DIVERGENCE_COEF = 0.5f;
00057
00058
00060
00062
00063 LLWind::LLWind()
00064 : mSize(16),
00065 mCloudDensityp(NULL)
00066 {
00067 init();
00068 }
00069
00070
00071 LLWind::~LLWind()
00072 {
00073 delete [] mVelX;
00074 delete [] mVelY;
00075 delete [] mCloudVelX;
00076 delete [] mCloudVelY;
00077 }
00078
00079
00081
00083
00084
00085 void LLWind::init()
00086 {
00087
00088 mVelX = new F32[mSize*mSize];
00089 mVelY = new F32[mSize*mSize];
00090
00091 mCloudVelX = new F32[mSize*mSize];
00092 mCloudVelY = new F32[mSize*mSize];
00093
00094 S32 i;
00095 for (i = 0; i < mSize*mSize; i++)
00096 {
00097 mVelX[i] = 0.5f;
00098 mVelY[i] = 0.5f;
00099 mCloudVelX[i] = 0.0f;
00100 mCloudVelY[i] = 0.0f;
00101 }
00102 }
00103
00104
00105 void LLWind::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)
00106 {
00107 if (!mCloudDensityp)
00108 {
00109 return;
00110 }
00111
00112 LLPatchHeader patch_header;
00113 S32 buffer[16*16];
00114
00115 init_patch_decompressor(group_headerp->patch_size);
00116
00117
00118
00119 group_headerp->stride = group_headerp->patch_size;
00120 set_group_of_patch_header(group_headerp);
00121
00122
00123 decode_patch_header(bitpack, &patch_header);
00124 decode_patch(bitpack, buffer);
00125 decompress_patch(mVelX, buffer, &patch_header);
00126
00127
00128 decode_patch_header(bitpack, &patch_header);
00129 decode_patch(bitpack, buffer);
00130 decompress_patch(mVelY, buffer, &patch_header);
00131
00132
00133
00134 S32 i, j, k;
00135
00136
00137
00138
00139
00140
00141 for (j=1; j<mSize-1; j++)
00142 {
00143 for (i=1; i<mSize-1; i++)
00144 {
00145 k = i + j * mSize;
00146 *(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 1) - *(mCloudDensityp + k - 1));
00147 *(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + mSize) - *(mCloudDensityp + k - mSize));
00148 }
00149 }
00150
00151 i = mSize - 1;
00152 for (j=1; j<mSize-1; j++)
00153 {
00154 k = i + j * mSize;
00155 *(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k) - *(mCloudDensityp + k - 2));
00156 *(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + mSize) - *(mCloudDensityp + k - mSize));
00157 }
00158 i = 0;
00159 for (j=1; j<mSize-1; j++)
00160 {
00161 k = i + j * mSize;
00162 *(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 2) - *(mCloudDensityp + k));
00163 *(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + mSize) - *(mCloudDensityp + k + mSize));
00164 }
00165 j = mSize - 1;
00166 for (i=1; i<mSize-1; i++)
00167 {
00168 k = i + j * mSize;
00169 *(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 1) - *(mCloudDensityp + k - 1));
00170 *(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k) - *(mCloudDensityp + k - 2*mSize));
00171 }
00172 j = 0;
00173 for (i=1; i<mSize-1; i++)
00174 {
00175 k = i + j * mSize;
00176 *(mCloudVelX + k) = *(mVelX + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 1) - *(mCloudDensityp + k -1));
00177 *(mCloudVelY + k) = *(mVelY + k) + CLOUD_DIVERGENCE_COEF * (*(mCloudDensityp + k + 2*mSize) - *(mCloudDensityp + k));
00178 }
00179 }
00180
00181
00182 LLVector3 LLWind::getAverage()
00183 {
00184
00185 LLVector3 average(0.0f, 0.0f, 0.0f);
00186 S32 i, grid_count;
00187 grid_count = mSize * mSize;
00188 for (i = 0; i < grid_count; i++)
00189 {
00190 average.mV[VX] += mVelX[i];
00191 average.mV[VY] += mVelY[i];
00192 }
00193
00194 average *= 1.f/((F32)(grid_count)) * WIND_SCALE_HACK;
00195 return average;
00196 }
00197
00198
00199 LLVector3 LLWind::getVelocityNoisy(const LLVector3 &pos_region, const F32 dim)
00200 {
00201
00202 LLVector3 r_val(0,0,0);
00203 F32 norm = 1.0f;
00204 if (dim == 8)
00205 {
00206 norm = 1.875;
00207 }
00208 else if (dim == 4)
00209 {
00210 norm = 1.75;
00211 }
00212 else if (dim == 2)
00213 {
00214 norm = 1.5;
00215 }
00216
00217 F32 temp_dim = dim;
00218 while (temp_dim >= 1.0)
00219 {
00220 LLVector3 pos_region_scaled(pos_region * temp_dim);
00221 r_val += getVelocity(pos_region_scaled) * (1.0f/temp_dim);
00222 temp_dim /= 2.0;
00223 }
00224
00225 return r_val * (1.0f/norm) * WIND_SCALE_HACK;
00226 }
00227
00228
00229 LLVector3 LLWind::getVelocity(const LLVector3 &pos_region)
00230 {
00231 llassert(mSize == 16);
00232
00233
00234
00235 LLVector3 r_val;
00236 F32 dx,dy;
00237 S32 k;
00238
00239 LLVector3 pos_clamped_region(pos_region);
00240
00241 F32 region_width_meters = gWorldPointer->getRegionWidthInMeters();
00242
00243 if (pos_clamped_region.mV[VX] < 0.f)
00244 {
00245 pos_clamped_region.mV[VX] = 0.f;
00246 }
00247 else if (pos_clamped_region.mV[VX] >= region_width_meters)
00248 {
00249 pos_clamped_region.mV[VX] = (F32) fmod(pos_clamped_region.mV[VX], region_width_meters);
00250 }
00251
00252 if (pos_clamped_region.mV[VY] < 0.f)
00253 {
00254 pos_clamped_region.mV[VY] = 0.f;
00255 }
00256 else if (pos_clamped_region.mV[VY] >= region_width_meters)
00257 {
00258 pos_clamped_region.mV[VY] = (F32) fmod(pos_clamped_region.mV[VY], region_width_meters);
00259 }
00260
00261
00262 S32 i = llfloor(pos_clamped_region.mV[VX] * mSize / region_width_meters);
00263 S32 j = llfloor(pos_clamped_region.mV[VY] * mSize / region_width_meters);
00264 k = i + j*mSize;
00265 dx = ((pos_clamped_region.mV[VX] * mSize / region_width_meters) - (F32) i);
00266 dy = ((pos_clamped_region.mV[VY] * mSize / region_width_meters) - (F32) j);
00267
00268 if ((i < mSize-1) && (j < mSize-1))
00269 {
00270
00271 r_val.mV[VX] = mVelX[k]*(1.0f - dx)*(1.0f - dy) +
00272 mVelX[k + 1]*dx*(1.0f - dy) +
00273 mVelX[k + mSize]*dy*(1.0f - dx) +
00274 mVelX[k + mSize + 1]*dx*dy;
00275 r_val.mV[VY] = mVelY[k]*(1.0f - dx)*(1.0f - dy) +
00276 mVelY[k + 1]*dx*(1.0f - dy) +
00277 mVelY[k + mSize]*dy*(1.0f - dx) +
00278 mVelY[k + mSize + 1]*dx*dy;
00279 }
00280 else
00281 {
00282 r_val.mV[VX] = mVelX[k];
00283 r_val.mV[VY] = mVelY[k];
00284 }
00285
00286 r_val.mV[VZ] = 0.f;
00287 return r_val * WIND_SCALE_HACK;
00288 }
00289
00290
00291 LLVector3 LLWind::getCloudVelocity(const LLVector3 &pos_region)
00292 {
00293 llassert(mSize == 16);
00294
00295
00296
00297 LLVector3 r_val;
00298 F32 dx,dy;
00299 S32 k;
00300
00301 LLVector3 pos_clamped_region(pos_region);
00302
00303 F32 region_width_meters = gWorldPointer->getRegionWidthInMeters();
00304
00305 if (pos_clamped_region.mV[VX] < 0.f)
00306 {
00307 pos_clamped_region.mV[VX] = 0.f;
00308 }
00309 else if (pos_clamped_region.mV[VX] >= region_width_meters)
00310 {
00311 pos_clamped_region.mV[VX] = (F32) fmod(pos_clamped_region.mV[VX], region_width_meters);
00312 }
00313
00314 if (pos_clamped_region.mV[VY] < 0.f)
00315 {
00316 pos_clamped_region.mV[VY] = 0.f;
00317 }
00318 else if (pos_clamped_region.mV[VY] >= region_width_meters)
00319 {
00320 pos_clamped_region.mV[VY] = (F32) fmod(pos_clamped_region.mV[VY], region_width_meters);
00321 }
00322
00323
00324 S32 i = llfloor(pos_clamped_region.mV[VX] * mSize / region_width_meters);
00325 S32 j = llfloor(pos_clamped_region.mV[VY] * mSize / region_width_meters);
00326 k = i + j*mSize;
00327 dx = ((pos_clamped_region.mV[VX] * mSize / region_width_meters) - (F32) i);
00328 dy = ((pos_clamped_region.mV[VY] * mSize / region_width_meters) - (F32) j);
00329
00330 if ((i < mSize-1) && (j < mSize-1))
00331 {
00332
00333 r_val.mV[VX] = mCloudVelX[k]*(1.0f - dx)*(1.0f - dy) +
00334 mCloudVelX[k + 1]*dx*(1.0f - dy) +
00335 mCloudVelX[k + mSize]*dy*(1.0f - dx) +
00336 mCloudVelX[k + mSize + 1]*dx*dy;
00337 r_val.mV[VY] = mCloudVelY[k]*(1.0f - dx)*(1.0f - dy) +
00338 mCloudVelY[k + 1]*dx*(1.0f - dy) +
00339 mCloudVelY[k + mSize]*dy*(1.0f - dx) +
00340 mCloudVelY[k + mSize + 1]*dx*dy;
00341 }
00342 else
00343 {
00344 r_val.mV[VX] = mCloudVelX[k];
00345 r_val.mV[VY] = mCloudVelY[k];
00346 }
00347
00348 r_val.mV[VZ] = 0.f;
00349 return r_val * WIND_SCALE_HACK;
00350 }
00351
00352
00353 void LLWind::setCloudDensityPointer(F32 *densityp)
00354 {
00355 mCloudDensityp = densityp;
00356 }
00357
00358 void LLWind::setOriginGlobal(const LLVector3d &origin_global)
00359 {
00360 mOriginGlobal = origin_global;
00361 }
00362
00363