PageRenderTime 248ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llsurface.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1293 lines | 933 code | 201 blank | 159 comment | 149 complexity | 9ae2007a2c00774d369894a49f9c5f33 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsurface.cpp
  3. * @brief Implementation of LLSurface class
  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. #include "llviewerprecompiledheaders.h"
  27. #include "llsurface.h"
  28. #include "llrender.h"
  29. #include "llviewertexturelist.h"
  30. #include "llpatchvertexarray.h"
  31. #include "patch_dct.h"
  32. #include "patch_code.h"
  33. #include "bitpack.h"
  34. #include "llviewerobjectlist.h"
  35. #include "llregionhandle.h"
  36. #include "llagent.h"
  37. #include "llagentcamera.h"
  38. #include "llappviewer.h"
  39. #include "llworld.h"
  40. #include "llviewercontrol.h"
  41. #include "llviewertexture.h"
  42. #include "llsurfacepatch.h"
  43. #include "llvosurfacepatch.h"
  44. #include "llvowater.h"
  45. #include "pipeline.h"
  46. #include "llviewerregion.h"
  47. #include "llvlcomposition.h"
  48. #include "noise.h"
  49. #include "llviewercamera.h"
  50. #include "llglheaders.h"
  51. #include "lldrawpoolterrain.h"
  52. #include "lldrawable.h"
  53. extern LLPipeline gPipeline;
  54. LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
  55. S32 LLSurface::sTextureSize = 256;
  56. S32 LLSurface::sTexelsUpdated = 0;
  57. F32 LLSurface::sTextureUpdateTime = 0.f;
  58. // ---------------- LLSurface:: Public Members ---------------
  59. LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) :
  60. mGridsPerEdge(0),
  61. mOOGridsPerEdge(0.f),
  62. mPatchesPerEdge(0),
  63. mNumberOfPatches(0),
  64. mType(type),
  65. mDetailTextureScale(0.f),
  66. mOriginGlobal(0.0, 0.0, 0.0),
  67. mSTexturep(NULL),
  68. mWaterTexturep(NULL),
  69. mGridsPerPatchEdge(0),
  70. mMetersPerGrid(1.0f),
  71. mMetersPerEdge(1.0f),
  72. mRegionp(regionp)
  73. {
  74. // Surface data
  75. mSurfaceZ = NULL;
  76. mNorm = NULL;
  77. // Patch data
  78. mPatchList = NULL;
  79. // One of each for each camera
  80. mVisiblePatchCount = 0;
  81. mHasZData = FALSE;
  82. // "uninitialized" min/max z
  83. mMinZ = 10000.f;
  84. mMaxZ = -10000.f;
  85. mWaterObjp = NULL;
  86. // In here temporarily.
  87. mSurfacePatchUpdateCount = 0;
  88. for (S32 i = 0; i < 8; i++)
  89. {
  90. mNeighbors[i] = NULL;
  91. }
  92. }
  93. LLSurface::~LLSurface()
  94. {
  95. delete [] mSurfaceZ;
  96. mSurfaceZ = NULL;
  97. delete [] mNorm;
  98. mGridsPerEdge = 0;
  99. mGridsPerPatchEdge = 0;
  100. mPatchesPerEdge = 0;
  101. mNumberOfPatches = 0;
  102. destroyPatchData();
  103. LLDrawPoolTerrain *poolp = (LLDrawPoolTerrain*) gPipeline.findPool(LLDrawPool::POOL_TERRAIN, mSTexturep);
  104. if (!poolp)
  105. {
  106. llwarns << "No pool for terrain on destruction!" << llendl;
  107. }
  108. else if (poolp->mReferences.empty())
  109. {
  110. gPipeline.removePool(poolp);
  111. // Don't enable this until we blitz the draw pool for it as well. -- djs
  112. if (mSTexturep)
  113. {
  114. mSTexturep = NULL;
  115. }
  116. if (mWaterTexturep)
  117. {
  118. mWaterTexturep = NULL;
  119. }
  120. }
  121. else
  122. {
  123. llerrs << "Terrain pool not empty!" << llendl;
  124. }
  125. }
  126. void LLSurface::initClasses()
  127. {
  128. }
  129. void LLSurface::setRegion(LLViewerRegion *regionp)
  130. {
  131. mRegionp = regionp;
  132. mWaterObjp = NULL; // depends on regionp, needs recreating
  133. }
  134. // Assumes that arguments are powers of 2, and that
  135. // grids_per_edge / grids_per_patch_edge = power of 2
  136. void LLSurface::create(const S32 grids_per_edge,
  137. const S32 grids_per_patch_edge,
  138. const LLVector3d &origin_global,
  139. const F32 width)
  140. {
  141. // Initialize various constants for the surface
  142. mGridsPerEdge = grids_per_edge + 1; // Add 1 for the east and north buffer
  143. mOOGridsPerEdge = 1.f / mGridsPerEdge;
  144. mGridsPerPatchEdge = grids_per_patch_edge;
  145. mPatchesPerEdge = (mGridsPerEdge - 1) / mGridsPerPatchEdge;
  146. mNumberOfPatches = mPatchesPerEdge * mPatchesPerEdge;
  147. mMetersPerGrid = width / ((F32)(mGridsPerEdge - 1));
  148. mMetersPerEdge = mMetersPerGrid * (mGridsPerEdge - 1);
  149. mOriginGlobal.setVec(origin_global);
  150. mPVArray.create(mGridsPerEdge, mGridsPerPatchEdge, LLWorld::getInstance()->getRegionScale());
  151. S32 number_of_grids = mGridsPerEdge * mGridsPerEdge;
  152. /////////////////////////////////////
  153. //
  154. // Initialize data arrays for surface
  155. ///
  156. mSurfaceZ = new F32[number_of_grids];
  157. mNorm = new LLVector3[number_of_grids];
  158. // Reset the surface to be a flat square grid
  159. for(S32 i=0; i < number_of_grids; i++)
  160. {
  161. // Surface is flat and zero
  162. // Normals all point up
  163. mSurfaceZ[i] = 0.0f;
  164. mNorm[i].setVec(0.f, 0.f, 1.f);
  165. }
  166. mVisiblePatchCount = 0;
  167. ///////////////////////
  168. //
  169. // Initialize textures
  170. //
  171. initTextures();
  172. // Has to be done after texture initialization
  173. createPatchData();
  174. }
  175. LLViewerTexture* LLSurface::getSTexture()
  176. {
  177. if (mSTexturep.notNull() && !mSTexturep->hasGLTexture())
  178. {
  179. createSTexture();
  180. }
  181. return mSTexturep;
  182. }
  183. LLViewerTexture* LLSurface::getWaterTexture()
  184. {
  185. if (mWaterTexturep.notNull() && !mWaterTexturep->hasGLTexture())
  186. {
  187. createWaterTexture();
  188. }
  189. return mWaterTexturep;
  190. }
  191. void LLSurface::createSTexture()
  192. {
  193. if (!mSTexturep)
  194. {
  195. // Fill with dummy gray data.
  196. // GL NOT ACTIVE HERE
  197. LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3);
  198. U8 *default_texture = raw->getData();
  199. for (S32 i = 0; i < sTextureSize; i++)
  200. {
  201. for (S32 j = 0; j < sTextureSize; j++)
  202. {
  203. *(default_texture + (i*sTextureSize + j)*3) = 128;
  204. *(default_texture + (i*sTextureSize + j)*3 + 1) = 128;
  205. *(default_texture + (i*sTextureSize + j)*3 + 2) = 128;
  206. }
  207. }
  208. mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
  209. mSTexturep->dontDiscard();
  210. gGL.getTexUnit(0)->bind(mSTexturep);
  211. mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  212. }
  213. }
  214. void LLSurface::createWaterTexture()
  215. {
  216. if (!mWaterTexturep)
  217. {
  218. // Create the water texture
  219. LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4);
  220. U8 *default_texture = raw->getData();
  221. for (S32 i = 0; i < sTextureSize/2; i++)
  222. {
  223. for (S32 j = 0; j < sTextureSize/2; j++)
  224. {
  225. *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0];
  226. *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1];
  227. *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2];
  228. *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3];
  229. }
  230. }
  231. mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
  232. mWaterTexturep->dontDiscard();
  233. gGL.getTexUnit(0)->bind(mWaterTexturep);
  234. mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  235. }
  236. }
  237. void LLSurface::initTextures()
  238. {
  239. ///////////////////////
  240. //
  241. // Main surface texture
  242. //
  243. createSTexture();
  244. ///////////////////////
  245. //
  246. // Water texture
  247. //
  248. if (gSavedSettings.getBOOL("RenderWater") )
  249. {
  250. createWaterTexture();
  251. mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
  252. gPipeline.createObject(mWaterObjp);
  253. LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
  254. water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT);
  255. mWaterObjp->setPositionGlobal(water_pos_global);
  256. }
  257. }
  258. void LLSurface::setOriginGlobal(const LLVector3d &origin_global)
  259. {
  260. LLVector3d new_origin_global;
  261. mOriginGlobal = origin_global;
  262. LLSurfacePatch *patchp;
  263. S32 i, j;
  264. // Need to update the southwest corners of the patches
  265. for (j=0; j<mPatchesPerEdge; j++)
  266. {
  267. for (i=0; i<mPatchesPerEdge; i++)
  268. {
  269. patchp = getPatch(i, j);
  270. new_origin_global = patchp->getOriginGlobal();
  271. new_origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge;
  272. new_origin_global.mdV[1] = mOriginGlobal.mdV[1] + j * mMetersPerGrid * mGridsPerPatchEdge;
  273. patchp->setOriginGlobal(new_origin_global);
  274. }
  275. }
  276. // Hack!
  277. if (mWaterObjp.notNull() && mWaterObjp->mDrawable.notNull())
  278. {
  279. const F64 x = origin_global.mdV[VX] + 128.0;
  280. const F64 y = origin_global.mdV[VY] + 128.0;
  281. const F64 z = mWaterObjp->getPositionGlobal().mdV[VZ];
  282. LLVector3d water_origin_global(x, y, z);
  283. mWaterObjp->setPositionGlobal(water_origin_global);
  284. }
  285. }
  286. void LLSurface::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
  287. {
  288. S32 i;
  289. for (i = 0; i < 8; i++)
  290. {
  291. if ( mNeighbors[i] != NULL )
  292. {
  293. uniqueRegions.push_back( mNeighbors[i]->getRegion() );
  294. }
  295. }
  296. }
  297. void LLSurface::connectNeighbor(LLSurface *neighborp, U32 direction)
  298. {
  299. S32 i;
  300. LLSurfacePatch *patchp, *neighbor_patchp;
  301. mNeighbors[direction] = neighborp;
  302. neighborp->mNeighbors[gDirOpposite[direction]] = this;
  303. // Connect patches
  304. if (NORTHEAST == direction)
  305. {
  306. patchp = getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
  307. neighbor_patchp = neighborp->getPatch(0, 0);
  308. patchp->connectNeighbor(neighbor_patchp, direction);
  309. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  310. patchp->updateNorthEdge(); // Only update one of north or east.
  311. patchp->dirtyZ();
  312. }
  313. else if (NORTHWEST == direction)
  314. {
  315. patchp = getPatch(0, mPatchesPerEdge - 1);
  316. neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, 0);
  317. patchp->connectNeighbor(neighbor_patchp, direction);
  318. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  319. }
  320. else if (SOUTHWEST == direction)
  321. {
  322. patchp = getPatch(0, 0);
  323. neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, mPatchesPerEdge - 1);
  324. patchp->connectNeighbor(neighbor_patchp, direction);
  325. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  326. neighbor_patchp->updateNorthEdge(); // Only update one of north or east.
  327. neighbor_patchp->dirtyZ();
  328. }
  329. else if (SOUTHEAST == direction)
  330. {
  331. patchp = getPatch(mPatchesPerEdge - 1, 0);
  332. neighbor_patchp = neighborp->getPatch(0, mPatchesPerEdge - 1);
  333. patchp->connectNeighbor(neighbor_patchp, direction);
  334. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  335. }
  336. else if (EAST == direction)
  337. {
  338. // Do east/west connections, first
  339. for (i = 0; i < (S32)mPatchesPerEdge; i++)
  340. {
  341. patchp = getPatch(mPatchesPerEdge - 1, i);
  342. neighbor_patchp = neighborp->getPatch(0, i);
  343. patchp->connectNeighbor(neighbor_patchp, direction);
  344. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  345. patchp->updateEastEdge();
  346. patchp->dirtyZ();
  347. }
  348. // Now do northeast/southwest connections
  349. for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
  350. {
  351. patchp = getPatch(mPatchesPerEdge - 1, i);
  352. neighbor_patchp = neighborp->getPatch(0, i+1);
  353. patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
  354. neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
  355. }
  356. // Now do southeast/northwest connections
  357. for (i = 1; i < (S32)mPatchesPerEdge; i++)
  358. {
  359. patchp = getPatch(mPatchesPerEdge - 1, i);
  360. neighbor_patchp = neighborp->getPatch(0, i-1);
  361. patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
  362. neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
  363. }
  364. }
  365. else if (NORTH == direction)
  366. {
  367. // Do north/south connections, first
  368. for (i = 0; i < (S32)mPatchesPerEdge; i++)
  369. {
  370. patchp = getPatch(i, mPatchesPerEdge - 1);
  371. neighbor_patchp = neighborp->getPatch(i, 0);
  372. patchp->connectNeighbor(neighbor_patchp, direction);
  373. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  374. patchp->updateNorthEdge();
  375. patchp->dirtyZ();
  376. }
  377. // Do northeast/southwest connections
  378. for (i = 0; i < (S32)mPatchesPerEdge - 1; i++)
  379. {
  380. patchp = getPatch(i, mPatchesPerEdge - 1);
  381. neighbor_patchp = neighborp->getPatch(i+1, 0);
  382. patchp->connectNeighbor(neighbor_patchp, NORTHEAST);
  383. neighbor_patchp->connectNeighbor(patchp, SOUTHWEST);
  384. }
  385. // Do southeast/northwest connections
  386. for (i = 1; i < (S32)mPatchesPerEdge; i++)
  387. {
  388. patchp = getPatch(i, mPatchesPerEdge - 1);
  389. neighbor_patchp = neighborp->getPatch(i-1, 0);
  390. patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
  391. neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
  392. }
  393. }
  394. else if (WEST == direction)
  395. {
  396. // Do east/west connections, first
  397. for (i = 0; i < mPatchesPerEdge; i++)
  398. {
  399. patchp = getPatch(0, i);
  400. neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i);
  401. patchp->connectNeighbor(neighbor_patchp, direction);
  402. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  403. neighbor_patchp->updateEastEdge();
  404. neighbor_patchp->dirtyZ();
  405. }
  406. // Now do northeast/southwest connections
  407. for (i = 1; i < mPatchesPerEdge; i++)
  408. {
  409. patchp = getPatch(0, i);
  410. neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i - 1);
  411. patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
  412. neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
  413. }
  414. // Now do northwest/southeast connections
  415. for (i = 0; i < mPatchesPerEdge - 1; i++)
  416. {
  417. patchp = getPatch(0, i);
  418. neighbor_patchp = neighborp->getPatch(mPatchesPerEdge - 1, i + 1);
  419. patchp->connectNeighbor(neighbor_patchp, NORTHWEST);
  420. neighbor_patchp->connectNeighbor(patchp, SOUTHEAST);
  421. }
  422. }
  423. else if (SOUTH == direction)
  424. {
  425. // Do north/south connections, first
  426. for (i = 0; i < mPatchesPerEdge; i++)
  427. {
  428. patchp = getPatch(i, 0);
  429. neighbor_patchp = neighborp->getPatch(i, mPatchesPerEdge - 1);
  430. patchp->connectNeighbor(neighbor_patchp, direction);
  431. neighbor_patchp->connectNeighbor(patchp, gDirOpposite[direction]);
  432. neighbor_patchp->updateNorthEdge();
  433. neighbor_patchp->dirtyZ();
  434. }
  435. // Now do northeast/southwest connections
  436. for (i = 1; i < mPatchesPerEdge; i++)
  437. {
  438. patchp = getPatch(i, 0);
  439. neighbor_patchp = neighborp->getPatch(i - 1, mPatchesPerEdge - 1);
  440. patchp->connectNeighbor(neighbor_patchp, SOUTHWEST);
  441. neighbor_patchp->connectNeighbor(patchp, NORTHEAST);
  442. }
  443. // Now do northeast/southwest connections
  444. for (i = 0; i < mPatchesPerEdge - 1; i++)
  445. {
  446. patchp = getPatch(i, 0);
  447. neighbor_patchp = neighborp->getPatch(i + 1, mPatchesPerEdge - 1);
  448. patchp->connectNeighbor(neighbor_patchp, SOUTHEAST);
  449. neighbor_patchp->connectNeighbor(patchp, NORTHWEST);
  450. }
  451. }
  452. }
  453. void LLSurface::disconnectNeighbor(LLSurface *surfacep)
  454. {
  455. S32 i;
  456. for (i = 0; i < 8; i++)
  457. {
  458. if (surfacep == mNeighbors[i])
  459. {
  460. mNeighbors[i] = NULL;
  461. }
  462. }
  463. // Iterate through surface patches, removing any connectivity to removed surface.
  464. for (i = 0; i < mNumberOfPatches; i++)
  465. {
  466. (mPatchList + i)->disconnectNeighbor(surfacep);
  467. }
  468. }
  469. void LLSurface::disconnectAllNeighbors()
  470. {
  471. S32 i;
  472. for (i = 0; i < 8; i++)
  473. {
  474. if (mNeighbors[i])
  475. {
  476. mNeighbors[i]->disconnectNeighbor(this);
  477. mNeighbors[i] = NULL;
  478. }
  479. }
  480. }
  481. const LLVector3d &LLSurface::getOriginGlobal() const
  482. {
  483. return mOriginGlobal;
  484. }
  485. LLVector3 LLSurface::getOriginAgent() const
  486. {
  487. return gAgent.getPosAgentFromGlobal(mOriginGlobal);
  488. }
  489. F32 LLSurface::getMetersPerGrid() const
  490. {
  491. return mMetersPerGrid;
  492. }
  493. S32 LLSurface::getGridsPerEdge() const
  494. {
  495. return mGridsPerEdge;
  496. }
  497. S32 LLSurface::getPatchesPerEdge() const
  498. {
  499. return mPatchesPerEdge;
  500. }
  501. S32 LLSurface::getGridsPerPatchEdge() const
  502. {
  503. return mGridsPerPatchEdge;
  504. }
  505. void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta)
  506. {
  507. llassert(x >= 0);
  508. llassert(y >= 0);
  509. llassert(x < mGridsPerEdge);
  510. llassert(y < mGridsPerEdge);
  511. mSurfaceZ[x + y*mGridsPerEdge] += delta;
  512. }
  513. void LLSurface::updatePatchVisibilities(LLAgent &agent)
  514. {
  515. LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
  516. LLSurfacePatch *patchp;
  517. mVisiblePatchCount = 0;
  518. for (S32 i=0; i<mNumberOfPatches; i++)
  519. {
  520. patchp = mPatchList + i;
  521. patchp->updateVisibility();
  522. if (patchp->getVisible())
  523. {
  524. mVisiblePatchCount++;
  525. patchp->updateCameraDistanceRegion(pos_region);
  526. }
  527. }
  528. }
  529. BOOL LLSurface::idleUpdate(F32 max_update_time)
  530. {
  531. LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE);
  532. if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN))
  533. {
  534. return FALSE;
  535. }
  536. // Perform idle time update of non-critical stuff.
  537. // In this case, texture and normal updates.
  538. LLTimer update_timer;
  539. BOOL did_update = FALSE;
  540. // If the Z height data has changed, we need to rebuild our
  541. // property line vertex arrays.
  542. if (mDirtyPatchList.size() > 0)
  543. {
  544. getRegion()->dirtyHeights();
  545. }
  546. // Always call updateNormals() / updateVerticalStats()
  547. // every frame to avoid artifacts
  548. for(std::set<LLSurfacePatch *>::iterator iter = mDirtyPatchList.begin();
  549. iter != mDirtyPatchList.end(); )
  550. {
  551. std::set<LLSurfacePatch *>::iterator curiter = iter++;
  552. LLSurfacePatch *patchp = *curiter;
  553. patchp->updateNormals();
  554. patchp->updateVerticalStats();
  555. if (max_update_time == 0.f || update_timer.getElapsedTimeF32() < max_update_time)
  556. {
  557. if (patchp->updateTexture())
  558. {
  559. did_update = TRUE;
  560. patchp->clearDirty();
  561. mDirtyPatchList.erase(curiter);
  562. }
  563. }
  564. }
  565. return did_update;
  566. }
  567. void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL b_large_patch)
  568. {
  569. LLPatchHeader ph;
  570. S32 j, i;
  571. S32 patch[LARGE_PATCH_SIZE*LARGE_PATCH_SIZE];
  572. LLSurfacePatch *patchp;
  573. init_patch_decompressor(gopp->patch_size);
  574. gopp->stride = mGridsPerEdge;
  575. set_group_of_patch_header(gopp);
  576. while (1)
  577. {
  578. decode_patch_header(bitpack, &ph);
  579. if (ph.quant_wbits == END_OF_PATCHES)
  580. {
  581. break;
  582. }
  583. i = ph.patchids >> 5;
  584. j = ph.patchids & 0x1F;
  585. if ((i >= mPatchesPerEdge) || (j >= mPatchesPerEdge))
  586. {
  587. llwarns << "Received invalid terrain packet - patch header patch ID incorrect!"
  588. << " patches per edge " << mPatchesPerEdge
  589. << " i " << i
  590. << " j " << j
  591. << " dc_offset " << ph.dc_offset
  592. << " range " << (S32)ph.range
  593. << " quant_wbits " << (S32)ph.quant_wbits
  594. << " patchids " << (S32)ph.patchids
  595. << llendl;
  596. LLAppViewer::instance()->badNetworkHandler();
  597. return;
  598. }
  599. patchp = &mPatchList[j*mPatchesPerEdge + i];
  600. decode_patch(bitpack, patch);
  601. decompress_patch(patchp->getDataZ(), patch, &ph);
  602. // Update edges for neighbors. Need to guarantee that this gets done before we generate vertical stats.
  603. patchp->updateNorthEdge();
  604. patchp->updateEastEdge();
  605. if (patchp->getNeighborPatch(WEST))
  606. {
  607. patchp->getNeighborPatch(WEST)->updateEastEdge();
  608. }
  609. if (patchp->getNeighborPatch(SOUTHWEST))
  610. {
  611. patchp->getNeighborPatch(SOUTHWEST)->updateEastEdge();
  612. patchp->getNeighborPatch(SOUTHWEST)->updateNorthEdge();
  613. }
  614. if (patchp->getNeighborPatch(SOUTH))
  615. {
  616. patchp->getNeighborPatch(SOUTH)->updateNorthEdge();
  617. }
  618. // Dirty patch statistics, and flag that the patch has data.
  619. patchp->dirtyZ();
  620. patchp->setHasReceivedData();
  621. }
  622. }
  623. // Retrurns TRUE if "position" is within the bounds of surface.
  624. // "position" is region-local
  625. BOOL LLSurface::containsPosition(const LLVector3 &position)
  626. {
  627. if (position.mV[VX] < 0.0f || position.mV[VX] > mMetersPerEdge ||
  628. position.mV[VY] < 0.0f || position.mV[VY] > mMetersPerEdge)
  629. {
  630. return FALSE;
  631. }
  632. return TRUE;
  633. }
  634. F32 LLSurface::resolveHeightRegion(const F32 x, const F32 y) const
  635. {
  636. F32 height = 0.0f;
  637. F32 oometerspergrid = 1.f/mMetersPerGrid;
  638. // Check to see if v is actually above surface
  639. // We use (mGridsPerEdge-1) below rather than (mGridsPerEdge)
  640. // becuase of the east and north buffers
  641. if (x >= 0.f &&
  642. x <= mMetersPerEdge &&
  643. y >= 0.f &&
  644. y <= mMetersPerEdge)
  645. {
  646. const S32 left = llfloor(x * oometerspergrid);
  647. const S32 bottom = llfloor(y * oometerspergrid);
  648. // Don't walk off the edge of the array!
  649. const S32 right = ( left+1 < (S32)mGridsPerEdge-1 ? left+1 : left );
  650. const S32 top = ( bottom+1 < (S32)mGridsPerEdge-1 ? bottom+1 : bottom );
  651. // Figure out if v is in first or second triangle of the square
  652. // and calculate the slopes accordingly
  653. // | |
  654. // -(i,j+1)---(i+1,j+1)--
  655. // | 1 / | ^
  656. // | / 2 | |
  657. // | / | j
  658. // --(i,j)----(i+1,j)--
  659. // | |
  660. //
  661. // i ->
  662. // where N = mGridsPerEdge
  663. const F32 left_bottom = getZ( left, bottom );
  664. const F32 right_bottom = getZ( right, bottom );
  665. const F32 left_top = getZ( left, top );
  666. const F32 right_top = getZ( right, top );
  667. // dx and dy are incremental steps from (mSurface + k)
  668. F32 dx = x - left * mMetersPerGrid;
  669. F32 dy = y - bottom * mMetersPerGrid;
  670. if (dy > dx)
  671. {
  672. // triangle 1
  673. dy *= left_top - left_bottom;
  674. dx *= right_top - left_top;
  675. }
  676. else
  677. {
  678. // triangle 2
  679. dx *= right_bottom - left_bottom;
  680. dy *= right_top - right_bottom;
  681. }
  682. height = left_bottom + (dx + dy) * oometerspergrid;
  683. }
  684. return height;
  685. }
  686. F32 LLSurface::resolveHeightGlobal(const LLVector3d& v) const
  687. {
  688. if (!mRegionp)
  689. {
  690. return 0.f;
  691. }
  692. LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(v);
  693. return resolveHeightRegion(pos_region);
  694. }
  695. LLVector3 LLSurface::resolveNormalGlobal(const LLVector3d& pos_global) const
  696. {
  697. if (!mSurfaceZ)
  698. {
  699. // Hmm. Uninitialized surface!
  700. return LLVector3::z_axis;
  701. }
  702. //
  703. // Returns the vector normal to a surface at location specified by vector v
  704. //
  705. F32 oometerspergrid = 1.f/mMetersPerGrid;
  706. LLVector3 normal;
  707. F32 dzx, dzy;
  708. if (pos_global.mdV[VX] >= mOriginGlobal.mdV[VX] &&
  709. pos_global.mdV[VX] < mOriginGlobal.mdV[VX] + mMetersPerEdge &&
  710. pos_global.mdV[VY] >= mOriginGlobal.mdV[VY] &&
  711. pos_global.mdV[VY] < mOriginGlobal.mdV[VY] + mMetersPerEdge)
  712. {
  713. U32 i, j, k;
  714. F32 dx, dy;
  715. i = (U32) ((pos_global.mdV[VX] - mOriginGlobal.mdV[VX]) * oometerspergrid);
  716. j = (U32) ((pos_global.mdV[VY] - mOriginGlobal.mdV[VY]) * oometerspergrid );
  717. k = i + j*mGridsPerEdge;
  718. // Figure out if v is in first or second triangle of the square
  719. // and calculate the slopes accordingly
  720. // | |
  721. // -(k+N)---(k+1+N)--
  722. // | 1 / | ^
  723. // | / 2 | |
  724. // | / | j
  725. // --(k)----(k+1)--
  726. // | |
  727. //
  728. // i ->
  729. // where N = mGridsPerEdge
  730. // dx and dy are incremental steps from (mSurface + k)
  731. dx = (F32)(pos_global.mdV[VX] - i*mMetersPerGrid - mOriginGlobal.mdV[VX]);
  732. dy = (F32)(pos_global.mdV[VY] - j*mMetersPerGrid - mOriginGlobal.mdV[VY]);
  733. if (dy > dx)
  734. { // triangle 1
  735. dzx = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + mGridsPerEdge);
  736. dzy = *(mSurfaceZ + k) - *(mSurfaceZ + k + mGridsPerEdge);
  737. normal.setVec(-dzx,dzy,1);
  738. }
  739. else
  740. { // triangle 2
  741. dzx = *(mSurfaceZ + k) - *(mSurfaceZ + k + 1);
  742. dzy = *(mSurfaceZ + k + 1 + mGridsPerEdge) - *(mSurfaceZ + k + 1);
  743. normal.setVec(dzx,-dzy,1);
  744. }
  745. }
  746. normal.normVec();
  747. return normal;
  748. }
  749. LLSurfacePatch *LLSurface::resolvePatchRegion(const F32 x, const F32 y) const
  750. {
  751. // x and y should be region-local coordinates.
  752. // If x and y are outside of the surface, then the returned
  753. // index will be for the nearest boundary patch.
  754. //
  755. // 12 | 13| 14| 15
  756. // | | |
  757. // +---+---+---+---+
  758. // | 12| 13| 14| 15|
  759. // ----+---+---+---+---+-----
  760. // 8 | 8 | 9 | 10| 11| 11
  761. // ----+---+---+---+---+-----
  762. // 4 | 4 | 5 | 6 | 7 | 7
  763. // ----+---+---+---+---+-----
  764. // | 0 | 1 | 2 | 3 |
  765. // +---+---+---+---+
  766. // | | |
  767. // 0 | 1 | 2 | 3
  768. //
  769. // When x and y are not region-local do the following first
  770. S32 i, j;
  771. if (x < 0.0f)
  772. {
  773. i = 0;
  774. }
  775. else if (x >= mMetersPerEdge)
  776. {
  777. i = mPatchesPerEdge - 1;
  778. }
  779. else
  780. {
  781. i = (U32) (x / (mMetersPerGrid * mGridsPerPatchEdge));
  782. }
  783. if (y < 0.0f)
  784. {
  785. j = 0;
  786. }
  787. else if (y >= mMetersPerEdge)
  788. {
  789. j = mPatchesPerEdge - 1;
  790. }
  791. else
  792. {
  793. j = (U32) (y / (mMetersPerGrid * mGridsPerPatchEdge));
  794. }
  795. // *NOTE: Super paranoia code follows.
  796. S32 index = i + j * mPatchesPerEdge;
  797. if((index < 0) || (index >= mNumberOfPatches))
  798. {
  799. if(0 == mNumberOfPatches)
  800. {
  801. llwarns << "No patches for current region!" << llendl;
  802. return NULL;
  803. }
  804. S32 old_index = index;
  805. index = llclamp(old_index, 0, (mNumberOfPatches - 1));
  806. llwarns << "Clamping out of range patch index " << old_index
  807. << " to " << index << llendl;
  808. }
  809. return &(mPatchList[index]);
  810. }
  811. LLSurfacePatch *LLSurface::resolvePatchRegion(const LLVector3 &pos_region) const
  812. {
  813. return resolvePatchRegion(pos_region.mV[VX], pos_region.mV[VY]);
  814. }
  815. LLSurfacePatch *LLSurface::resolvePatchGlobal(const LLVector3d &pos_global) const
  816. {
  817. llassert(mRegionp);
  818. LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(pos_global);
  819. return resolvePatchRegion(pos_region);
  820. }
  821. std::ostream& operator<<(std::ostream &s, const LLSurface &S)
  822. {
  823. s << "{ \n";
  824. s << " mGridsPerEdge = " << S.mGridsPerEdge - 1 << " + 1\n";
  825. s << " mGridsPerPatchEdge = " << S.mGridsPerPatchEdge << "\n";
  826. s << " mPatchesPerEdge = " << S.mPatchesPerEdge << "\n";
  827. s << " mOriginGlobal = " << S.mOriginGlobal << "\n";
  828. s << " mMetersPerGrid = " << S.mMetersPerGrid << "\n";
  829. s << " mVisiblePatchCount = " << S.mVisiblePatchCount << "\n";
  830. s << "}";
  831. return s;
  832. }
  833. // ---------------- LLSurface:: Protected ----------------
  834. void LLSurface::createPatchData()
  835. {
  836. // Assumes mGridsPerEdge, mGridsPerPatchEdge, and mPatchesPerEdge have been properly set
  837. // TODO -- check for create() called when surface is not empty
  838. S32 i, j;
  839. LLSurfacePatch *patchp;
  840. // Allocate memory
  841. mPatchList = new LLSurfacePatch[mNumberOfPatches];
  842. // One of each for each camera
  843. mVisiblePatchCount = mNumberOfPatches;
  844. for (j=0; j<mPatchesPerEdge; j++)
  845. {
  846. for (i=0; i<mPatchesPerEdge; i++)
  847. {
  848. patchp = getPatch(i, j);
  849. patchp->setSurface(this);
  850. }
  851. }
  852. for (j=0; j<mPatchesPerEdge; j++)
  853. {
  854. for (i=0; i<mPatchesPerEdge; i++)
  855. {
  856. patchp = getPatch(i, j);
  857. patchp->mHasReceivedData = FALSE;
  858. patchp->mSTexUpdate = TRUE;
  859. S32 data_offset = i * mGridsPerPatchEdge + j * mGridsPerPatchEdge * mGridsPerEdge;
  860. patchp->setDataZ(mSurfaceZ + data_offset);
  861. patchp->setDataNorm(mNorm + data_offset);
  862. // We make each patch point to its neighbors so we can do resolution checking
  863. // when butting up different resolutions. Patches that don't have neighbors
  864. // somewhere will point to NULL on that side.
  865. if (i < mPatchesPerEdge-1)
  866. {
  867. patchp->setNeighborPatch(EAST,getPatch(i+1, j));
  868. }
  869. else
  870. {
  871. patchp->setNeighborPatch(EAST, NULL);
  872. }
  873. if (j < mPatchesPerEdge-1)
  874. {
  875. patchp->setNeighborPatch(NORTH, getPatch(i, j+1));
  876. }
  877. else
  878. {
  879. patchp->setNeighborPatch(NORTH, NULL);
  880. }
  881. if (i > 0)
  882. {
  883. patchp->setNeighborPatch(WEST, getPatch(i - 1, j));
  884. }
  885. else
  886. {
  887. patchp->setNeighborPatch(WEST, NULL);
  888. }
  889. if (j > 0)
  890. {
  891. patchp->setNeighborPatch(SOUTH, getPatch(i, j-1));
  892. }
  893. else
  894. {
  895. patchp->setNeighborPatch(SOUTH, NULL);
  896. }
  897. if (i < (mPatchesPerEdge-1) && j < (mPatchesPerEdge-1))
  898. {
  899. patchp->setNeighborPatch(NORTHEAST, getPatch(i + 1, j + 1));
  900. }
  901. else
  902. {
  903. patchp->setNeighborPatch(NORTHEAST, NULL);
  904. }
  905. if (i > 0 && j < (mPatchesPerEdge-1))
  906. {
  907. patchp->setNeighborPatch(NORTHWEST, getPatch(i - 1, j + 1));
  908. }
  909. else
  910. {
  911. patchp->setNeighborPatch(NORTHWEST, NULL);
  912. }
  913. if (i > 0 && j > 0)
  914. {
  915. patchp->setNeighborPatch(SOUTHWEST, getPatch(i - 1, j - 1));
  916. }
  917. else
  918. {
  919. patchp->setNeighborPatch(SOUTHWEST, NULL);
  920. }
  921. if (i < (mPatchesPerEdge-1) && j > 0)
  922. {
  923. patchp->setNeighborPatch(SOUTHEAST, getPatch(i + 1, j - 1));
  924. }
  925. else
  926. {
  927. patchp->setNeighborPatch(SOUTHEAST, NULL);
  928. }
  929. LLVector3d origin_global;
  930. origin_global.mdV[0] = mOriginGlobal.mdV[0] + i * mMetersPerGrid * mGridsPerPatchEdge;
  931. origin_global.mdV[1] = mOriginGlobal.mdV[0] + j * mMetersPerGrid * mGridsPerPatchEdge;
  932. origin_global.mdV[2] = 0.f;
  933. patchp->setOriginGlobal(origin_global);
  934. }
  935. }
  936. }
  937. void LLSurface::destroyPatchData()
  938. {
  939. // Delete all of the cached patch data for these patches.
  940. delete [] mPatchList;
  941. mPatchList = NULL;
  942. mVisiblePatchCount = 0;
  943. }
  944. void LLSurface::setTextureSize(const S32 texture_size)
  945. {
  946. sTextureSize = texture_size;
  947. }
  948. U32 LLSurface::getRenderLevel(const U32 render_stride) const
  949. {
  950. return mPVArray.mRenderLevelp[render_stride];
  951. }
  952. U32 LLSurface::getRenderStride(const U32 render_level) const
  953. {
  954. return mPVArray.mRenderStridep[render_level];
  955. }
  956. LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const
  957. {
  958. if ((x < 0) || (x >= mPatchesPerEdge))
  959. {
  960. llerrs << "Asking for patch out of bounds" << llendl;
  961. return NULL;
  962. }
  963. if ((y < 0) || (y >= mPatchesPerEdge))
  964. {
  965. llerrs << "Asking for patch out of bounds" << llendl;
  966. return NULL;
  967. }
  968. return mPatchList + x + y*mPatchesPerEdge;
  969. }
  970. void LLSurface::dirtyAllPatches()
  971. {
  972. S32 i;
  973. for (i = 0; i < mNumberOfPatches; i++)
  974. {
  975. mPatchList[i].dirtyZ();
  976. }
  977. }
  978. void LLSurface::dirtySurfacePatch(LLSurfacePatch *patchp)
  979. {
  980. // Put surface patch on dirty surface patch list
  981. mDirtyPatchList.insert(patchp);
  982. }
  983. void LLSurface::setWaterHeight(F32 height)
  984. {
  985. if (!mWaterObjp.isNull())
  986. {
  987. LLVector3 water_pos_region = mWaterObjp->getPositionRegion();
  988. bool changed = water_pos_region.mV[VZ] != height;
  989. water_pos_region.mV[VZ] = height;
  990. mWaterObjp->setPositionRegion(water_pos_region);
  991. if (changed)
  992. {
  993. LLWorld::getInstance()->updateWaterObjects();
  994. }
  995. }
  996. else
  997. {
  998. llwarns << "LLSurface::setWaterHeight with no water object!" << llendl;
  999. }
  1000. }
  1001. F32 LLSurface::getWaterHeight() const
  1002. {
  1003. if (!mWaterObjp.isNull())
  1004. {
  1005. // we have a water object, the usual case
  1006. return mWaterObjp->getPositionRegion().mV[VZ];
  1007. }
  1008. else
  1009. {
  1010. return DEFAULT_WATER_HEIGHT;
  1011. }
  1012. }
  1013. BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
  1014. const F32 width, const F32 height)
  1015. {
  1016. if (!getWaterTexture())
  1017. {
  1018. return FALSE;
  1019. }
  1020. S32 tex_width = mWaterTexturep->getWidth();
  1021. S32 tex_height = mWaterTexturep->getHeight();
  1022. S32 tex_comps = mWaterTexturep->getComponents();
  1023. S32 tex_stride = tex_width * tex_comps;
  1024. LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
  1025. U8 *rawp = raw->getData();
  1026. F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width;
  1027. F32 scale_inv = 1.f / scale;
  1028. S32 x_begin, y_begin, x_end, y_end;
  1029. x_begin = llround(x * scale_inv);
  1030. y_begin = llround(y * scale_inv);
  1031. x_end = llround((x + width) * scale_inv);
  1032. y_end = llround((y + width) * scale_inv);
  1033. if (x_end > tex_width)
  1034. {
  1035. x_end = tex_width;
  1036. }
  1037. if (y_end > tex_width)
  1038. {
  1039. y_end = tex_width;
  1040. }
  1041. LLVector3d origin_global = from_region_handle(getRegion()->getHandle());
  1042. // OK, for now, just have the composition value equal the height at the point.
  1043. LLVector3 location;
  1044. LLColor4U coloru;
  1045. const F32 WATER_HEIGHT = getWaterHeight();
  1046. S32 i, j, offset;
  1047. for (j = y_begin; j < y_end; j++)
  1048. {
  1049. for (i = x_begin; i < x_end; i++)
  1050. {
  1051. //F32 nv[2];
  1052. //nv[0] = i/256.f;
  1053. //nv[1] = j/256.f;
  1054. // const S32 modulation = noise2(nv)*40;
  1055. offset = j*tex_stride + i*tex_comps;
  1056. location.mV[VX] = i*scale;
  1057. location.mV[VY] = j*scale;
  1058. // Sample multiple points
  1059. const F32 height = resolveHeightRegion(location);
  1060. if (height > WATER_HEIGHT)
  1061. {
  1062. // Above water...
  1063. coloru = MAX_WATER_COLOR;
  1064. coloru.mV[3] = ABOVE_WATERLINE_ALPHA;
  1065. *(rawp + offset++) = coloru.mV[0];
  1066. *(rawp + offset++) = coloru.mV[1];
  1067. *(rawp + offset++) = coloru.mV[2];
  1068. *(rawp + offset++) = coloru.mV[3];
  1069. }
  1070. else
  1071. {
  1072. // Want non-linear curve for transparency gradient
  1073. coloru = MAX_WATER_COLOR;
  1074. const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT));
  1075. S32 alpha = 64 + llround((255-64)*frac);
  1076. alpha = llmin(llround((F32)MAX_WATER_COLOR.mV[3]), alpha);
  1077. alpha = llmax(64, alpha);
  1078. coloru.mV[3] = alpha;
  1079. *(rawp + offset++) = coloru.mV[0];
  1080. *(rawp + offset++) = coloru.mV[1];
  1081. *(rawp + offset++) = coloru.mV[2];
  1082. *(rawp + offset++) = coloru.mV[3];
  1083. }
  1084. }
  1085. }
  1086. if (!mWaterTexturep->hasGLTexture())
  1087. {
  1088. mWaterTexturep->createGLTexture(0, raw);
  1089. }
  1090. mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin);
  1091. return TRUE;
  1092. }