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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llvosurfacepatch.cpp
  3.  * @brief Viewer-object derived "surface patch", which is a piece of terrain
  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 "llvosurfacepatch.h"
  34. #include "lldrawpoolterrain.h"
  35. #include "lldrawable.h"
  36. #include "llface.h"
  37. #include "llprimitive.h"
  38. #include "llsky.h"
  39. #include "llsurfacepatch.h"
  40. #include "llsurface.h"
  41. #include "llviewerobjectlist.h"
  42. #include "llviewerregion.h"
  43. #include "llvlcomposition.h"
  44. #include "llvovolume.h"
  45. #include "pipeline.h"
  46. #include "llspatialpartition.h"
  47. F32 LLVOSurfacePatch::sLODFactor = 1.f;
  48. //============================================================================
  49. class LLVertexBufferTerrain : public LLVertexBuffer
  50. {
  51. public:
  52. LLVertexBufferTerrain() :
  53. LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW_ARB)
  54. {
  55. //texture coordinates 2 and 3 exist, but use the same data as texture coordinate 1
  56. mOffsets[TYPE_TEXCOORD3] = mOffsets[TYPE_TEXCOORD2] = mOffsets[TYPE_TEXCOORD1];
  57. mTypeMask |= MAP_TEXCOORD2 | MAP_TEXCOORD3;
  58. };
  59. /*// virtual
  60. void setupVertexBuffer(U32 data_mask) const
  61. {
  62. if (LLDrawPoolTerrain::getDetailMode() == 0 || LLPipeline::sShadowRender)
  63. {
  64. LLVertexBuffer::setupVertexBuffer(data_mask);
  65. }
  66. else if (data_mask & LLVertexBuffer::MAP_TEXCOORD1)
  67. {
  68. LLVertexBuffer::setupVertexBuffer(data_mask);
  69. }
  70. else
  71. {
  72. LLVertexBuffer::setupVertexBuffer(data_mask);
  73. }
  74. llglassertok();
  75. }*/
  76. };
  77. //============================================================================
  78. LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  79. : LLStaticViewerObject(id, LL_VO_SURFACE_PATCH, regionp),
  80. mDirtiedPatch(FALSE),
  81. mPool(NULL),
  82. mBaseComp(0),
  83. mPatchp(NULL),
  84. mDirtyTexture(FALSE),
  85. mDirtyTerrain(FALSE),
  86. mLastNorthStride(0),
  87. mLastEastStride(0),
  88. mLastStride(0),
  89. mLastLength(0)
  90. {
  91. // Terrain must draw during selection passes so it can block objects behind it.
  92. mbCanSelect = TRUE;
  93. setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility.
  94. }
  95. LLVOSurfacePatch::~LLVOSurfacePatch()
  96. {
  97. mPatchp = NULL;
  98. }
  99. void LLVOSurfacePatch::markDead()
  100. {
  101. if (mPatchp)
  102. {
  103. mPatchp->clearVObj();
  104. mPatchp = NULL;
  105. }
  106. LLViewerObject::markDead();
  107. }
  108. BOOL LLVOSurfacePatch::isActive() const
  109. {
  110. return FALSE;
  111. }
  112. void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent)
  113. {
  114. mAppAngle = 50;
  115. mPixelArea = 500*500;
  116. }
  117. void LLVOSurfacePatch::updateTextures()
  118. {
  119. }
  120. LLFacePool *LLVOSurfacePatch::getPool()
  121. {
  122. mPool = (LLDrawPoolTerrain*) gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture());
  123. return mPool;
  124. }
  125. LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline)
  126. {
  127. pipeline->allocDrawable(this);
  128. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN);
  129. mBaseComp = llfloor(mPatchp->getMinComposition());
  130. S32 min_comp, max_comp, range;
  131. min_comp = llfloor(mPatchp->getMinComposition());
  132. max_comp = llceil(mPatchp->getMaxComposition());
  133. range = (max_comp - min_comp);
  134. range++;
  135. if (range > 3)
  136. {
  137. if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
  138. {
  139. // The top side runs over more
  140. mBaseComp++;
  141. }
  142. range = 3;
  143. }
  144. LLFacePool *poolp = getPool();
  145. mDrawable->addFace(poolp, NULL);
  146. return mDrawable;
  147. }
  148. static LLFastTimer::DeclareTimer FTM_UPDATE_TERRAIN("Update Terrain");
  149. void LLVOSurfacePatch::updateGL()
  150. {
  151. if (mPatchp)
  152. {
  153. mPatchp->updateGL();
  154. }
  155. }
  156. BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
  157. {
  158. LLFastTimer ftm(FTM_UPDATE_TERRAIN);
  159. dirtySpatialGroup(TRUE);
  160. S32 min_comp, max_comp, range;
  161. min_comp = lltrunc(mPatchp->getMinComposition());
  162. max_comp = lltrunc(ceil(mPatchp->getMaxComposition()));
  163. range = (max_comp - min_comp);
  164. range++;
  165. S32 new_base_comp = lltrunc(mPatchp->getMinComposition());
  166. if (range > 3)
  167. {
  168. if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
  169. {
  170. // The top side runs over more
  171. new_base_comp++;
  172. }
  173. range = 3;
  174. }
  175. // Pick the two closest detail textures for this patch...
  176. // Then create the draw pool for it.
  177. // Actually, should get the average composition instead of the center.
  178. mBaseComp = new_base_comp;
  179. //////////////////////////
  180. //
  181. // Figure out the strides
  182. //
  183. //
  184. U32 patch_width, render_stride, north_stride, east_stride, length;
  185. render_stride = mPatchp->getRenderStride();
  186. patch_width = mPatchp->getSurface()->getGridsPerPatchEdge();
  187. length = patch_width / render_stride;
  188. if (mPatchp->getNeighborPatch(NORTH))
  189. {
  190. north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride();
  191. }
  192. else
  193. {
  194. north_stride = render_stride;
  195. }
  196. if (mPatchp->getNeighborPatch(EAST))
  197. {
  198. east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride();
  199. }
  200. else
  201. {
  202. east_stride = render_stride;
  203. }
  204. mLastLength = length;
  205. mLastStride = render_stride;
  206. mLastNorthStride = north_stride;
  207. mLastEastStride = east_stride;
  208. return TRUE;
  209. }
  210. void LLVOSurfacePatch::updateFaceSize(S32 idx)
  211. {
  212. if (idx != 0)
  213. {
  214. llwarns << "Terrain partition requested invalid face!!!" << llendl;
  215. return;
  216. }
  217. LLFace* facep = mDrawable->getFace(idx);
  218. S32 num_vertices = 0;
  219. S32 num_indices = 0;
  220. if (mLastStride)
  221. {
  222. getGeomSizesMain(mLastStride, num_vertices, num_indices);
  223. getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
  224. getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
  225. }
  226. facep->setSize(num_vertices, num_indices);
  227. }
  228. BOOL LLVOSurfacePatch::updateLOD()
  229. {
  230. return TRUE;
  231. }
  232. void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
  233. LLStrider<LLVector3> &normalsp,
  234. LLStrider<LLColor4U> &colorsp,
  235. LLStrider<LLVector2> &texCoords0p,
  236. LLStrider<LLVector2> &texCoords1p,
  237. LLStrider<U16> &indicesp)
  238. {
  239. LLFace* facep = mDrawable->getFace(0);
  240. U32 index_offset = facep->getGeomIndex();
  241. updateMainGeometry(facep, 
  242. verticesp,
  243. normalsp,
  244. colorsp,
  245. texCoords0p,
  246. texCoords1p,
  247. indicesp,
  248. index_offset);
  249. updateNorthGeometry(facep, 
  250. verticesp,
  251. normalsp,
  252. colorsp,
  253. texCoords0p,
  254. texCoords1p,
  255. indicesp,
  256. index_offset);
  257. updateEastGeometry(facep, 
  258. verticesp,
  259. normalsp,
  260. colorsp,
  261. texCoords0p,
  262. texCoords1p,
  263. indicesp,
  264. index_offset);
  265. }
  266. void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
  267. LLStrider<LLVector3> &verticesp,
  268. LLStrider<LLVector3> &normalsp,
  269. LLStrider<LLColor4U> &colorsp,
  270. LLStrider<LLVector2> &texCoords0p,
  271. LLStrider<LLVector2> &texCoords1p,
  272. LLStrider<U16> &indicesp,
  273. U32 &index_offset)
  274. {
  275. S32 i, j, x, y;
  276. U32 patch_size, render_stride;
  277. S32 num_vertices, num_indices;
  278. U32 index;
  279. render_stride = mLastStride;
  280. patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
  281. S32 vert_size = patch_size / render_stride;
  282. ///////////////////////////
  283. //
  284. // Render the main patch
  285. //
  286. //
  287. num_vertices = 0;
  288. num_indices = 0;
  289. // First, figure out how many vertices we need...
  290. getGeomSizesMain(render_stride, num_vertices, num_indices);
  291. if (num_vertices > 0)
  292. {
  293. facep->mCenterAgent = mPatchp->getPointAgent(8, 8);
  294. // Generate patch points first
  295. for (j = 0; j < vert_size; j++)
  296. {
  297. for (i = 0; i < vert_size; i++)
  298. {
  299. x = i * render_stride;
  300. y = j * render_stride;
  301. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  302. *colorsp++ = LLColor4U::white;
  303. verticesp++;
  304. normalsp++;
  305. texCoords0p++;
  306. texCoords1p++;
  307. }
  308. }
  309. for (j = 0; j < (vert_size - 1); j++)
  310. {
  311. if (j % 2)
  312. {
  313. for (i = (vert_size - 1); i > 0; i--)
  314. {
  315. index = (i - 1)+ j*vert_size;
  316. *(indicesp++) = index_offset + index;
  317. index = i + (j+1)*vert_size;
  318. *(indicesp++) = index_offset + index;
  319. index = (i - 1) + (j+1)*vert_size;
  320. *(indicesp++) = index_offset + index;
  321. index = (i - 1) + j*vert_size;
  322. *(indicesp++) = index_offset + index;
  323. index = i + j*vert_size;
  324. *(indicesp++) = index_offset + index;
  325. index = i + (j+1)*vert_size;
  326. *(indicesp++) = index_offset + index;
  327. }
  328. }
  329. else
  330. {
  331. for (i = 0; i < (vert_size - 1); i++)
  332. {
  333. index = i + j*vert_size;
  334. *(indicesp++) = index_offset + index;
  335. index = (i + 1) + (j+1)*vert_size;
  336. *(indicesp++) = index_offset + index;
  337. index = i + (j+1)*vert_size;
  338. *(indicesp++) = index_offset + index;
  339. index = i + j*vert_size;
  340. *(indicesp++) = index_offset + index;
  341. index = (i + 1) + j*vert_size;
  342. *(indicesp++) = index_offset + index;
  343. index = (i + 1) + (j + 1)*vert_size;
  344. *(indicesp++) = index_offset + index;
  345. }
  346. }
  347. }
  348. }
  349. index_offset += num_vertices;
  350. }
  351. void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
  352. LLStrider<LLVector3> &verticesp,
  353. LLStrider<LLVector3> &normalsp,
  354. LLStrider<LLColor4U> &colorsp,
  355. LLStrider<LLVector2> &texCoords0p,
  356. LLStrider<LLVector2> &texCoords1p,
  357. LLStrider<U16> &indicesp,
  358. U32 &index_offset)
  359. {
  360. S32 vertex_count = 0;
  361. S32 i, x, y;
  362. S32 num_vertices, num_indices;
  363. U32 render_stride = mLastStride;
  364. S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
  365. S32 length = patch_size / render_stride;
  366. S32 half_length = length / 2;
  367. U32 north_stride = mLastNorthStride;
  368. ///////////////////////////
  369. //
  370. // Render the north strip
  371. //
  372. //
  373. // Stride lengths are the same
  374. if (north_stride == render_stride)
  375. {
  376. num_vertices = 2 * length + 1;
  377. num_indices = length * 6 - 3;
  378. facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
  379. // Main patch
  380. for (i = 0; i < length; i++)
  381. {
  382. x = i * render_stride;
  383. y = 16 - render_stride;
  384. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  385. *colorsp++ = LLColor4U::white;
  386. verticesp++;
  387. normalsp++;
  388. texCoords0p++;
  389. texCoords1p++;
  390. vertex_count++;
  391. }
  392. // North patch
  393. for (i = 0; i <= length; i++)
  394. {
  395. x = i * render_stride;
  396. y = 16;
  397. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  398. verticesp++;
  399. normalsp++;
  400. *colorsp++ = LLColor4U::white;
  401. texCoords0p++;
  402. texCoords1p++;
  403. vertex_count++;
  404. }
  405. for (i = 0; i < length; i++)
  406. {
  407. // Generate indices
  408. *(indicesp++) = index_offset + i;
  409. *(indicesp++) = index_offset + length + i + 1;
  410. *(indicesp++) = index_offset + length + i;
  411. if (i != length - 1)
  412. {
  413. *(indicesp++) = index_offset + i;
  414. *(indicesp++) = index_offset + i + 1;
  415. *(indicesp++) = index_offset + length + i + 1;
  416. }
  417. }
  418. }
  419. else if (north_stride > render_stride)
  420. {
  421. // North stride is longer (has less vertices)
  422. num_vertices = length + length/2 + 1;
  423. num_indices = half_length*9 - 3;
  424. facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
  425. // Iterate through this patch's points
  426. for (i = 0; i < length; i++)
  427. {
  428. x = i * render_stride;
  429. y = 16 - render_stride;
  430. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  431. verticesp++;
  432. normalsp++;
  433. *colorsp++ = LLColor4U::white;
  434. texCoords0p++;
  435. texCoords1p++;
  436. vertex_count++;
  437. }
  438. // Iterate through the north patch's points
  439. for (i = 0; i <= length; i+=2)
  440. {
  441. x = i * render_stride;
  442. y = 16;
  443. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  444. verticesp++;
  445. normalsp++;
  446. *colorsp++ = LLColor4U::white;
  447. texCoords0p++;
  448. texCoords1p++;
  449. vertex_count++;
  450. }
  451. for (i = 0; i < length; i++)
  452. {
  453. if (!(i % 2))
  454. {
  455. *(indicesp++) = index_offset + i;
  456. *(indicesp++) = index_offset + i + 1;
  457. *(indicesp++) = index_offset + length + (i/2);
  458. *(indicesp++) = index_offset + i + 1;
  459. *(indicesp++) = index_offset + length + (i/2) + 1;
  460. *(indicesp++) = index_offset + length + (i/2);
  461. }
  462. else if (i < (length - 1))
  463. {
  464. *(indicesp++) = index_offset + i;
  465. *(indicesp++) = index_offset + i + 1;
  466. *(indicesp++) = index_offset + length + (i/2) + 1;
  467. }
  468. }
  469. }
  470. else
  471. {
  472. // North stride is shorter (more vertices)
  473. length = patch_size / north_stride;
  474. half_length = length / 2;
  475. num_vertices = length + half_length + 1;
  476. num_indices = 9*half_length - 3;
  477. facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
  478. // Iterate through this patch's points
  479. for (i = 0; i < length; i+=2)
  480. {
  481. x = i * north_stride;
  482. y = 16 - render_stride;
  483. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  484. *colorsp++ = LLColor4U::white;
  485. verticesp++;
  486. normalsp++;
  487. texCoords0p++;
  488. texCoords1p++;
  489. vertex_count++;
  490. }
  491. // Iterate through the north patch's points
  492. for (i = 0; i <= length; i++)
  493. {
  494. x = i * north_stride;
  495. y = 16;
  496. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  497. verticesp++;
  498. normalsp++;
  499. *colorsp++ = LLColor4U::white;
  500. texCoords0p++;
  501. texCoords1p++;
  502. vertex_count++;
  503. }
  504. for (i = 0; i < length; i++)
  505. {
  506. if (!(i%2))
  507. {
  508. *(indicesp++) = index_offset + half_length + i;
  509. *(indicesp++) = index_offset + i/2;
  510. *(indicesp++) = index_offset + half_length + i + 1;
  511. }
  512. else if (i < (length - 2))
  513. {
  514. *(indicesp++) = index_offset + half_length + i;
  515. *(indicesp++) = index_offset + i/2;
  516. *(indicesp++) = index_offset + i/2 + 1;
  517. *(indicesp++) = index_offset + half_length + i;
  518. *(indicesp++) = index_offset + i/2 + 1;
  519. *(indicesp++) = index_offset + half_length + i + 1;
  520. }
  521. else
  522. {
  523. *(indicesp++) = index_offset + half_length + i;
  524. *(indicesp++) = index_offset + i/2;
  525. *(indicesp++) = index_offset + half_length + i + 1;
  526. }
  527. }
  528. }
  529. index_offset += num_vertices;
  530. }
  531. void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
  532.   LLStrider<LLVector3> &verticesp,
  533.   LLStrider<LLVector3> &normalsp,
  534.   LLStrider<LLColor4U> &colorsp,
  535.   LLStrider<LLVector2> &texCoords0p,
  536.   LLStrider<LLVector2> &texCoords1p,
  537.   LLStrider<U16> &indicesp,
  538.   U32 &index_offset)
  539. {
  540. S32 i, x, y;
  541. S32 num_vertices, num_indices;
  542. U32 render_stride = mLastStride;
  543. S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
  544. S32 length = patch_size / render_stride;
  545. S32 half_length = length / 2;
  546. U32 east_stride = mLastEastStride;
  547. // Stride lengths are the same
  548. if (east_stride == render_stride)
  549. {
  550. num_vertices = 2 * length + 1;
  551. num_indices = length * 6 - 3;
  552. facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
  553. // Main patch
  554. for (i = 0; i < length; i++)
  555. {
  556. x = 16 - render_stride;
  557. y = i * render_stride;
  558. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  559. verticesp++;
  560. normalsp++;
  561. *colorsp++ = LLColor4U::white;
  562. texCoords0p++;
  563. texCoords1p++;
  564. }
  565. // East patch
  566. for (i = 0; i <= length; i++)
  567. {
  568. x = 16;
  569. y = i * render_stride;
  570. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  571. verticesp++;
  572. normalsp++;
  573. *colorsp++ = LLColor4U::white;
  574. texCoords0p++;
  575. texCoords1p++;
  576. }
  577. for (i = 0; i < length; i++)
  578. {
  579. // Generate indices
  580. *(indicesp++) = index_offset + i;
  581. *(indicesp++) = index_offset + length + i;
  582. *(indicesp++) = index_offset + length + i + 1;
  583. if (i != length - 1)
  584. {
  585. *(indicesp++) = index_offset + i;
  586. *(indicesp++) = index_offset + length + i + 1;
  587. *(indicesp++) = index_offset + i + 1;
  588. }
  589. }
  590. }
  591. else if (east_stride > render_stride)
  592. {
  593. // East stride is longer (has less vertices)
  594. num_vertices = length + half_length + 1;
  595. num_indices = half_length*9 - 3;
  596. facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
  597. // Iterate through this patch's points
  598. for (i = 0; i < length; i++)
  599. {
  600. x = 16 - render_stride;
  601. y = i * render_stride;
  602. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  603. verticesp++;
  604. normalsp++;
  605. *colorsp++ = LLColor4U::white;
  606. texCoords0p++;
  607. texCoords1p++;
  608. }
  609. // Iterate through the east patch's points
  610. for (i = 0; i <= length; i+=2)
  611. {
  612. x = 16;
  613. y = i * render_stride;
  614. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  615. verticesp++;
  616. normalsp++;
  617. *colorsp++ = LLColor4U::white;
  618. texCoords0p++;
  619. texCoords1p++;
  620. }
  621. for (i = 0; i < length; i++)
  622. {
  623. if (!(i % 2))
  624. {
  625. *(indicesp++) = index_offset + i;
  626. *(indicesp++) = index_offset + length + (i/2);
  627. *(indicesp++) = index_offset + i + 1;
  628. *(indicesp++) = index_offset + i + 1;
  629. *(indicesp++) = index_offset + length + (i/2);
  630. *(indicesp++) = index_offset + length + (i/2) + 1;
  631. }
  632. else if (i < (length - 1))
  633. {
  634. *(indicesp++) = index_offset + i;
  635. *(indicesp++) = index_offset + length + (i/2) + 1;
  636. *(indicesp++) = index_offset + i + 1;
  637. }
  638. }
  639. }
  640. else
  641. {
  642. // East stride is shorter (more vertices)
  643. length = patch_size / east_stride;
  644. half_length = length / 2;
  645. num_vertices = length + length/2 + 1;
  646. num_indices = 9*(length/2) - 3;
  647. facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
  648. // Iterate through this patch's points
  649. for (i = 0; i < length; i+=2)
  650. {
  651. x = 16 - render_stride;
  652. y = i * east_stride;
  653. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  654. verticesp++;
  655. normalsp++;
  656. *colorsp++ = LLColor4U::white;
  657. texCoords0p++;
  658. texCoords1p++;
  659. }
  660. // Iterate through the east patch's points
  661. for (i = 0; i <= length; i++)
  662. {
  663. x = 16;
  664. y = i * east_stride;
  665. mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
  666. verticesp++;
  667. normalsp++;
  668. *colorsp++ = LLColor4U::white;
  669. texCoords0p++;
  670. texCoords1p++;
  671. }
  672. for (i = 0; i < length; i++)
  673. {
  674. if (!(i%2))
  675. {
  676. *(indicesp++) = index_offset + half_length + i;
  677. *(indicesp++) = index_offset + half_length + i + 1;
  678. *(indicesp++) = index_offset + i/2;
  679. }
  680. else if (i < (length - 2))
  681. {
  682. *(indicesp++) = index_offset + half_length + i;
  683. *(indicesp++) = index_offset + i/2 + 1;
  684. *(indicesp++) = index_offset + i/2;
  685. *(indicesp++) = index_offset + half_length + i;
  686. *(indicesp++) = index_offset + half_length + i + 1;
  687. *(indicesp++) = index_offset + i/2 + 1;
  688. }
  689. else
  690. {
  691. *(indicesp++) = index_offset + half_length + i;
  692. *(indicesp++) = index_offset + half_length + i + 1;
  693. *(indicesp++) = index_offset + i/2;
  694. }
  695. }
  696. }
  697. index_offset += num_vertices;
  698. }
  699. void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp)
  700. {
  701. mPatchp = patchp;
  702. dirtyPatch();
  703. };
  704. void LLVOSurfacePatch::dirtyPatch()
  705. {
  706. mDirtiedPatch = TRUE;
  707. dirtyGeom();
  708. mDirtyTerrain = TRUE;
  709. LLVector3 center = mPatchp->getCenterRegion();
  710. LLSurface *surfacep = mPatchp->getSurface();
  711. setPositionRegion(center);
  712. F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid();
  713. setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ()));
  714. }
  715. void LLVOSurfacePatch::dirtyGeom()
  716. {
  717. if (mDrawable)
  718. {
  719. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
  720. mDrawable->getFace(0)->mVertexBuffer = NULL;
  721. mDrawable->movePartition();
  722. }
  723. }
  724. void LLVOSurfacePatch::getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices)
  725. {
  726. S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
  727. // First, figure out how many vertices we need...
  728. S32 vert_size = patch_size / stride;
  729. if (vert_size >= 2)
  730. {
  731. num_vertices += vert_size * vert_size;
  732. num_indices += 6 * (vert_size - 1)*(vert_size - 1);
  733. }
  734. }
  735. void LLVOSurfacePatch::getGeomSizesNorth(const S32 stride, const S32 north_stride,
  736.  S32 &num_vertices, S32 &num_indices)
  737. {
  738. S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
  739. S32 length = patch_size / stride;
  740. // Stride lengths are the same
  741. if (north_stride == stride)
  742. {
  743. num_vertices += 2 * length + 1;
  744. num_indices += length * 6 - 3;
  745. }
  746. else if (north_stride > stride)
  747. {
  748. // North stride is longer (has less vertices)
  749. num_vertices += length + (length/2) + 1;
  750. num_indices += (length/2)*9 - 3;
  751. }
  752. else
  753. {
  754. // North stride is shorter (more vertices)
  755. length = patch_size / north_stride;
  756. num_vertices += length + (length/2) + 1;
  757. num_indices += 9*(length/2) - 3;
  758. }
  759. }
  760. void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
  761. S32 &num_vertices, S32 &num_indices)
  762. {
  763. S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
  764. S32 length = patch_size / stride;
  765. // Stride lengths are the same
  766. if (east_stride == stride)
  767. {
  768. num_vertices += 2 * length + 1;
  769. num_indices += length * 6 - 3;
  770. }
  771. else if (east_stride > stride)
  772. {
  773. // East stride is longer (has less vertices)
  774. num_vertices += length + (length/2) + 1;
  775. num_indices += (length/2)*9 - 3;
  776. }
  777. else
  778. {
  779. // East stride is shorter (more vertices)
  780. length = patch_size / east_stride;
  781. num_vertices += length + (length/2) + 1;
  782. num_indices += 9*(length/2) - 3;
  783. }
  784. }
  785. BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp,
  786.   LLVector3* intersection,LLVector2* tex_coord, LLVector3* normal, LLVector3* bi_normal)
  787. {
  788. if (!lineSegmentBoundingBox(start, end))
  789. {
  790. return FALSE;
  791. }
  792. LLVector3 delta = end-start;
  793. LLVector3 pdelta = delta;
  794. pdelta.mV[2] = 0;
  795. F32 plength = pdelta.length();
  796. F32 tdelta = 1.f/plength;
  797. LLVector3 origin = start - mRegionp->getOriginAgent();
  798. if (mRegionp->getLandHeightRegion(origin) > origin.mV[2])
  799. {
  800. //origin is under ground, treat as no intersection
  801. return FALSE;
  802. }
  803. //step one meter at a time until intersection point found
  804. const LLVector3* ext = mDrawable->getSpatialExtents();
  805. F32 rad = (delta*tdelta).magVecSquared();
  806. F32 t = 0.f;
  807. while ( t <= 1.f)
  808. {
  809. LLVector3 sample = origin + delta*t;
  810. if (AABBSphereIntersectR2(ext[0], ext[1], sample+mRegionp->getOriginAgent(), rad))
  811. {
  812. F32 height = mRegionp->getLandHeightRegion(sample);
  813. if (height > sample.mV[2])
  814. { //ray went below ground, positive intersection
  815. //quick and dirty binary search to get impact point
  816. tdelta = -tdelta*0.5f;
  817. F32 err_dist = 0.001f;
  818. F32 dist = fabsf(sample.mV[2] - height);
  819. while (dist > err_dist && tdelta*tdelta > 0.0f)
  820. {
  821. t += tdelta;
  822. sample = origin+delta*t;
  823. height = mRegionp->getLandHeightRegion(sample);
  824. if ((tdelta < 0 && height < sample.mV[2]) ||
  825. (height > sample.mV[2] && tdelta > 0))
  826. { //jumped over intersection point, go back
  827. tdelta = -tdelta;
  828. }
  829. tdelta *= 0.5f;
  830. dist = fabsf(sample.mV[2] - height);
  831. }
  832. if (intersection)
  833. {
  834. F32 height = mRegionp->getLandHeightRegion(sample);
  835. if (fabsf(sample.mV[2]-height) < delta.length()*tdelta)
  836. {
  837. sample.mV[2] = mRegionp->getLandHeightRegion(sample);
  838. }
  839. *intersection = sample + mRegionp->getOriginAgent();
  840. }
  841. if (normal)
  842. {
  843. *normal = mRegionp->getLand().resolveNormalGlobal(mRegionp->getPosGlobalFromRegion(sample));
  844. }
  845. return TRUE;
  846. }
  847. }
  848. t += tdelta;
  849. if (t > 1 && t < 1.f+tdelta*0.99f)
  850. { //make sure end point is checked (saves vertical lines coming up negative)
  851. t = 1.f;
  852. }
  853. }
  854. return FALSE;
  855. }
  856. void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
  857. {
  858. LLVector3 posAgent = getPositionAgent();
  859. LLVector3 scale = getScale();
  860. newMin = posAgent-scale*0.5f; // Changing to 2.f makes the culling a -little- better, but still wrong
  861. newMax = posAgent+scale*0.5f;
  862. mDrawable->setPositionGroup((newMin+newMax)*0.5f);
  863. }
  864. U32 LLVOSurfacePatch::getPartitionType() const
  865. return LLViewerRegion::PARTITION_TERRAIN; 
  866. }
  867. LLTerrainPartition::LLTerrainPartition()
  868. : LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB)
  869. {
  870. mOcclusionEnabled = FALSE;
  871. mInfiniteFarClip = TRUE;
  872. mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN;
  873. mPartitionType = LLViewerRegion::PARTITION_TERRAIN;
  874. }
  875. LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage)
  876. {
  877. return new LLVertexBufferTerrain();
  878. }
  879. static LLFastTimer::DeclareTimer FTM_REBUILD_TERRAIN_VB("Terrain VB");
  880. void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
  881. {
  882. LLFastTimer ftm(FTM_REBUILD_TERRAIN_VB);
  883. LLVertexBuffer* buffer = group->mVertexBuffer;
  884. //get vertex buffer striders
  885. LLStrider<LLVector3> vertices;
  886. LLStrider<LLVector3> normals;
  887. LLStrider<LLVector2> texcoords2;
  888. LLStrider<LLVector2> texcoords;
  889. LLStrider<LLColor4U> colors;
  890. LLStrider<U16> indices;
  891. llassert_always(buffer->getVertexStrider(vertices));
  892. llassert_always(buffer->getNormalStrider(normals));
  893. llassert_always(buffer->getTexCoord0Strider(texcoords));
  894. llassert_always(buffer->getTexCoord1Strider(texcoords2));
  895. llassert_always(buffer->getColorStrider(colors));
  896. llassert_always(buffer->getIndexStrider(indices));
  897. U32 indices_index = 0;
  898. U32 index_offset = 0;
  899. for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
  900. {
  901. LLFace* facep = *i;
  902. facep->setIndicesIndex(indices_index);
  903. facep->setGeomIndex(index_offset);
  904. facep->mVertexBuffer = buffer;
  905. LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject();
  906. patchp->getGeometry(vertices, normals, colors, texcoords, texcoords2, indices);
  907. indices_index += facep->getIndicesCount();
  908. index_offset += facep->getGeomCount();
  909. }
  910. buffer->setBuffer(0);
  911. mFaceList.clear();
  912. }