llsurface.cpp 35 KB

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