llvosurfacepatch.cpp

Go to the documentation of this file.
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         // virtual
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         // Terrain must draw during selection passes so it can block objects behind it.
00111         mbCanSelect = TRUE;
00112         setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility.
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                         // The top side runs over more
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                         // The top side runs over more
00206                         new_base_comp++;
00207                 }
00208                 range = 3;
00209         }
00210 
00211         // Pick the two closest detail textures for this patch...
00212         // Then create the draw pool for it.
00213         // Actually, should get the average composition instead of the center.
00214         mBaseComp = new_base_comp;
00215 
00217         //
00218         // Figure out the strides
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         // Render the main patch
00341         //
00342         //
00343 
00344         num_vertices = 0;
00345         num_indices = 0;
00346         // First, figure out how many vertices we need...
00347         getGeomSizesMain(render_stride, num_vertices, num_indices);
00348 
00349         if (num_vertices > 0)
00350         {
00351                 facep->mCenterAgent = mPatchp->getPointAgent(8, 8);
00352 
00353                 // Generate patch points first
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         // Render the north strip
00446         //
00447         //
00448 
00449         // Stride lengths are the same
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                 // Main patch
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                 // North patch
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                         // Generate indices
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                 // North stride is longer (has less vertices)
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                 // Iterate through this patch's points
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                 // Iterate through the north patch's points
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                 // North stride is shorter (more vertices)
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                 // Iterate through this patch's points
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                 // Iterate through the north patch's points
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         // Stride lengths are the same
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                 // Main patch
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                 // East patch
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                         // Generate indices
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                 // East stride is longer (has less vertices)
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                 // Iterate through this patch's points
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                 // Iterate through the east patch's points
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                 // East stride is shorter (more vertices)
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                 // Iterate through this patch's points
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                 // Iterate through the east patch's points
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         // First, figure out how many vertices we need...
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         // Stride lengths are the same
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                 // North stride is longer (has less vertices)
00881                 num_vertices += length + (length/2) + 1;
00882                 num_indices += (length/2)*9 - 3;
00883         }
00884         else
00885         {
00886                 // North stride is shorter (more vertices)
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         // Stride lengths are the same
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                 // East stride is longer (has less vertices)
00907                 num_vertices += length + (length/2) + 1;
00908                 num_indices += (length/2)*9 - 3;
00909         }
00910         else
00911         {
00912                 // East stride is shorter (more vertices)
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; // Changing to 2.f makes the culling a -little- better, but still wrong
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         //get vertex buffer striders
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 

Generated on Fri May 16 08:34:23 2008 for SecondLife by  doxygen 1.5.5