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

游戏引擎

开发平台:

C++ Builder

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