PageRenderTime 222ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llsurfacepatch.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1028 lines | 815 code | 136 blank | 77 comment | 131 complexity | 0d1e6b95d83b59dda20b9e9410dbbd78 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsurfacepatch.cpp
  3. * @brief LLSurfacePatch class implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&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 "llsurfacepatch.h"
  28. #include "llpatchvertexarray.h"
  29. #include "llviewerobjectlist.h"
  30. #include "llvosurfacepatch.h"
  31. #include "llsurface.h"
  32. #include "pipeline.h"
  33. #include "llagent.h"
  34. #include "timing.h"
  35. #include "llsky.h"
  36. #include "llviewercamera.h"
  37. // For getting composition values
  38. #include "llviewerregion.h"
  39. #include "llvlcomposition.h"
  40. #include "lldrawpool.h"
  41. #include "noise.h"
  42. extern U64 gFrameTime;
  43. extern LLPipeline gPipeline;
  44. LLSurfacePatch::LLSurfacePatch() :
  45. mHasReceivedData(FALSE),
  46. mSTexUpdate(FALSE),
  47. mDirty(FALSE),
  48. mDirtyZStats(TRUE),
  49. mHeightsGenerated(FALSE),
  50. mDataOffset(0),
  51. mDataZ(NULL),
  52. mDataNorm(NULL),
  53. mVObjp(NULL),
  54. mOriginRegion(0.f, 0.f, 0.f),
  55. mCenterRegion(0.f, 0.f, 0.f),
  56. mMinZ(0.f),
  57. mMaxZ(0.f),
  58. mMeanZ(0.f),
  59. mRadius(0.f),
  60. mMinComposition(0.f),
  61. mMaxComposition(0.f),
  62. mMeanComposition(0.f),
  63. // This flag is used to communicate between adjacent surfaces and is
  64. // set to non-zero values by higher classes.
  65. mConnectedEdge(NO_EDGE),
  66. mLastUpdateTime(0),
  67. mSurfacep(NULL)
  68. {
  69. S32 i;
  70. for (i = 0; i < 8; i++)
  71. {
  72. setNeighborPatch(i, NULL);
  73. }
  74. for (i = 0; i < 9; i++)
  75. {
  76. mNormalsInvalid[i] = TRUE;
  77. }
  78. }
  79. LLSurfacePatch::~LLSurfacePatch()
  80. {
  81. mVObjp = NULL;
  82. }
  83. void LLSurfacePatch::dirty()
  84. {
  85. // These are outside of the loop in case we're still waiting for a dirty from the
  86. // texture being updated...
  87. if (mVObjp)
  88. {
  89. mVObjp->dirtyGeom();
  90. }
  91. else
  92. {
  93. llwarns << "No viewer object for this surface patch!" << llendl;
  94. }
  95. mDirtyZStats = TRUE;
  96. mHeightsGenerated = FALSE;
  97. if (!mDirty)
  98. {
  99. mDirty = TRUE;
  100. mSurfacep->dirtySurfacePatch(this);
  101. }
  102. }
  103. void LLSurfacePatch::setSurface(LLSurface *surfacep)
  104. {
  105. mSurfacep = surfacep;
  106. if (mVObjp == (LLVOSurfacePatch *)NULL)
  107. {
  108. llassert(mSurfacep->mType == 'l');
  109. mVObjp = (LLVOSurfacePatch *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SURFACE_PATCH, mSurfacep->getRegion());
  110. mVObjp->setPatch(this);
  111. mVObjp->setPositionRegion(mCenterRegion);
  112. gPipeline.createObject(mVObjp);
  113. }
  114. }
  115. void LLSurfacePatch::disconnectNeighbor(LLSurface *surfacep)
  116. {
  117. U32 i;
  118. for (i = 0; i < 8; i++)
  119. {
  120. if (getNeighborPatch(i))
  121. {
  122. if (getNeighborPatch(i)->mSurfacep == surfacep)
  123. {
  124. setNeighborPatch(i, NULL);
  125. mNormalsInvalid[i] = TRUE;
  126. }
  127. }
  128. }
  129. // Clean up connected edges
  130. if (getNeighborPatch(EAST))
  131. {
  132. if (getNeighborPatch(EAST)->mSurfacep == surfacep)
  133. {
  134. mConnectedEdge &= ~EAST_EDGE;
  135. }
  136. }
  137. if (getNeighborPatch(NORTH))
  138. {
  139. if (getNeighborPatch(NORTH)->mSurfacep == surfacep)
  140. {
  141. mConnectedEdge &= ~NORTH_EDGE;
  142. }
  143. }
  144. if (getNeighborPatch(WEST))
  145. {
  146. if (getNeighborPatch(WEST)->mSurfacep == surfacep)
  147. {
  148. mConnectedEdge &= ~WEST_EDGE;
  149. }
  150. }
  151. if (getNeighborPatch(SOUTH))
  152. {
  153. if (getNeighborPatch(SOUTH)->mSurfacep == surfacep)
  154. {
  155. mConnectedEdge &= ~SOUTH_EDGE;
  156. }
  157. }
  158. }
  159. LLVector3 LLSurfacePatch::getPointAgent(const U32 x, const U32 y) const
  160. {
  161. U32 surface_stride = mSurfacep->getGridsPerEdge();
  162. U32 point_offset = x + y*surface_stride;
  163. LLVector3 pos;
  164. pos = getOriginAgent();
  165. pos.mV[VX] += x * mSurfacep->getMetersPerGrid();
  166. pos.mV[VY] += y * mSurfacep->getMetersPerGrid();
  167. pos.mV[VZ] = *(mDataZ + point_offset);
  168. return pos;
  169. }
  170. LLVector2 LLSurfacePatch::getTexCoords(const U32 x, const U32 y) const
  171. {
  172. U32 surface_stride = mSurfacep->getGridsPerEdge();
  173. U32 point_offset = x + y*surface_stride;
  174. LLVector3 pos, rel_pos;
  175. pos = getOriginAgent();
  176. pos.mV[VX] += x * mSurfacep->getMetersPerGrid();
  177. pos.mV[VY] += y * mSurfacep->getMetersPerGrid();
  178. pos.mV[VZ] = *(mDataZ + point_offset);
  179. rel_pos = pos - mSurfacep->getOriginAgent();
  180. rel_pos *= 1.f/surface_stride;
  181. return LLVector2(rel_pos.mV[VX], rel_pos.mV[VY]);
  182. }
  183. void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 *vertex, LLVector3 *normal,
  184. LLVector2 *tex0, LLVector2 *tex1)
  185. {
  186. if (!mSurfacep || !mSurfacep->getRegion() || !mSurfacep->getGridsPerEdge())
  187. {
  188. return; // failsafe
  189. }
  190. llassert_always(vertex && normal && tex0 && tex1);
  191. U32 surface_stride = mSurfacep->getGridsPerEdge();
  192. U32 point_offset = x + y*surface_stride;
  193. *normal = getNormal(x, y);
  194. LLVector3 pos_agent = getOriginAgent();
  195. pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid();
  196. pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid();
  197. pos_agent.mV[VZ] = *(mDataZ + point_offset);
  198. *vertex = pos_agent;
  199. LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
  200. LLVector3 tex_pos = rel_pos * (1.f/surface_stride);
  201. tex0->mV[0] = tex_pos.mV[0];
  202. tex0->mV[1] = tex_pos.mV[1];
  203. tex1->mV[0] = mSurfacep->getRegion()->getCompositionXY(llfloor(mOriginRegion.mV[0])+x, llfloor(mOriginRegion.mV[1])+y);
  204. const F32 xyScale = 4.9215f*7.f; //0.93284f;
  205. const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f);
  206. F32 vec[3] = {
  207. fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f),
  208. fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f),
  209. 0.f
  210. };
  211. F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f);
  212. tex1->mV[1] = rand_val;
  213. }
  214. void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride)
  215. {
  216. U32 patch_width = mSurfacep->mPVArray.mPatchWidth;
  217. U32 surface_stride = mSurfacep->getGridsPerEdge();
  218. const F32 mpg = mSurfacep->getMetersPerGrid() * stride;
  219. S32 poffsets[2][2][2];
  220. poffsets[0][0][0] = x - stride;
  221. poffsets[0][0][1] = y - stride;
  222. poffsets[0][1][0] = x - stride;
  223. poffsets[0][1][1] = y + stride;
  224. poffsets[1][0][0] = x + stride;
  225. poffsets[1][0][1] = y - stride;
  226. poffsets[1][1][0] = x + stride;
  227. poffsets[1][1][1] = y + stride;
  228. const LLSurfacePatch *ppatches[2][2];
  229. // LLVector3 p1, p2, p3, p4;
  230. ppatches[0][0] = this;
  231. ppatches[0][1] = this;
  232. ppatches[1][0] = this;
  233. ppatches[1][1] = this;
  234. U32 i, j;
  235. for (i = 0; i < 2; i++)
  236. {
  237. for (j = 0; j < 2; j++)
  238. {
  239. if (poffsets[i][j][0] < 0)
  240. {
  241. if (!ppatches[i][j]->getNeighborPatch(WEST))
  242. {
  243. poffsets[i][j][0] = 0;
  244. }
  245. else
  246. {
  247. poffsets[i][j][0] += patch_width;
  248. ppatches[i][j] = ppatches[i][j]->getNeighborPatch(WEST);
  249. }
  250. }
  251. if (poffsets[i][j][1] < 0)
  252. {
  253. if (!ppatches[i][j]->getNeighborPatch(SOUTH))
  254. {
  255. poffsets[i][j][1] = 0;
  256. }
  257. else
  258. {
  259. poffsets[i][j][1] += patch_width;
  260. ppatches[i][j] = ppatches[i][j]->getNeighborPatch(SOUTH);
  261. }
  262. }
  263. if (poffsets[i][j][0] >= (S32)patch_width)
  264. {
  265. if (!ppatches[i][j]->getNeighborPatch(EAST))
  266. {
  267. poffsets[i][j][0] = patch_width - 1;
  268. }
  269. else
  270. {
  271. poffsets[i][j][0] -= patch_width;
  272. ppatches[i][j] = ppatches[i][j]->getNeighborPatch(EAST);
  273. }
  274. }
  275. if (poffsets[i][j][1] >= (S32)patch_width)
  276. {
  277. if (!ppatches[i][j]->getNeighborPatch(NORTH))
  278. {
  279. poffsets[i][j][1] = patch_width - 1;
  280. }
  281. else
  282. {
  283. poffsets[i][j][1] -= patch_width;
  284. ppatches[i][j] = ppatches[i][j]->getNeighborPatch(NORTH);
  285. }
  286. }
  287. }
  288. }
  289. LLVector3 p00(-mpg,-mpg,
  290. *(ppatches[0][0]->mDataZ
  291. + poffsets[0][0][0]
  292. + poffsets[0][0][1]*surface_stride));
  293. LLVector3 p01(-mpg,+mpg,
  294. *(ppatches[0][1]->mDataZ
  295. + poffsets[0][1][0]
  296. + poffsets[0][1][1]*surface_stride));
  297. LLVector3 p10(+mpg,-mpg,
  298. *(ppatches[1][0]->mDataZ
  299. + poffsets[1][0][0]
  300. + poffsets[1][0][1]*surface_stride));
  301. LLVector3 p11(+mpg,+mpg,
  302. *(ppatches[1][1]->mDataZ
  303. + poffsets[1][1][0]
  304. + poffsets[1][1][1]*surface_stride));
  305. LLVector3 c1 = p11 - p00;
  306. LLVector3 c2 = p01 - p10;
  307. LLVector3 normal = c1;
  308. normal %= c2;
  309. normal.normVec();
  310. llassert(mDataNorm);
  311. *(mDataNorm + surface_stride * y + x) = normal;
  312. }
  313. const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const
  314. {
  315. U32 surface_stride = mSurfacep->getGridsPerEdge();
  316. llassert(mDataNorm);
  317. return *(mDataNorm + surface_stride * y + x);
  318. }
  319. void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region)
  320. {
  321. if (LLPipeline::sDynamicLOD)
  322. {
  323. LLVector3 dv = pos_region;
  324. dv -= mCenterRegion;
  325. mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
  326. llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
  327. }
  328. else
  329. {
  330. mVisInfo.mDistance = 0.f;
  331. }
  332. }
  333. F32 LLSurfacePatch::getDistance() const
  334. {
  335. return mVisInfo.mDistance;
  336. }
  337. // Called when a patch has changed its height field
  338. // data.
  339. void LLSurfacePatch::updateVerticalStats()
  340. {
  341. if (!mDirtyZStats)
  342. {
  343. return;
  344. }
  345. U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
  346. U32 grids_per_edge = mSurfacep->getGridsPerEdge();
  347. F32 meters_per_grid = mSurfacep->getMetersPerGrid();
  348. U32 i, j, k;
  349. F32 z, total;
  350. llassert(mDataZ);
  351. z = *(mDataZ);
  352. mMinZ = z;
  353. mMaxZ = z;
  354. k = 0;
  355. total = 0.0f;
  356. // Iterate to +1 because we need to do the edges correctly.
  357. for (j=0; j<(grids_per_patch_edge+1); j++)
  358. {
  359. for (i=0; i<(grids_per_patch_edge+1); i++)
  360. {
  361. z = *(mDataZ + i + j*grids_per_edge);
  362. if (z < mMinZ)
  363. {
  364. mMinZ = z;
  365. }
  366. if (z > mMaxZ)
  367. {
  368. mMaxZ = z;
  369. }
  370. total += z;
  371. k++;
  372. }
  373. }
  374. mMeanZ = total / (F32) k;
  375. mCenterRegion.mV[VZ] = 0.5f * (mMinZ + mMaxZ);
  376. LLVector3 diam_vec(meters_per_grid*grids_per_patch_edge,
  377. meters_per_grid*grids_per_patch_edge,
  378. mMaxZ - mMinZ);
  379. mRadius = diam_vec.magVec() * 0.5f;
  380. mSurfacep->mMaxZ = llmax(mMaxZ, mSurfacep->mMaxZ);
  381. mSurfacep->mMinZ = llmin(mMinZ, mSurfacep->mMinZ);
  382. mSurfacep->mHasZData = TRUE;
  383. mSurfacep->getRegion()->calculateCenterGlobal();
  384. if (mVObjp)
  385. {
  386. mVObjp->dirtyPatch();
  387. }
  388. mDirtyZStats = FALSE;
  389. }
  390. void LLSurfacePatch::updateNormals()
  391. {
  392. if (mSurfacep->mType == 'w')
  393. {
  394. return;
  395. }
  396. U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
  397. U32 grids_per_edge = mSurfacep->getGridsPerEdge();
  398. BOOL dirty_patch = FALSE;
  399. U32 i, j;
  400. // update the east edge
  401. if (mNormalsInvalid[EAST] || mNormalsInvalid[NORTHEAST] || mNormalsInvalid[SOUTHEAST])
  402. {
  403. for (j = 0; j <= grids_per_patch_edge; j++)
  404. {
  405. calcNormal(grids_per_patch_edge, j, 2);
  406. calcNormal(grids_per_patch_edge - 1, j, 2);
  407. calcNormal(grids_per_patch_edge - 2, j, 2);
  408. }
  409. dirty_patch = TRUE;
  410. }
  411. // update the north edge
  412. if (mNormalsInvalid[NORTHEAST] || mNormalsInvalid[NORTH] || mNormalsInvalid[NORTHWEST])
  413. {
  414. for (i = 0; i <= grids_per_patch_edge; i++)
  415. {
  416. calcNormal(i, grids_per_patch_edge, 2);
  417. calcNormal(i, grids_per_patch_edge - 1, 2);
  418. calcNormal(i, grids_per_patch_edge - 2, 2);
  419. }
  420. dirty_patch = TRUE;
  421. }
  422. // update the west edge
  423. if (mNormalsInvalid[NORTHWEST] || mNormalsInvalid[WEST] || mNormalsInvalid[SOUTHWEST])
  424. {
  425. for (j = 0; j < grids_per_patch_edge; j++)
  426. {
  427. calcNormal(0, j, 2);
  428. calcNormal(1, j, 2);
  429. }
  430. dirty_patch = TRUE;
  431. }
  432. // update the south edge
  433. if (mNormalsInvalid[SOUTHWEST] || mNormalsInvalid[SOUTH] || mNormalsInvalid[SOUTHEAST])
  434. {
  435. for (i = 0; i < grids_per_patch_edge; i++)
  436. {
  437. calcNormal(i, 0, 2);
  438. calcNormal(i, 1, 2);
  439. }
  440. dirty_patch = TRUE;
  441. }
  442. // Invalidating the northeast corner is different, because depending on what the adjacent neighbors are,
  443. // we'll want to do different things.
  444. if (mNormalsInvalid[NORTHEAST])
  445. {
  446. if (!getNeighborPatch(NORTHEAST))
  447. {
  448. if (!getNeighborPatch(NORTH))
  449. {
  450. if (!getNeighborPatch(EAST))
  451. {
  452. // No north or east neighbors. Pull from the diagonal in your own patch.
  453. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  454. *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
  455. }
  456. else
  457. {
  458. if (getNeighborPatch(EAST)->getHasReceivedData())
  459. {
  460. // East, but not north. Pull from your east neighbor's northwest point.
  461. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  462. *(getNeighborPatch(EAST)->mDataZ + (grids_per_patch_edge - 1)*grids_per_edge);
  463. }
  464. else
  465. {
  466. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  467. *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
  468. }
  469. }
  470. }
  471. else
  472. {
  473. // We have a north.
  474. if (getNeighborPatch(EAST))
  475. {
  476. // North and east neighbors, but not northeast.
  477. // Pull from diagonal in your own patch.
  478. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  479. *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
  480. }
  481. else
  482. {
  483. if (getNeighborPatch(NORTH)->getHasReceivedData())
  484. {
  485. // North, but not east. Pull from your north neighbor's southeast corner.
  486. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  487. *(getNeighborPatch(NORTH)->mDataZ + (grids_per_patch_edge - 1));
  488. }
  489. else
  490. {
  491. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  492. *(mDataZ + grids_per_patch_edge - 1 + (grids_per_patch_edge - 1)*grids_per_edge);
  493. }
  494. }
  495. }
  496. }
  497. else if (getNeighborPatch(NORTHEAST)->mSurfacep != mSurfacep)
  498. {
  499. if (
  500. (!getNeighborPatch(NORTH) || (getNeighborPatch(NORTH)->mSurfacep != mSurfacep))
  501. &&
  502. (!getNeighborPatch(EAST) || (getNeighborPatch(EAST)->mSurfacep != mSurfacep)))
  503. {
  504. *(mDataZ + grids_per_patch_edge + grids_per_patch_edge*grids_per_edge) =
  505. *(getNeighborPatch(NORTHEAST)->mDataZ);
  506. }
  507. }
  508. else
  509. {
  510. // We've got a northeast patch in the same surface.
  511. // The z and normals will be handled by that patch.
  512. }
  513. calcNormal(grids_per_patch_edge, grids_per_patch_edge, 2);
  514. calcNormal(grids_per_patch_edge, grids_per_patch_edge - 1, 2);
  515. calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge, 2);
  516. calcNormal(grids_per_patch_edge - 1, grids_per_patch_edge - 1, 2);
  517. dirty_patch = TRUE;
  518. }
  519. // update the middle normals
  520. if (mNormalsInvalid[MIDDLE])
  521. {
  522. for (j=2; j < grids_per_patch_edge - 2; j++)
  523. {
  524. for (i=2; i < grids_per_patch_edge - 2; i++)
  525. {
  526. calcNormal(i, j, 2);
  527. }
  528. }
  529. dirty_patch = TRUE;
  530. }
  531. if (dirty_patch)
  532. {
  533. mSurfacep->dirtySurfacePatch(this);
  534. }
  535. for (i = 0; i < 9; i++)
  536. {
  537. mNormalsInvalid[i] = FALSE;
  538. }
  539. }
  540. void LLSurfacePatch::updateEastEdge()
  541. {
  542. U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
  543. U32 grids_per_edge = mSurfacep->getGridsPerEdge();
  544. U32 j, k;
  545. F32 *west_surface, *east_surface;
  546. if (!getNeighborPatch(EAST))
  547. {
  548. west_surface = mDataZ + grids_per_patch_edge;
  549. east_surface = mDataZ + grids_per_patch_edge - 1;
  550. }
  551. else if (mConnectedEdge & EAST_EDGE)
  552. {
  553. west_surface = mDataZ + grids_per_patch_edge;
  554. east_surface = getNeighborPatch(EAST)->mDataZ;
  555. }
  556. else
  557. {
  558. return;
  559. }
  560. // If patchp is on the east edge of its surface, then we update the east
  561. // side buffer
  562. for (j=0; j < grids_per_patch_edge; j++)
  563. {
  564. k = j * grids_per_edge;
  565. *(west_surface + k) = *(east_surface + k); // update buffer Z
  566. }
  567. }
  568. void LLSurfacePatch::updateNorthEdge()
  569. {
  570. U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
  571. U32 grids_per_edge = mSurfacep->getGridsPerEdge();
  572. U32 i;
  573. F32 *south_surface, *north_surface;
  574. if (!getNeighborPatch(NORTH))
  575. {
  576. south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
  577. north_surface = mDataZ + (grids_per_patch_edge - 1) * grids_per_edge;
  578. }
  579. else if (mConnectedEdge & NORTH_EDGE)
  580. {
  581. south_surface = mDataZ + grids_per_patch_edge*grids_per_edge;
  582. north_surface = getNeighborPatch(NORTH)->mDataZ;
  583. }
  584. else
  585. {
  586. return;
  587. }
  588. // Update patchp's north edge ...
  589. for (i=0; i<grids_per_patch_edge; i++)
  590. {
  591. *(south_surface + i) = *(north_surface + i); // update buffer Z
  592. }
  593. }
  594. BOOL LLSurfacePatch::updateTexture()
  595. {
  596. if (mSTexUpdate) // Update texture as needed
  597. {
  598. F32 meters_per_grid = getSurface()->getMetersPerGrid();
  599. F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
  600. if ((!getNeighborPatch(EAST) || getNeighborPatch(EAST)->getHasReceivedData())
  601. && (!getNeighborPatch(WEST) || getNeighborPatch(WEST)->getHasReceivedData())
  602. && (!getNeighborPatch(SOUTH) || getNeighborPatch(SOUTH)->getHasReceivedData())
  603. && (!getNeighborPatch(NORTH) || getNeighborPatch(NORTH)->getHasReceivedData()))
  604. {
  605. LLViewerRegion *regionp = getSurface()->getRegion();
  606. LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
  607. // Have to figure out a better way to deal with these edge conditions...
  608. LLVLComposition* comp = regionp->getComposition();
  609. if (!mHeightsGenerated)
  610. {
  611. F32 patch_size = meters_per_grid*(grids_per_patch_edge+1);
  612. if (comp->generateHeights((F32)origin_region[VX], (F32)origin_region[VY],
  613. patch_size, patch_size))
  614. {
  615. mHeightsGenerated = TRUE;
  616. }
  617. else
  618. {
  619. return FALSE;
  620. }
  621. }
  622. if (comp->generateComposition())
  623. {
  624. if (mVObjp)
  625. {
  626. mVObjp->dirtyGeom();
  627. gPipeline.markGLRebuild(mVObjp);
  628. return TRUE;
  629. }
  630. }
  631. }
  632. return FALSE;
  633. }
  634. else
  635. {
  636. return TRUE;
  637. }
  638. }
  639. void LLSurfacePatch::updateGL()
  640. {
  641. F32 meters_per_grid = getSurface()->getMetersPerGrid();
  642. F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge();
  643. LLViewerRegion *regionp = getSurface()->getRegion();
  644. LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal();
  645. LLVLComposition* comp = regionp->getComposition();
  646. updateCompositionStats();
  647. F32 tex_patch_size = meters_per_grid*grids_per_patch_edge;
  648. if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY],
  649. tex_patch_size, tex_patch_size))
  650. {
  651. mSTexUpdate = FALSE;
  652. // Also generate the water texture
  653. mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY],
  654. tex_patch_size, tex_patch_size);
  655. }
  656. }
  657. void LLSurfacePatch::dirtyZ()
  658. {
  659. mSTexUpdate = TRUE;
  660. // Invalidate all normals in this patch
  661. U32 i;
  662. for (i = 0; i < 9; i++)
  663. {
  664. mNormalsInvalid[i] = TRUE;
  665. }
  666. // Invalidate normals in this and neighboring patches
  667. for (i = 0; i < 8; i++)
  668. {
  669. if (getNeighborPatch(i))
  670. {
  671. getNeighborPatch(i)->mNormalsInvalid[gDirOpposite[i]] = TRUE;
  672. getNeighborPatch(i)->dirty();
  673. if (i < 4)
  674. {
  675. getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][0]] = TRUE;
  676. getNeighborPatch(i)->mNormalsInvalid[gDirAdjacent[gDirOpposite[i]][1]] = TRUE;
  677. }
  678. }
  679. }
  680. dirty();
  681. mLastUpdateTime = gFrameTime;
  682. }
  683. const U64 &LLSurfacePatch::getLastUpdateTime() const
  684. {
  685. return mLastUpdateTime;
  686. }
  687. F32 LLSurfacePatch::getMaxZ() const
  688. {
  689. return mMaxZ;
  690. }
  691. F32 LLSurfacePatch::getMinZ() const
  692. {
  693. return mMinZ;
  694. }
  695. void LLSurfacePatch::setOriginGlobal(const LLVector3d &origin_global)
  696. {
  697. mOriginGlobal = origin_global;
  698. LLVector3 origin_region;
  699. origin_region.setVec(mOriginGlobal - mSurfacep->getOriginGlobal());
  700. mOriginRegion = origin_region;
  701. mCenterRegion.mV[VX] = origin_region.mV[VX] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
  702. mCenterRegion.mV[VY] = origin_region.mV[VY] + 0.5f*mSurfacep->getGridsPerPatchEdge()*mSurfacep->getMetersPerGrid();
  703. mVisInfo.mbIsVisible = FALSE;
  704. mVisInfo.mDistance = 512.0f;
  705. mVisInfo.mRenderLevel = 0;
  706. mVisInfo.mRenderStride = mSurfacep->getGridsPerPatchEdge();
  707. }
  708. void LLSurfacePatch::connectNeighbor(LLSurfacePatch *neighbor_patchp, const U32 direction)
  709. {
  710. llassert(neighbor_patchp);
  711. mNormalsInvalid[direction] = TRUE;
  712. neighbor_patchp->mNormalsInvalid[gDirOpposite[direction]] = TRUE;
  713. setNeighborPatch(direction, neighbor_patchp);
  714. neighbor_patchp->setNeighborPatch(gDirOpposite[direction], this);
  715. if (EAST == direction)
  716. {
  717. mConnectedEdge |= EAST_EDGE;
  718. neighbor_patchp->mConnectedEdge |= WEST_EDGE;
  719. }
  720. else if (NORTH == direction)
  721. {
  722. mConnectedEdge |= NORTH_EDGE;
  723. neighbor_patchp->mConnectedEdge |= SOUTH_EDGE;
  724. }
  725. else if (WEST == direction)
  726. {
  727. mConnectedEdge |= WEST_EDGE;
  728. neighbor_patchp->mConnectedEdge |= EAST_EDGE;
  729. }
  730. else if (SOUTH == direction)
  731. {
  732. mConnectedEdge |= SOUTH_EDGE;
  733. neighbor_patchp->mConnectedEdge |= NORTH_EDGE;
  734. }
  735. }
  736. void LLSurfacePatch::updateVisibility()
  737. {
  738. if (mVObjp.isNull())
  739. {
  740. return;
  741. }
  742. const F32 DEFAULT_DELTA_ANGLE = (0.15f);
  743. U32 old_render_stride, max_render_stride;
  744. U32 new_render_level;
  745. F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid();
  746. U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge();
  747. LLVector4a center;
  748. center.load3( (mCenterRegion + mSurfacep->getOriginAgent()).mV);
  749. LLVector4a radius;
  750. radius.splat(mRadius);
  751. // sphere in frustum on global coordinates
  752. if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, radius))
  753. {
  754. // We now need to calculate the render stride based on patchp's distance
  755. // from LLCamera render_stride is governed by a relation something like this...
  756. //
  757. // delta_angle * patch.distance
  758. // render_stride <= ----------------------------------------
  759. // mMetersPerGrid
  760. //
  761. // where 'delta_angle' is the desired solid angle of the average polgon on a patch.
  762. //
  763. // Any render_stride smaller than the RHS would be 'satisfactory'. Smaller
  764. // strides give more resolution, but efficiency suggests that we use the largest
  765. // of the render_strides that obey the relation. Flexibility is achieved by
  766. // modulating 'delta_angle' until we have an acceptable number of triangles.
  767. old_render_stride = mVisInfo.mRenderStride;
  768. // Calculate the render_stride using information in agent
  769. max_render_stride = lltrunc(mVisInfo.mDistance * stride_per_distance);
  770. max_render_stride = llmin(max_render_stride , 2*grids_per_patch_edge);
  771. // We only use render_strides that are powers of two, so we use look-up tables to figure out
  772. // the render_level and corresponding render_stride
  773. new_render_level = mVisInfo.mRenderLevel = mSurfacep->getRenderLevel(max_render_stride);
  774. mVisInfo.mRenderStride = mSurfacep->getRenderStride(new_render_level);
  775. if ((mVisInfo.mRenderStride != old_render_stride))
  776. // The reason we check !mbIsVisible is because non-visible patches normals
  777. // are not updated when their data is changed. When this changes we can get
  778. // rid of mbIsVisible altogether.
  779. {
  780. if (mVObjp)
  781. {
  782. mVObjp->dirtyGeom();
  783. if (getNeighborPatch(WEST))
  784. {
  785. getNeighborPatch(WEST)->mVObjp->dirtyGeom();
  786. }
  787. if (getNeighborPatch(SOUTH))
  788. {
  789. getNeighborPatch(SOUTH)->mVObjp->dirtyGeom();
  790. }
  791. }
  792. }
  793. mVisInfo.mbIsVisible = TRUE;
  794. }
  795. else
  796. {
  797. mVisInfo.mbIsVisible = FALSE;
  798. }
  799. }
  800. const LLVector3d &LLSurfacePatch::getOriginGlobal() const
  801. {
  802. return mOriginGlobal;
  803. }
  804. LLVector3 LLSurfacePatch::getOriginAgent() const
  805. {
  806. return gAgent.getPosAgentFromGlobal(mOriginGlobal);
  807. }
  808. BOOL LLSurfacePatch::getVisible() const
  809. {
  810. return mVisInfo.mbIsVisible;
  811. }
  812. U32 LLSurfacePatch::getRenderStride() const
  813. {
  814. return mVisInfo.mRenderStride;
  815. }
  816. S32 LLSurfacePatch::getRenderLevel() const
  817. {
  818. return mVisInfo.mRenderLevel;
  819. }
  820. void LLSurfacePatch::setHasReceivedData()
  821. {
  822. mHasReceivedData = TRUE;
  823. }
  824. BOOL LLSurfacePatch::getHasReceivedData() const
  825. {
  826. return mHasReceivedData;
  827. }
  828. const LLVector3 &LLSurfacePatch::getCenterRegion() const
  829. {
  830. return mCenterRegion;
  831. }
  832. void LLSurfacePatch::updateCompositionStats()
  833. {
  834. LLViewerLayer *vlp = mSurfacep->getRegion()->getComposition();
  835. F32 x, y, width, height, mpg, min, mean, max;
  836. LLVector3 origin = getOriginAgent() - mSurfacep->getOriginAgent();
  837. mpg = mSurfacep->getMetersPerGrid();
  838. x = origin.mV[VX];
  839. y = origin.mV[VY];
  840. width = mpg*(mSurfacep->getGridsPerPatchEdge()+1);
  841. height = mpg*(mSurfacep->getGridsPerPatchEdge()+1);
  842. mean = 0.f;
  843. min = vlp->getValueScaled(x, y);
  844. max= min;
  845. U32 count = 0;
  846. F32 i, j;
  847. for (j = 0; j < height; j += mpg)
  848. {
  849. for (i = 0; i < width; i += mpg)
  850. {
  851. F32 comp = vlp->getValueScaled(x + i, y + j);
  852. mean += comp;
  853. min = llmin(min, comp);
  854. max = llmax(max, comp);
  855. count++;
  856. }
  857. }
  858. mean /= count;
  859. mMinComposition = min;
  860. mMeanComposition = mean;
  861. mMaxComposition = max;
  862. }
  863. F32 LLSurfacePatch::getMeanComposition() const
  864. {
  865. return mMeanComposition;
  866. }
  867. F32 LLSurfacePatch::getMinComposition() const
  868. {
  869. return mMinComposition;
  870. }
  871. F32 LLSurfacePatch::getMaxComposition() const
  872. {
  873. return mMaxComposition;
  874. }
  875. void LLSurfacePatch::setNeighborPatch(const U32 direction, LLSurfacePatch *neighborp)
  876. {
  877. mNeighborPatches[direction] = neighborp;
  878. mNormalsInvalid[direction] = TRUE;
  879. if (direction < 4)
  880. {
  881. mNormalsInvalid[gDirAdjacent[direction][0]] = TRUE;
  882. mNormalsInvalid[gDirAdjacent[direction][1]] = TRUE;
  883. }
  884. }
  885. LLSurfacePatch *LLSurfacePatch::getNeighborPatch(const U32 direction) const
  886. {
  887. return mNeighborPatches[direction];
  888. }
  889. void LLSurfacePatch::clearVObj()
  890. {
  891. mVObjp = NULL;
  892. }