diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/llvosurfacepatch.cpp |
Print done when done.
Diffstat (limited to 'indra/newview/llvosurfacepatch.cpp')
-rw-r--r-- | indra/newview/llvosurfacepatch.cpp | 924 |
1 files changed, 924 insertions, 0 deletions
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp new file mode 100644 index 0000000000..ae7d46dfee --- /dev/null +++ b/indra/newview/llvosurfacepatch.cpp @@ -0,0 +1,924 @@ +/** + * @file llvosurfacepatch.cpp + * @brief Viewer-object derived "surface patch", which is a piece of terrain + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llvosurfacepatch.h" + +#include "lldrawable.h" +#include "llface.h" +#include "llprimitive.h" +#include "llsky.h" +#include "llsurfacepatch.h" +#include "llsurface.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llvlcomposition.h" +#include "llvovolume.h" +#include "pipeline.h" + +LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) +: LLViewerObject(id, LL_VO_SURFACE_PATCH, regionp) +{ + // Terrain must draw during selection passes so it can block objects behind it. + mbCanSelect = TRUE; + + mBaseComp = 0; + setScale(LLVector3(16.f, 16.f, 16.f)); // Hack for setting scale for bounding boxes/visibility. + mPool = NULL; + mDirtiedPatch = FALSE; + mLastStride = 0; + mLastNorthStride = 0; + mLastEastStride = 0; + mLastLength = 0; + + mDirtyTerrain = TRUE; +} + + +LLVOSurfacePatch::~LLVOSurfacePatch() +{ + mPatchp = NULL; +} + + +void LLVOSurfacePatch::markDead() +{ + if (mPatchp) + { + mPatchp->clearVObj(); + mPatchp = NULL; + } + LLViewerObject::markDead(); +} + + +BOOL LLVOSurfacePatch::isActive() const +{ + return FALSE; +} + + +void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent) +{ + mAppAngle = 50; + mPixelArea = 500*500; +} + + +void LLVOSurfacePatch::updateTextures(LLAgent &agent) +{ +} + + +LLDrawPool *LLVOSurfacePatch::getPool() +{ + mPool = gPipeline.getPool(LLDrawPool::POOL_TERRAIN, mPatchp->getSurface()->getSTexture()); + + return mPool; +} + + +LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) +{ + pipeline->allocDrawable(this); + + mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TERRAIN); + + mBaseComp = llfloor(mPatchp->getMinComposition()); + S32 min_comp, max_comp, range; + min_comp = llfloor(mPatchp->getMinComposition()); + max_comp = llceil(mPatchp->getMaxComposition()); + range = (max_comp - min_comp); + range++; + if (range > 3) + { + if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition())) + { + // The top side runs over more + mBaseComp++; + } + range = 3; + } + + LLDrawPool *poolp = getPool(); + + mDrawable->addFace(poolp, NULL); + return mDrawable; +} + + +BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) +{ + S32 min_comp, max_comp, range; + min_comp = lltrunc(mPatchp->getMinComposition()); + max_comp = lltrunc(ceil(mPatchp->getMaxComposition())); + range = (max_comp - min_comp); + range++; + S32 new_base_comp = lltrunc(mPatchp->getMinComposition()); + if (range > 3) + { + if ((mPatchp->getMinComposition() - min_comp) > (max_comp - mPatchp->getMaxComposition())) + { + // The top side runs over more + new_base_comp++; + } + range = 3; + } + + // Pick the two closest detail textures for this patch... + // Then create the draw pool for it. + // Actually, should get the average composition instead of the center. + mBaseComp = new_base_comp; + + ////////////////////////// + // + // Figure out the strides + // + // + + U32 patch_width, render_stride, north_stride, east_stride, length; + render_stride = mPatchp->getRenderStride(); + patch_width = mPatchp->getSurface()->getGridsPerPatchEdge(); + + length = patch_width / render_stride; + + if (mPatchp->getNeighborPatch(NORTH)) + { + north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride(); + } + else + { + north_stride = render_stride; + } + + if (mPatchp->getNeighborPatch(EAST)) + { + east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride(); + } + else + { + east_stride = render_stride; + } + + S32 num_vertices = 0; + S32 num_indices = 0; + S32 new_north_offset = 0; + S32 new_east_offset = 0; + + getGeomSizesMain(render_stride, num_vertices, num_indices); + new_north_offset = num_vertices; + getGeomSizesNorth(render_stride, north_stride, num_vertices, num_indices); + new_east_offset = num_vertices; + getGeomSizesEast(render_stride, east_stride, num_vertices, num_indices); + S32 new_num_vertices = num_vertices; + S32 new_num_indices = num_indices; + + LLFace *facep = NULL; + + // Update the allocated face + LLStrider<LLVector3> verticesp; + LLStrider<LLVector3> normalsp; + LLStrider<LLVector2> texCoords0p; + LLStrider<LLVector2> texCoords1p; + LLStrider<LLColor4U> colorsp; + U32* indicesp = NULL; + S32 index_offset; + + facep = mDrawable->getFace(0); + + facep->setSize(new_num_vertices, new_num_indices); + facep->setPrimType(LLTriangles); + + index_offset = facep->getGeometryTerrain( + verticesp, + normalsp, + colorsp, + texCoords0p, + texCoords1p, + indicesp); + if (-1 == index_offset) + { + return TRUE; + } + + mDrawable->updateLightSet(); + + updateMainGeometry(facep, + verticesp, + normalsp, + colorsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateNorthGeometry(facep, + verticesp, + normalsp, + colorsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + updateEastGeometry(facep, + verticesp, + normalsp, + colorsp, + texCoords0p, + texCoords1p, + indicesp, + index_offset); + + if (mLastLength != 0) + { + // lazy, should cache the geom sizes so we know the offsets. + num_vertices = 0; + num_indices = 0; + + } + + mLastLength = length; + mLastStride = render_stride; + mLastNorthStride = north_stride; + mLastEastStride = east_stride; + + mDrawable->setState(LLDrawable::LIGHTING_BUILT); + + LLPipeline::sCompiles++; + return TRUE; +} + +void LLVOSurfacePatch::updateMainGeometry(LLFace *facep, + LLStrider<LLVector3> &verticesp, + LLStrider<LLVector3> &normalsp, + LLStrider<LLColor4U> &colorsp, + LLStrider<LLVector2> &texCoords0p, + LLStrider<LLVector2> &texCoords1p, + U32* &indicesp, + S32 &index_offset) +{ + S32 i, j, x, y; + + U32 patch_size, render_stride; + S32 num_vertices, num_indices; + U32 index; + + render_stride = mPatchp->getRenderStride(); + patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 vert_size = patch_size / render_stride; + + /////////////////////////// + // + // Render the main patch + // + // + + num_vertices = 0; + num_indices = 0; + // First, figure out how many vertices we need... + getGeomSizesMain(render_stride, num_vertices, num_indices); + + if (num_vertices > 0) + { + facep->mCenterAgent = mPatchp->getPointAgent(8, 8); + + // Generate patch points first + for (j = 0; j < vert_size; j++) + { + for (i = 0; i < vert_size; i++) + { + x = i * render_stride; + y = j * render_stride; + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + } + + for (j = 0; j < (vert_size - 1); j++) + { + if (j % 2) + { + for (i = (vert_size - 1); i > 0; i--) + { + index = (i - 1)+ j*vert_size; + *(indicesp++) = index_offset + index; + + index = i + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = (i - 1) + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = (i - 1) + j*vert_size; + *(indicesp++) = index_offset + index; + + index = i + j*vert_size; + *(indicesp++) = index_offset + index; + + index = i + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + } + } + else + { + for (i = 0; i < (vert_size - 1); i++) + { + index = i + j*vert_size; + *(indicesp++) = index_offset + index; + + index = (i + 1) + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = i + (j+1)*vert_size; + *(indicesp++) = index_offset + index; + + index = i + j*vert_size; + *(indicesp++) = index_offset + index; + + index = (i + 1) + j*vert_size; + *(indicesp++) = index_offset + index; + + index = (i + 1) + (j + 1)*vert_size; + *(indicesp++) = index_offset + index; + } + } + } + } + index_offset += num_vertices; +} + + +void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep, + LLStrider<LLVector3> &verticesp, + LLStrider<LLVector3> &normalsp, + LLStrider<LLColor4U> &colorsp, + LLStrider<LLVector2> &texCoords0p, + LLStrider<LLVector2> &texCoords1p, + U32* &indicesp, + S32 &index_offset) +{ + S32 vertex_count = 0; + S32 i, x, y; + + S32 num_vertices, num_indices; + + U32 render_stride = mPatchp->getRenderStride(); + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / render_stride; + S32 half_length = length / 2; + + U32 north_stride; + if (mPatchp->getNeighborPatch(NORTH)) + { + north_stride = mPatchp->getNeighborPatch(NORTH)->getRenderStride(); + } + else + { + north_stride = render_stride; + } + + /////////////////////////// + // + // Render the north strip + // + // + + // Stride lengths are the same + if (north_stride == render_stride) + { + num_vertices = 2 * length + 1; + num_indices = length * 6 - 3; + + facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Main patch + for (i = 0; i < length; i++) + { + x = i * render_stride; + y = 16 - render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + vertex_count++; + } + + // North patch + for (i = 0; i <= length; i++) + { + x = i * render_stride; + y = 16; + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + vertex_count++; + } + + + for (i = 0; i < length; i++) + { + // Generate indices + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + i + 1; + *(indicesp++) = index_offset + length + i; + + if (i != length - 1) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + i + 1; + } + } + } + else if (north_stride > render_stride) + { + // North stride is longer (has less vertices) + num_vertices = length + length/2 + 1; + num_indices = half_length*9 - 3; + + facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i++) + { + x = i * render_stride; + y = 16 - render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + vertex_count++; + } + + // Iterate through the north patch's points + for (i = 0; i <= length; i+=2) + { + x = i * render_stride; + y = 16; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + vertex_count++; + } + + + for (i = 0; i < length; i++) + { + if (!(i % 2)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2); + + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2) + 1; + *(indicesp++) = index_offset + length + (i/2); + } + else if (i < (length - 1)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2) + 1; + } + } + } + else + { + // North stride is shorter (more vertices) + length = patch_size / north_stride; + half_length = length / 2; + num_vertices = length + half_length + 1; + num_indices = 9*half_length - 3; + + facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i+=2) + { + x = i * north_stride; + y = 16 - render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + vertex_count++; + } + + // Iterate through the north patch's points + for (i = 0; i <= length; i++) + { + x = i * north_stride; + y = 16; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + vertex_count++; + } + + for (i = 0; i < length; i++) + { + if (!(i%2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2; + *(indicesp++) = index_offset + half_length + i + 1; + } + else if (i < (length - 2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2; + *(indicesp++) = index_offset + i/2 + 1; + + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2 + 1; + *(indicesp++) = index_offset + half_length + i + 1; + } + else + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2; + *(indicesp++) = index_offset + half_length + i + 1; + } + } + } + index_offset += num_vertices; +} + +void LLVOSurfacePatch::updateEastGeometry(LLFace *facep, + LLStrider<LLVector3> &verticesp, + LLStrider<LLVector3> &normalsp, + LLStrider<LLColor4U> &colorsp, + LLStrider<LLVector2> &texCoords0p, + LLStrider<LLVector2> &texCoords1p, + U32* &indicesp, + S32 &index_offset) +{ + S32 i, x, y; + + S32 num_vertices, num_indices; + + U32 render_stride = mPatchp->getRenderStride(); + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / render_stride; + S32 half_length = length / 2; + + U32 east_stride; + if (mPatchp->getNeighborPatch(EAST)) + { + east_stride = mPatchp->getNeighborPatch(EAST)->getRenderStride(); + } + else + { + east_stride = render_stride; + } + + // Stride lengths are the same + if (east_stride == render_stride) + { + num_vertices = 2 * length + 1; + num_indices = length * 6 - 3; + + facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Main patch + for (i = 0; i < length; i++) + { + x = 16 - render_stride; + y = i * render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + + // East patch + for (i = 0; i <= length; i++) + { + x = 16; + y = i * render_stride; + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + + + for (i = 0; i < length; i++) + { + // Generate indices + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + i; + *(indicesp++) = index_offset + length + i + 1; + + if (i != length - 1) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + i + 1; + *(indicesp++) = index_offset + i + 1; + } + } + } + else if (east_stride > render_stride) + { + // East stride is longer (has less vertices) + num_vertices = length + half_length + 1; + num_indices = half_length*9 - 3; + + facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i++) + { + x = 16 - render_stride; + y = i * render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + // Iterate through the east patch's points + for (i = 0; i <= length; i+=2) + { + x = 16; + y = i * render_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + + for (i = 0; i < length; i++) + { + if (!(i % 2)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + (i/2); + *(indicesp++) = index_offset + i + 1; + + *(indicesp++) = index_offset + i + 1; + *(indicesp++) = index_offset + length + (i/2); + *(indicesp++) = index_offset + length + (i/2) + 1; + } + else if (i < (length - 1)) + { + *(indicesp++) = index_offset + i; + *(indicesp++) = index_offset + length + (i/2) + 1; + *(indicesp++) = index_offset + i + 1; + } + } + } + else + { + // East stride is shorter (more vertices) + length = patch_size / east_stride; + half_length = length / 2; + num_vertices = length + length/2 + 1; + num_indices = 9*(length/2) - 3; + + facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f; + + // Iterate through this patch's points + for (i = 0; i < length; i+=2) + { + x = 16 - render_stride; + y = i * east_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + // Iterate through the east patch's points + for (i = 0; i <= length; i++) + { + x = 16; + y = i * east_stride; + + mPatchp->eval(x, y, render_stride, verticesp.get(), normalsp.get(), texCoords0p.get(), texCoords1p.get()); + calcColor(verticesp.get(), normalsp.get(), colorsp.get()); + verticesp++; + normalsp++; + colorsp++; + texCoords0p++; + texCoords1p++; + } + + for (i = 0; i < length; i++) + { + if (!(i%2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + half_length + i + 1; + *(indicesp++) = index_offset + i/2; + } + else if (i < (length - 2)) + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + i/2 + 1; + *(indicesp++) = index_offset + i/2; + + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + half_length + i + 1; + *(indicesp++) = index_offset + i/2 + 1; + } + else + { + *(indicesp++) = index_offset + half_length + i; + *(indicesp++) = index_offset + half_length + i + 1; + *(indicesp++) = index_offset + i/2; + } + } + } + index_offset += num_vertices; +} + +void LLVOSurfacePatch::calcColor(const LLVector3* vertex, const LLVector3* normal, LLColor4U* colorp) +{ + LLColor4 color(0,0,0,0); + if (gPipeline.getLightingDetail() >= 2) + { + for (LLDrawable::drawable_set_t::iterator iter = mDrawable->mLightSet.begin(); + iter != mDrawable->mLightSet.end(); ++iter) + { + LLDrawable* light_drawable = *iter; + LLVOVolume* light = light_drawable->getVOVolume(); + if (!light) + { + continue; + } + LLColor4 light_color; + light->calcLightAtPoint(*vertex, *normal, light_color); + color += light_color; + } + + color.mV[3] = 1.0f; + } + colorp->setVecScaleClamp(color); +} + +BOOL LLVOSurfacePatch::updateShadows(BOOL use_shadow_factor) +{ + return FALSE; //terrain updates its shadows during standard relight +} + +void LLVOSurfacePatch::setPatch(LLSurfacePatch *patchp) +{ + mPatchp = patchp; + + dirtyPatch(); +}; + + +void LLVOSurfacePatch::dirtyPatch() +{ + if (mDrawable) + { + gPipeline.markMoved(mDrawable); + } + mDirtiedPatch = TRUE; + dirtyGeom(); + mDirtyTerrain = TRUE; + LLVector3 center = mPatchp->getCenterRegion(); + LLSurface *surfacep = mPatchp->getSurface(); + + setPositionRegion(center); + + F32 scale_factor = surfacep->getGridsPerPatchEdge() * surfacep->getMetersPerGrid(); + setScale(LLVector3(scale_factor, scale_factor, mPatchp->getMaxZ() - mPatchp->getMinZ())); +} + +void LLVOSurfacePatch::dirtyGeom() +{ + if (mDrawable) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); + } +} + +void LLVOSurfacePatch::getGeomSizesMain(const S32 stride, S32 &num_vertices, S32 &num_indices) +{ + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + + // First, figure out how many vertices we need... + S32 vert_size = patch_size / stride; + if (vert_size >= 2) + { + num_vertices += vert_size * vert_size; + num_indices += 6 * (vert_size - 1)*(vert_size - 1); + } +} + +void LLVOSurfacePatch::getGeomSizesNorth(const S32 stride, const S32 north_stride, + S32 &num_vertices, S32 &num_indices) +{ + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / stride; + // Stride lengths are the same + if (north_stride == stride) + { + num_vertices += 2 * length + 1; + num_indices += length * 6 - 3; + } + else if (north_stride > stride) + { + // North stride is longer (has less vertices) + num_vertices += length + (length/2) + 1; + num_indices += (length/2)*9 - 3; + } + else + { + // North stride is shorter (more vertices) + length = patch_size / north_stride; + num_vertices += length + (length/2) + 1; + num_indices += 9*(length/2) - 3; + } +} + +void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride, + S32 &num_vertices, S32 &num_indices) +{ + S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge(); + S32 length = patch_size / stride; + // Stride lengths are the same + if (east_stride == stride) + { + num_vertices += 2 * length + 1; + num_indices += length * 6 - 3; + } + else if (east_stride > stride) + { + // East stride is longer (has less vertices) + num_vertices += length + (length/2) + 1; + num_indices += (length/2)*9 - 3; + } + else + { + // East stride is shorter (more vertices) + length = patch_size / east_stride; + num_vertices += length + (length/2) + 1; + num_indices += 9*(length/2) - 3; + } +} + +void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) +{ + LLVector3 posAgent = getPositionAgent(); + LLVector3 scale = getScale(); + newMin = posAgent-scale; + newMax = posAgent+scale; + mDrawable->setPositionGroup((newMin+newMax)*0.5f); +} |