00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llvosurfacepatch.h"
00035
00036 #include "lldrawpoolterrain.h"
00037
00038 #include "lldrawable.h"
00039 #include "llface.h"
00040 #include "llprimitive.h"
00041 #include "llsky.h"
00042 #include "llsurfacepatch.h"
00043 #include "llsurface.h"
00044 #include "llviewerobjectlist.h"
00045 #include "llviewerregion.h"
00046 #include "llvlcomposition.h"
00047 #include "llvovolume.h"
00048 #include "pipeline.h"
00049 #include "llspatialpartition.h"
00050
00051 F32 LLVOSurfacePatch::sLODFactor = 1.f;
00052
00053
00054
00055 class LLVertexBufferTerrain : public LLVertexBuffer
00056 {
00057 public:
00058 LLVertexBufferTerrain() :
00059 LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD | MAP_TEXCOORD2 | MAP_COLOR, GL_DYNAMIC_DRAW_ARB)
00060 {
00061 };
00062
00063
00064 void setupVertexBuffer(U32 data_mask) const
00065 {
00066 if (LLDrawPoolTerrain::getDetailMode() == 0)
00067 {
00068 LLVertexBuffer::setupVertexBuffer(data_mask);
00069 }
00070 else if (data_mask & LLVertexBuffer::MAP_TEXCOORD2)
00071 {
00072 U8* base = useVBOs() ? NULL : mMappedData;
00073
00074 glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0));
00075 glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL]));
00076 glColorPointer(4, GL_UNSIGNED_BYTE, mStride, (void*)(base + mOffsets[TYPE_COLOR]));
00077
00078 glClientActiveTextureARB(GL_TEXTURE3_ARB);
00079 glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
00080 glClientActiveTextureARB(GL_TEXTURE2_ARB);
00081 glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
00082 glClientActiveTextureARB(GL_TEXTURE1_ARB);
00083 glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
00084 glClientActiveTextureARB(GL_TEXTURE0_ARB);
00085 glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
00086 }
00087 else
00088 {
00089 LLVertexBuffer::setupVertexBuffer(data_mask);
00090 }
00091 llglassertok();
00092 }
00093 };
00094
00095
00096
00097 LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00098 : LLStaticViewerObject(id, LL_VO_SURFACE_PATCH, regionp),
00099 mDirtiedPatch(FALSE),
00100 mPool(NULL),
00101 mBaseComp(0),
00102 mPatchp(NULL),
00103 mDirtyTexture(FALSE),
00104 mDirtyTerrain(FALSE),
00105 mLastNorthStride(0),
00106 mLastEastStride(0),
00107 mLastStride(0),
00108 mLastLength(0)
00109 {
00110
00111 mbCanSelect = TRUE;
00112 setScale(LLVector3(16.f, 16.f, 16.f));
00113 }
00114
00115
00116 LLVOSurfacePatch::~LLVOSurfacePatch()
00117 {
00118 mPatchp = NULL;
00119 }
00120
00121
00122 void LLVOSurfacePatch::markDead()
00123 {
00124 if (mPatchp)
00125 {
00126 mPatchp->clearVObj();
00127 mPatchp = NULL;
00128 }
00129 LLViewerObject::markDead();
00130 }
00131
00132
00133 BOOL LLVOSurfacePatch::isActive() const
00134 {
00135 return FALSE;
00136 }
00137
00138
00139 void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent)
00140 {
00141 mAppAngle = 50;
00142 mPixelArea = 500*500;
00143 }
00144
00145
00146 void LLVOSurfacePatch::updateTextures(LLAgent &agent)
00147 {
00148 }
00149
00150
00151 LLFacePool *LLVOSurfacePatch::getPool()
00152 {
00153 mPool = (LLDrawPoolTerrain*) gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture());
00154
00155 return mPool;
00156 }
00157
00158
00159 LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline)
00160 {
00161 pipeline->allocDrawable(this);
00162
00163 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN);
00164
00165 mBaseComp = llfloor(mPatchp->getMinComposition());
00166 S32 min_comp, max_comp, range;
00167 min_comp = llfloor(mPatchp->getMinComposition());
00168 max_comp = llceil(mPatchp->getMaxComposition());
00169 range = (max_comp - min_comp);
00170 range++;
00171 if (range > 3)
00172 {
00173 if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
00174 {
00175
00176 mBaseComp++;
00177 }
00178 range = 3;
00179 }
00180
00181 LLFacePool *poolp = getPool();
00182
00183 mDrawable->addFace(poolp, NULL);
00184
00185 return mDrawable;
00186 }
00187
00188
00189 BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
00190 {
00191 LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN);
00192
00193 dirtySpatialGroup();
00194
00195 S32 min_comp, max_comp, range;
00196 min_comp = lltrunc(mPatchp->getMinComposition());
00197 max_comp = lltrunc(ceil(mPatchp->getMaxComposition()));
00198 range = (max_comp - min_comp);
00199 range++;
00200 S32 new_base_comp = lltrunc(mPatchp->getMinComposition());
00201 if (range > 3)
00202 {
00203 if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition()))
00204 {
00205
00206 new_base_comp++;
00207 }
00208 range = 3;
00209 }
00210
00211
00212
00213
00214 mBaseComp = new_base_comp;
00215
00217
00218
00219
00220
00221
00222 U32 patch_width, render_stride, north_stride, east_stride, length;
00223 render_stride = mPatchp->getRenderStride();
00224 patch_width = mPatchp->getSurface()->getGridsPerPatchEdge();
00225
00226 length = patch_width / render_stride;
00227
00228 if (mPatchp->getNeighborPatch(NORTH))
00229 {
00230 north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride();
00231 }
00232 else
00233 {
00234 north_stride = render_stride;
00235 }
00236
00237 if (mPatchp->getNeighborPatch(EAST))
00238 {
00239 east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride();
00240 }
00241 else
00242 {
00243 east_stride = render_stride;
00244 }
00245
00246 mLastLength = length;
00247 mLastStride = render_stride;
00248 mLastNorthStride = north_stride;
00249 mLastEastStride = east_stride;
00250
00251 return TRUE;
00252 }
00253
00254 void LLVOSurfacePatch::updateFaceSize(S32 idx)
00255 {
00256 if (idx != 0)
00257 {
00258 llwarns << "Terrain partition requested invalid face!!!" << llendl;
00259 return;
00260 }
00261
00262 LLFace* facep = mDrawable->getFace(idx);
00263
00264 S32 num_vertices = 0;
00265 S32 num_indices = 0;
00266
00267 if (mLastStride)
00268 {
00269 getGeomSizesMain(mLastStride, num_vertices, num_indices);
00270 getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
00271 getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
00272 }
00273
00274 facep->setSize(num_vertices, num_indices);
00275 }
00276
00277 BOOL LLVOSurfacePatch::updateLOD()
00278 {
00279 return TRUE;
00280 }
00281
00282 void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
00283 LLStrider<LLVector3> &normalsp,
00284 LLStrider<LLColor4U> &colorsp,
00285 LLStrider<LLVector2> &texCoords0p,
00286 LLStrider<LLVector2> &texCoords1p,
00287 LLStrider<U16> &indicesp)
00288 {
00289 LLFace* facep = mDrawable->getFace(0);
00290
00291 U32 index_offset = facep->getGeomIndex();
00292
00293 updateMainGeometry(facep,
00294 verticesp,
00295 normalsp,
00296 colorsp,
00297 texCoords0p,
00298 texCoords1p,
00299 indicesp,
00300 index_offset);
00301 updateNorthGeometry(facep,
00302 verticesp,
00303 normalsp,
00304 colorsp,
00305 texCoords0p,
00306 texCoords1p,
00307 indicesp,
00308 index_offset);
00309 updateEastGeometry(facep,
00310 verticesp,
00311 normalsp,
00312 colorsp,
00313 texCoords0p,
00314 texCoords1p,
00315 indicesp,
00316 index_offset);
00317 }
00318
00319 void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
00320 LLStrider<LLVector3> &verticesp,
00321 LLStrider<LLVector3> &normalsp,
00322 LLStrider<LLColor4U> &colorsp,
00323 LLStrider<LLVector2> &texCoords0p,
00324 LLStrider<LLVector2> &texCoords1p,
00325 LLStrider<U16> &indicesp,
00326 U32 &index_offset)
00327 {
00328 S32 i, j, x, y;
00329
00330 U32 patch_size, render_stride;
00331 S32 num_vertices, num_indices;
00332 U32 index;
00333
00334 render_stride = mLastStride;
00335 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
00336 S32 vert_size = patch_size / render_stride;
00337
00339
00340
00341
00342
00343
00344 num_vertices = 0;
00345 num_indices = 0;
00346
00347 getGeomSizesMain(render_stride, num_vertices, num_indices);
00348
00349 if (num_vertices > 0)
00350 {
00351 facep->mCenterAgent = mPatchp->getPointAgent(8, 8);
00352
00353
00354 for (j = 0; j < vert_size; j++)
00355 {
00356 for (i = 0; i < vert_size; i++)
00357 {
00358 x = i * render_stride;
00359 y = j * render_stride;
00360 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00361 *colorsp++ = LLColor4U::white;
00362 verticesp++;
00363 normalsp++;
00364 texCoords0p++;
00365 texCoords1p++;
00366 }
00367 }
00368
00369 for (j = 0; j < (vert_size - 1); j++)
00370 {
00371 if (j % 2)
00372 {
00373 for (i = (vert_size - 1); i > 0; i--)
00374 {
00375 index = (i - 1)+ j*vert_size;
00376 *(indicesp++) = index_offset + index;
00377
00378 index = i + (j+1)*vert_size;
00379 *(indicesp++) = index_offset + index;
00380
00381 index = (i - 1) + (j+1)*vert_size;
00382 *(indicesp++) = index_offset + index;
00383
00384 index = (i - 1) + j*vert_size;
00385 *(indicesp++) = index_offset + index;
00386
00387 index = i + j*vert_size;
00388 *(indicesp++) = index_offset + index;
00389
00390 index = i + (j+1)*vert_size;
00391 *(indicesp++) = index_offset + index;
00392 }
00393 }
00394 else
00395 {
00396 for (i = 0; i < (vert_size - 1); i++)
00397 {
00398 index = i + j*vert_size;
00399 *(indicesp++) = index_offset + index;
00400
00401 index = (i + 1) + (j+1)*vert_size;
00402 *(indicesp++) = index_offset + index;
00403
00404 index = i + (j+1)*vert_size;
00405 *(indicesp++) = index_offset + index;
00406
00407 index = i + j*vert_size;
00408 *(indicesp++) = index_offset + index;
00409
00410 index = (i + 1) + j*vert_size;
00411 *(indicesp++) = index_offset + index;
00412
00413 index = (i + 1) + (j + 1)*vert_size;
00414 *(indicesp++) = index_offset + index;
00415 }
00416 }
00417 }
00418 }
00419 index_offset += num_vertices;
00420 }
00421
00422
00423 void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
00424 LLStrider<LLVector3> &verticesp,
00425 LLStrider<LLVector3> &normalsp,
00426 LLStrider<LLColor4U> &colorsp,
00427 LLStrider<LLVector2> &texCoords0p,
00428 LLStrider<LLVector2> &texCoords1p,
00429 LLStrider<U16> &indicesp,
00430 U32 &index_offset)
00431 {
00432 S32 vertex_count = 0;
00433 S32 i, x, y;
00434
00435 S32 num_vertices, num_indices;
00436
00437 U32 render_stride = mLastStride;
00438 S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
00439 S32 length = patch_size / render_stride;
00440 S32 half_length = length / 2;
00441 U32 north_stride = mLastNorthStride;
00442
00444
00445
00446
00447
00448
00449
00450 if (north_stride == render_stride)
00451 {
00452 num_vertices = 2 * length + 1;
00453 num_indices = length * 6 - 3;
00454
00455 facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
00456
00457
00458 for (i = 0; i < length; i++)
00459 {
00460 x = i * render_stride;
00461 y = 16 - render_stride;
00462
00463 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00464 *colorsp++ = LLColor4U::white;
00465 verticesp++;
00466 normalsp++;
00467 texCoords0p++;
00468 texCoords1p++;
00469 vertex_count++;
00470 }
00471
00472
00473 for (i = 0; i <= length; i++)
00474 {
00475 x = i * render_stride;
00476 y = 16;
00477 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00478 verticesp++;
00479 normalsp++;
00480 *colorsp++ = LLColor4U::white;
00481 texCoords0p++;
00482 texCoords1p++;
00483 vertex_count++;
00484 }
00485
00486
00487 for (i = 0; i < length; i++)
00488 {
00489
00490 *(indicesp++) = index_offset + i;
00491 *(indicesp++) = index_offset + length + i + 1;
00492 *(indicesp++) = index_offset + length + i;
00493
00494 if (i != length - 1)
00495 {
00496 *(indicesp++) = index_offset + i;
00497 *(indicesp++) = index_offset + i + 1;
00498 *(indicesp++) = index_offset + length + i + 1;
00499 }
00500 }
00501 }
00502 else if (north_stride > render_stride)
00503 {
00504
00505 num_vertices = length + length/2 + 1;
00506 num_indices = half_length*9 - 3;
00507
00508 facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
00509
00510
00511 for (i = 0; i < length; i++)
00512 {
00513 x = i * render_stride;
00514 y = 16 - render_stride;
00515
00516 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00517 verticesp++;
00518 normalsp++;
00519 *colorsp++ = LLColor4U::white;
00520 texCoords0p++;
00521 texCoords1p++;
00522 vertex_count++;
00523 }
00524
00525
00526 for (i = 0; i <= length; i+=2)
00527 {
00528 x = i * render_stride;
00529 y = 16;
00530
00531 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00532 verticesp++;
00533 normalsp++;
00534 *colorsp++ = LLColor4U::white;
00535 texCoords0p++;
00536 texCoords1p++;
00537 vertex_count++;
00538 }
00539
00540
00541 for (i = 0; i < length; i++)
00542 {
00543 if (!(i % 2))
00544 {
00545 *(indicesp++) = index_offset + i;
00546 *(indicesp++) = index_offset + i + 1;
00547 *(indicesp++) = index_offset + length + (i/2);
00548
00549 *(indicesp++) = index_offset + i + 1;
00550 *(indicesp++) = index_offset + length + (i/2) + 1;
00551 *(indicesp++) = index_offset + length + (i/2);
00552 }
00553 else if (i < (length - 1))
00554 {
00555 *(indicesp++) = index_offset + i;
00556 *(indicesp++) = index_offset + i + 1;
00557 *(indicesp++) = index_offset + length + (i/2) + 1;
00558 }
00559 }
00560 }
00561 else
00562 {
00563
00564 length = patch_size / north_stride;
00565 half_length = length / 2;
00566 num_vertices = length + half_length + 1;
00567 num_indices = 9*half_length - 3;
00568
00569 facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
00570
00571
00572 for (i = 0; i < length; i+=2)
00573 {
00574 x = i * north_stride;
00575 y = 16 - render_stride;
00576
00577 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00578 *colorsp++ = LLColor4U::white;
00579 verticesp++;
00580 normalsp++;
00581 texCoords0p++;
00582 texCoords1p++;
00583 vertex_count++;
00584 }
00585
00586
00587 for (i = 0; i <= length; i++)
00588 {
00589 x = i * north_stride;
00590 y = 16;
00591
00592 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00593 verticesp++;
00594 normalsp++;
00595 *colorsp++ = LLColor4U::white;
00596 texCoords0p++;
00597 texCoords1p++;
00598 vertex_count++;
00599 }
00600
00601 for (i = 0; i < length; i++)
00602 {
00603 if (!(i%2))
00604 {
00605 *(indicesp++) = index_offset + half_length + i;
00606 *(indicesp++) = index_offset + i/2;
00607 *(indicesp++) = index_offset + half_length + i + 1;
00608 }
00609 else if (i < (length - 2))
00610 {
00611 *(indicesp++) = index_offset + half_length + i;
00612 *(indicesp++) = index_offset + i/2;
00613 *(indicesp++) = index_offset + i/2 + 1;
00614
00615 *(indicesp++) = index_offset + half_length + i;
00616 *(indicesp++) = index_offset + i/2 + 1;
00617 *(indicesp++) = index_offset + half_length + i + 1;
00618 }
00619 else
00620 {
00621 *(indicesp++) = index_offset + half_length + i;
00622 *(indicesp++) = index_offset + i/2;
00623 *(indicesp++) = index_offset + half_length + i + 1;
00624 }
00625 }
00626 }
00627 index_offset += num_vertices;
00628 }
00629
00630 void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
00631 LLStrider<LLVector3> &verticesp,
00632 LLStrider<LLVector3> &normalsp,
00633 LLStrider<LLColor4U> &colorsp,
00634 LLStrider<LLVector2> &texCoords0p,
00635 LLStrider<LLVector2> &texCoords1p,
00636 LLStrider<U16> &indicesp,
00637 U32 &index_offset)
00638 {
00639 S32 i, x, y;
00640
00641 S32 num_vertices, num_indices;
00642
00643 U32 render_stride = mLastStride;
00644 S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
00645 S32 length = patch_size / render_stride;
00646 S32 half_length = length / 2;
00647
00648 U32 east_stride = mLastEastStride;
00649
00650
00651 if (east_stride == render_stride)
00652 {
00653 num_vertices = 2 * length + 1;
00654 num_indices = length * 6 - 3;
00655
00656 facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
00657
00658
00659 for (i = 0; i < length; i++)
00660 {
00661 x = 16 - render_stride;
00662 y = i * render_stride;
00663
00664 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00665 verticesp++;
00666 normalsp++;
00667 *colorsp++ = LLColor4U::white;
00668 texCoords0p++;
00669 texCoords1p++;
00670 }
00671
00672
00673 for (i = 0; i <= length; i++)
00674 {
00675 x = 16;
00676 y = i * render_stride;
00677 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00678 verticesp++;
00679 normalsp++;
00680 *colorsp++ = LLColor4U::white;
00681 texCoords0p++;
00682 texCoords1p++;
00683 }
00684
00685
00686 for (i = 0; i < length; i++)
00687 {
00688
00689 *(indicesp++) = index_offset + i;
00690 *(indicesp++) = index_offset + length + i;
00691 *(indicesp++) = index_offset + length + i + 1;
00692
00693 if (i != length - 1)
00694 {
00695 *(indicesp++) = index_offset + i;
00696 *(indicesp++) = index_offset + length + i + 1;
00697 *(indicesp++) = index_offset + i + 1;
00698 }
00699 }
00700 }
00701 else if (east_stride > render_stride)
00702 {
00703
00704 num_vertices = length + half_length + 1;
00705 num_indices = half_length*9 - 3;
00706
00707 facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
00708
00709
00710 for (i = 0; i < length; i++)
00711 {
00712 x = 16 - render_stride;
00713 y = i * render_stride;
00714
00715 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00716 verticesp++;
00717 normalsp++;
00718 *colorsp++ = LLColor4U::white;
00719 texCoords0p++;
00720 texCoords1p++;
00721 }
00722
00723 for (i = 0; i <= length; i+=2)
00724 {
00725 x = 16;
00726 y = i * render_stride;
00727
00728 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00729 verticesp++;
00730 normalsp++;
00731 *colorsp++ = LLColor4U::white;
00732 texCoords0p++;
00733 texCoords1p++;
00734 }
00735
00736 for (i = 0; i < length; i++)
00737 {
00738 if (!(i % 2))
00739 {
00740 *(indicesp++) = index_offset + i;
00741 *(indicesp++) = index_offset + length + (i/2);
00742 *(indicesp++) = index_offset + i + 1;
00743
00744 *(indicesp++) = index_offset + i + 1;
00745 *(indicesp++) = index_offset + length + (i/2);
00746 *(indicesp++) = index_offset + length + (i/2) + 1;
00747 }
00748 else if (i < (length - 1))
00749 {
00750 *(indicesp++) = index_offset + i;
00751 *(indicesp++) = index_offset + length + (i/2) + 1;
00752 *(indicesp++) = index_offset + i + 1;
00753 }
00754 }
00755 }
00756 else
00757 {
00758
00759 length = patch_size / east_stride;
00760 half_length = length / 2;
00761 num_vertices = length + length/2 + 1;
00762 num_indices = 9*(length/2) - 3;
00763
00764 facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
00765
00766
00767 for (i = 0; i < length; i+=2)
00768 {
00769 x = 16 - render_stride;
00770 y = i * east_stride;
00771
00772 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00773 verticesp++;
00774 normalsp++;
00775 *colorsp++ = LLColor4U::white;
00776 texCoords0p++;
00777 texCoords1p++;
00778 }
00779
00780 for (i = 0; i <= length; i++)
00781 {
00782 x = 16;
00783 y = i * east_stride;
00784
00785 mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get());
00786 verticesp++;
00787 normalsp++;
00788 *colorsp++ = LLColor4U::white;
00789 texCoords0p++;
00790 texCoords1p++;
00791 }
00792
00793 for (i = 0; i < length; i++)
00794 {
00795 if (!(i%2))
00796 {
00797 *(indicesp++) = index_offset + half_length + i;
00798 *(indicesp++) = index_offset + half_length + i + 1;
00799 *(indicesp++) = index_offset + i/2;
00800 }
00801 else if (i < (length - 2))
00802 {
00803 *(indicesp++) = index_offset + half_length + i;
00804 *(indicesp++) = index_offset + i/2 + 1;
00805 *(indicesp++) = index_offset + i/2;
00806
00807 *(indicesp++) = index_offset + half_length + i;
00808 *(indicesp++) = index_offset + half_length + i + 1;
00809 *(indicesp++) = index_offset + i/2 + 1;
00810 }
00811 else
00812 {
00813 *(indicesp++) = index_offset + half_length + i;
00814 *(indicesp++) = index_offset + half_length + i + 1;
00815 *(indicesp++) = index_offset + i/2;
00816 }
00817 }
00818 }
00819 index_offset += num_vertices;
00820 }
00821
00822 void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp)
00823 {
00824 mPatchp = patchp;
00825
00826 dirtyPatch();
00827 };
00828
00829
00830 void LLVOSurfacePatch::dirtyPatch()
00831 {
00832 mDirtiedPatch = TRUE;
00833 dirtyGeom();
00834 mDirtyTerrain = TRUE;
00835 LLVector3 center = mPatchp->getCenterRegion();
00836 LLSurface *surfacep = mPatchp->getSurface();
00837
00838 setPositionRegion(center);
00839
00840 F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid();
00841 setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ()));
00842 }
00843
00844 void LLVOSurfacePatch::dirtyGeom()
00845 {
00846 if (mDrawable)
00847 {
00848 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00849 mDrawable->getFace(0)->mVertexBuffer = NULL;
00850 mDrawable->movePartition();
00851 }
00852 }
00853
00854 void LLVOSurfacePatch::getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices)
00855 {
00856 S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
00857
00858
00859 S32 vert_size = patch_size / stride;
00860 if (vert_size >= 2)
00861 {
00862 num_vertices += vert_size * vert_size;
00863 num_indices += 6 * (vert_size - 1)*(vert_size - 1);
00864 }
00865 }
00866
00867 void LLVOSurfacePatch::getGeomSizesNorth(const S32 stride, const S32 north_stride,
00868 S32 &num_vertices, S32 &num_indices)
00869 {
00870 S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
00871 S32 length = patch_size / stride;
00872
00873 if (north_stride == stride)
00874 {
00875 num_vertices += 2 * length + 1;
00876 num_indices += length * 6 - 3;
00877 }
00878 else if (north_stride > stride)
00879 {
00880
00881 num_vertices += length + (length/2) + 1;
00882 num_indices += (length/2)*9 - 3;
00883 }
00884 else
00885 {
00886
00887 length = patch_size / north_stride;
00888 num_vertices += length + (length/2) + 1;
00889 num_indices += 9*(length/2) - 3;
00890 }
00891 }
00892
00893 void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
00894 S32 &num_vertices, S32 &num_indices)
00895 {
00896 S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
00897 S32 length = patch_size / stride;
00898
00899 if (east_stride == stride)
00900 {
00901 num_vertices += 2 * length + 1;
00902 num_indices += length * 6 - 3;
00903 }
00904 else if (east_stride > stride)
00905 {
00906
00907 num_vertices += length + (length/2) + 1;
00908 num_indices += (length/2)*9 - 3;
00909 }
00910 else
00911 {
00912
00913 length = patch_size / east_stride;
00914 num_vertices += length + (length/2) + 1;
00915 num_indices += 9*(length/2) - 3;
00916 }
00917 }
00918
00919 void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
00920 {
00921 LLVector3 posAgent = getPositionAgent();
00922 LLVector3 scale = getScale();
00923 newMin = posAgent-scale*0.5f;
00924 newMax = posAgent+scale*0.5f;
00925 mDrawable->setPositionGroup((newMin+newMax)*0.5f);
00926 }
00927
00928 U32 LLVOSurfacePatch::getPartitionType() const
00929 {
00930 return LLViewerRegion::PARTITION_TERRAIN;
00931 }
00932
00933 LLTerrainPartition::LLTerrainPartition()
00934 : LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK)
00935 {
00936 mOcclusionEnabled = FALSE;
00937 mRenderByGroup = FALSE;
00938 mInfiniteFarClip = TRUE;
00939 mBufferUsage = GL_DYNAMIC_DRAW_ARB;
00940 mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN;
00941 mPartitionType = LLViewerRegion::PARTITION_TERRAIN;
00942 }
00943
00944 LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage)
00945 {
00946 return new LLVertexBufferTerrain();
00947 }
00948
00949 void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
00950 {
00951 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_TERRAIN_VB);
00952
00953 LLVertexBuffer* buffer = group->mVertexBuffer;
00954
00955
00956 LLStrider<LLVector3> vertices;
00957 LLStrider<LLVector3> normals;
00958 LLStrider<LLVector2> texcoords2;
00959 LLStrider<LLVector2> texcoords;
00960 LLStrider<LLColor4U> colors;
00961 LLStrider<U16> indices;
00962
00963 buffer->getVertexStrider(vertices);
00964 buffer->getNormalStrider(normals);
00965 buffer->getTexCoordStrider(texcoords);
00966 buffer->getTexCoord2Strider(texcoords2);
00967 buffer->getColorStrider(colors);
00968 buffer->getIndexStrider(indices);
00969
00970 U32 indices_index = 0;
00971 U32 index_offset = 0;
00972
00973 for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
00974 {
00975 LLFace* facep = *i;
00976
00977 facep->setIndicesIndex(indices_index);
00978 facep->setGeomIndex(index_offset);
00979 facep->mVertexBuffer = buffer;
00980
00981 LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject();
00982 patchp->getGeometry(vertices, normals, colors, texcoords, texcoords2, indices);
00983
00984 indices_index += facep->getIndicesCount();
00985 index_offset += facep->getGeomCount();
00986 }
00987
00988 buffer->setBuffer(0);
00989 mFaceList.clear();
00990 }
00991