PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llwind.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 267 lines | 173 code | 45 blank | 49 comment | 27 complexity | 6f551aae20bea230dec57744c1a213bf MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llwind.cpp
  3. * @brief LLWind class implementation
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. // Wind is a lattice. It is computed on the simulator, and transmitted to the viewer.
  27. // It drives special effects like smoke blowing, trees bending, and grass wiggling.
  28. //
  29. // Currently wind lattice does not interpolate correctly to neighbors. This will need
  30. // work.
  31. #include "llviewerprecompiledheaders.h"
  32. #include "indra_constants.h"
  33. #include "llwind.h"
  34. // linden libraries
  35. #include "llgl.h"
  36. #include "patch_dct.h"
  37. #include "patch_code.h"
  38. // viewer
  39. #include "noise.h"
  40. #include "v4color.h"
  41. #include "llworld.h"
  42. //////////////////////////////////////////////////////////////////////
  43. // Construction/Destruction
  44. //////////////////////////////////////////////////////////////////////
  45. LLWind::LLWind()
  46. : mSize(16)
  47. {
  48. init();
  49. }
  50. LLWind::~LLWind()
  51. {
  52. delete [] mVelX;
  53. delete [] mVelY;
  54. }
  55. //////////////////////////////////////////////////////////////////////
  56. // Public Methods
  57. //////////////////////////////////////////////////////////////////////
  58. void LLWind::init()
  59. {
  60. LL_DEBUGS("Wind") << "initializing wind size: "<< mSize << LL_ENDL;
  61. // Initialize vector data
  62. mVelX = new F32[mSize*mSize];
  63. mVelY = new F32[mSize*mSize];
  64. S32 i;
  65. for (i = 0; i < mSize*mSize; i++)
  66. {
  67. mVelX[i] = 0.5f;
  68. mVelY[i] = 0.5f;
  69. }
  70. }
  71. void LLWind::decompress(LLBitPack &bitpack, LLGroupHeader *group_headerp)
  72. {
  73. LLPatchHeader patch_header;
  74. S32 buffer[16*16];
  75. init_patch_decompressor(group_headerp->patch_size);
  76. // Don't use the packed group_header stride because the strides used on
  77. // simulator and viewer are not equal.
  78. group_headerp->stride = group_headerp->patch_size;
  79. set_group_of_patch_header(group_headerp);
  80. // X component
  81. decode_patch_header(bitpack, &patch_header);
  82. decode_patch(bitpack, buffer);
  83. decompress_patch(mVelX, buffer, &patch_header);
  84. // Y component
  85. decode_patch_header(bitpack, &patch_header);
  86. decode_patch(bitpack, buffer);
  87. decompress_patch(mVelY, buffer, &patch_header);
  88. S32 i, j, k;
  89. for (j=1; j<mSize-1; j++)
  90. {
  91. for (i=1; i<mSize-1; i++)
  92. {
  93. k = i + j * mSize;
  94. *(mVelX + k) = *(mVelX + k);
  95. *(mVelY + k) = *(mVelY + k);
  96. }
  97. }
  98. i = mSize - 1;
  99. for (j=1; j<mSize-1; j++)
  100. {
  101. k = i + j * mSize;
  102. *(mVelX + k) = *(mVelX + k);
  103. *(mVelY + k) = *(mVelY + k);
  104. }
  105. i = 0;
  106. for (j=1; j<mSize-1; j++)
  107. {
  108. k = i + j * mSize;
  109. *(mVelX + k) = *(mVelX + k);
  110. *(mVelY + k) = *(mVelY + k);
  111. }
  112. j = mSize - 1;
  113. for (i=1; i<mSize-1; i++)
  114. {
  115. k = i + j * mSize;
  116. *(mVelX + k) = *(mVelX + k);
  117. *(mVelY + k) = *(mVelY + k);
  118. }
  119. j = 0;
  120. for (i=1; i<mSize-1; i++)
  121. {
  122. k = i + j * mSize;
  123. *(mVelX + k) = *(mVelX + k);
  124. *(mVelY + k) = *(mVelY + k);
  125. }
  126. }
  127. LLVector3 LLWind::getAverage()
  128. {
  129. // Returns in average_wind the average wind velocity
  130. LLVector3 average(0.0f, 0.0f, 0.0f);
  131. S32 i, grid_count;
  132. grid_count = mSize * mSize;
  133. for (i = 0; i < grid_count; i++)
  134. {
  135. average.mV[VX] += mVelX[i];
  136. average.mV[VY] += mVelY[i];
  137. }
  138. average *= 1.f/((F32)(grid_count)) * WIND_SCALE_HACK;
  139. return average;
  140. }
  141. LLVector3 LLWind::getVelocityNoisy(const LLVector3 &pos_region, const F32 dim)
  142. {
  143. // Resolve a value, using fractal summing to perturb the returned value
  144. LLVector3 r_val(0,0,0);
  145. F32 norm = 1.0f;
  146. if (dim == 8)
  147. {
  148. norm = 1.875;
  149. }
  150. else if (dim == 4)
  151. {
  152. norm = 1.75;
  153. }
  154. else if (dim == 2)
  155. {
  156. norm = 1.5;
  157. }
  158. F32 temp_dim = dim;
  159. while (temp_dim >= 1.0)
  160. {
  161. LLVector3 pos_region_scaled(pos_region * temp_dim);
  162. r_val += getVelocity(pos_region_scaled) * (1.0f/temp_dim);
  163. temp_dim /= 2.0;
  164. }
  165. return r_val * (1.0f/norm) * WIND_SCALE_HACK;
  166. }
  167. LLVector3 LLWind::getVelocity(const LLVector3 &pos_region)
  168. {
  169. llassert(mSize == 16);
  170. // Resolves value of wind at a location relative to SW corner of region
  171. //
  172. // Returns wind magnitude in X,Y components of vector3
  173. LLVector3 r_val;
  174. F32 dx,dy;
  175. S32 k;
  176. LLVector3 pos_clamped_region(pos_region);
  177. F32 region_width_meters = LLWorld::getInstance()->getRegionWidthInMeters();
  178. if (pos_clamped_region.mV[VX] < 0.f)
  179. {
  180. pos_clamped_region.mV[VX] = 0.f;
  181. }
  182. else if (pos_clamped_region.mV[VX] >= region_width_meters)
  183. {
  184. pos_clamped_region.mV[VX] = (F32) fmod(pos_clamped_region.mV[VX], region_width_meters);
  185. }
  186. if (pos_clamped_region.mV[VY] < 0.f)
  187. {
  188. pos_clamped_region.mV[VY] = 0.f;
  189. }
  190. else if (pos_clamped_region.mV[VY] >= region_width_meters)
  191. {
  192. pos_clamped_region.mV[VY] = (F32) fmod(pos_clamped_region.mV[VY], region_width_meters);
  193. }
  194. S32 i = llfloor(pos_clamped_region.mV[VX] * mSize / region_width_meters);
  195. S32 j = llfloor(pos_clamped_region.mV[VY] * mSize / region_width_meters);
  196. k = i + j*mSize;
  197. dx = ((pos_clamped_region.mV[VX] * mSize / region_width_meters) - (F32) i);
  198. dy = ((pos_clamped_region.mV[VY] * mSize / region_width_meters) - (F32) j);
  199. if ((i < mSize-1) && (j < mSize-1))
  200. {
  201. // Interior points, no edges
  202. r_val.mV[VX] = mVelX[k]*(1.0f - dx)*(1.0f - dy) +
  203. mVelX[k + 1]*dx*(1.0f - dy) +
  204. mVelX[k + mSize]*dy*(1.0f - dx) +
  205. mVelX[k + mSize + 1]*dx*dy;
  206. r_val.mV[VY] = mVelY[k]*(1.0f - dx)*(1.0f - dy) +
  207. mVelY[k + 1]*dx*(1.0f - dy) +
  208. mVelY[k + mSize]*dy*(1.0f - dx) +
  209. mVelY[k + mSize + 1]*dx*dy;
  210. }
  211. else
  212. {
  213. r_val.mV[VX] = mVelX[k];
  214. r_val.mV[VY] = mVelY[k];
  215. }
  216. r_val.mV[VZ] = 0.f;
  217. return r_val * WIND_SCALE_HACK;
  218. }
  219. void LLWind::setOriginGlobal(const LLVector3d &origin_global)
  220. {
  221. mOriginGlobal = origin_global;
  222. }