llsurface.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:31k
源码类别:

游戏引擎

开发平台:

C++ Builder

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