summaryrefslogtreecommitdiff
path: root/indra/newview/llvowater.cpp
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2007-03-02 21:25:50 +0000
committerSteven Bennetts <steve@lindenlab.com>2007-03-02 21:25:50 +0000
commit4dabd9c0472deb49573fdafef2fa413e59703f19 (patch)
tree06c680d6a2047e03838d6548bccd26c7baf9d652 /indra/newview/llvowater.cpp
parentd4462963c6ba5db2088723bbedc7b60f1184c594 (diff)
merge release@58699 beta-1-14-0@58707 -> release
Diffstat (limited to 'indra/newview/llvowater.cpp')
-rw-r--r--indra/newview/llvowater.cpp830
1 files changed, 36 insertions, 794 deletions
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 135873b5b8..abff230c4e 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -45,22 +45,8 @@ const F32 WAVE_STEP_INV = (1. / WAVE_STEP);
const F32 g = 9.81f; // gravitational constant (m/s^2)
-///////////////////////////////////
-
-LLWaterSurface::LLWaterSurface() :
- mInitialized(FALSE),
- mWind(9, 0, 0),
- mA(0.2f),
- mVisc(0.001f),
- mShininess(8.0f)
-{}
-
-
-LLWaterGrid *LLVOWater::sGrid = 0;
-
-
LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-: LLViewerObject(id, LL_VO_WATER, regionp)
+: LLStaticViewerObject(id, LL_VO_WATER, regionp)
{
// Terrain must draw during selection passes so it can block objects behind it.
mbCanSelect = FALSE;
@@ -94,18 +80,6 @@ void LLVOWater::updateTextures(LLAgent &agent)
{
}
-// virtual
-void LLVOWater::updateDrawable(BOOL force_damped)
-{
- // Force an immediate rebuild on any update
- if (mDrawable.notNull())
- {
- gPipeline.updateMoveNormalAsync(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- }
- clearChanged(SHIFTED);
-}
-
// Never gets called
BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
@@ -142,17 +116,13 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
- return updateGeometryFlat(drawable);
-}
-
-
-BOOL LLVOWater::updateGeometryFlat(LLDrawable *drawable)
-{
+ LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
LLFace *face;
if (drawable->getNumFaces() < 1)
{
- drawable->addFace(gPipeline.getPool(LLDrawPool::POOL_WATER), NULL);
+ LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
+ drawable->addFace(poolp, NULL);
}
face = drawable->getFace(0);
@@ -161,15 +131,26 @@ BOOL LLVOWater::updateGeometryFlat(LLDrawable *drawable)
LLStrider<LLVector3> verticesp, normalsp;
LLStrider<LLVector2> texCoordsp;
- U32 *indicesp;
+ LLStrider<U32> indicesp;
S32 index_offset;
S32 size = 16;
- S32 num_quads = size*size;
-
- face->setPrimType(LLTriangles);
- face->setSize(4*num_quads, 6*num_quads);
+ if (face->mVertexBuffer.isNull())
+ {
+ S32 num_quads = size*size;
+ face->setSize(4*num_quads, 6*num_quads);
+
+ face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
+ face->mVertexBuffer->allocateBuffer(4*num_quads, 6*num_quads, TRUE);
+ face->setIndicesIndex(0);
+ face->setGeomIndex(0);
+ }
+ else
+ {
+ face->mVertexBuffer->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
+ }
+
index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
if (-1 == index_offset)
{
@@ -179,6 +160,7 @@ BOOL LLVOWater::updateGeometryFlat(LLDrawable *drawable)
LLVector3 position_agent;
position_agent = getPositionAgent();
face->mCenterAgent = position_agent;
+ face->mCenterLocal = position_agent;
S32 x, y;
F32 step_x = getScale().mV[0] / size;
@@ -237,378 +219,20 @@ BOOL LLVOWater::updateGeometryFlat(LLDrawable *drawable)
*indicesp++ = toffset + 2;
}
}
-
-
- mDrawable->movePartition();
- LLPipeline::sCompiles++;
- return TRUE;
-}
-
-
-BOOL LLVOWater::updateGeometryHeightFieldRoam(LLDrawable *drawable)
-{
- LLVector3 position_agent = getPositionAgent();
- const LLVector3 region_size = getScale();
- const LLVector3 region_origin = position_agent - region_size * 0.5f;
-
- S32 patch_origx = llround(region_origin.mV[VX] - sGrid->mRegionOrigin.mV[VX]) / sGrid->mRegionWidth;
- S32 patch_origy = llround(region_origin.mV[VY] - sGrid->mRegionOrigin.mV[VY]) / sGrid->mRegionWidth;
- S32 patch_dimx = llround(region_size.mV[VX]) / sGrid->mRegionWidth;
- S32 patch_dimy = llround(region_size.mV[VY]) / sGrid->mRegionWidth;
-
- static S32 res = (S32)sGrid->mPatchRes;
- if (patch_origx < 0)
- {
- patch_dimx -= - patch_origx;
- if (patch_dimx < 1)
- {
- return TRUE;
- }
- patch_origx = 0;
- }
- if (patch_origy < 0)
- {
- patch_dimy -= - patch_origy;
- if (patch_dimy < 1)
- {
- return TRUE;
- }
- patch_origy = 0;
- }
- if (patch_origx >= res)
- {
- return TRUE;
- }
- if (patch_origy >= res)
- {
- return TRUE;
- }
-
- patch_dimx = llmin<U32>(patch_dimx, res - patch_origx);
- patch_dimy = llmin<U32>(patch_dimy, res - patch_origy);
-
- U32 num_of_tris = 0;
- S32 px, py;
- for (py = patch_origy; py < patch_origy + patch_dimy; py++)
- {
- for (px = patch_origx; px < patch_origx + patch_dimx; px++)
- {
- const U32 ind = py * sGrid->mPatchRes + px;
- if (sGrid->mPatches[ind].visible() && sGrid->mTab[px][py] == 0)
- {
- num_of_tris += sGrid->mPatches[ind].numTris();
- sGrid->mTab[px][py] = this;
- }
- }
- }
-
- if (num_of_tris == 0)
- {
- return TRUE;
- }
-
- if (drawable->getNumFaces() < 1)
- {
- drawable->addFace((LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER),
- gWorldp->getDefaultWaterTexture());
- }
-
- LLFace *face;
-
- face = drawable->getFace(0);
- face->mCenterAgent = position_agent;
-
- LLStrider<LLVector3> verticesp, normalsp;
- LLStrider<LLVector2> texCoordsp;
- U32 *indicesp;
- S32 index_offset;
-
- const F32 water_height = getRegion()->getWaterHeight();
-
- face->setPrimType(LLTriangles);
- face->setSize(3 * num_of_tris, 3 * num_of_tris);
- index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
- if (-1 == index_offset)
- {
- return TRUE;
- }
-
- U32 num_of_vtx = 0;
-
- for (py = patch_origy; py < patch_origy + patch_dimy; py++)
- {
- for (px = patch_origx; px < patch_origx + patch_dimx; px++)
- {
- for (U8 h = 0; h < 2; h++)
- {
- const U32 ind = py * sGrid->mPatchRes + px;
- if (!sGrid->mPatches[ind].visible() || sGrid->mTab[px][py] != this)
- continue;
- LLWaterTri* half = (LLWaterTri*) sGrid->mPatches[ind].half(h);
- for (const LLWaterTri* tri = (LLWaterTri*) half->getFirstLeaf();
- tri != NULL;
- tri = (LLWaterTri*) tri->getNextLeaf())
- {
- /////// check for coordinates
- *(verticesp++) = sGrid->vtx(tri->Lvtx(), water_height);
- *(verticesp++) = sGrid->vtx(tri->Rvtx(), water_height);
- *(verticesp++) = sGrid->vtx(tri->Tvtx(), water_height);
-
- *(normalsp++) = sGrid->norm(tri->Lvtx());
- *(normalsp++) = sGrid->norm(tri->Rvtx());
- *(normalsp++) = sGrid->norm(tri->Tvtx());
-
- *(indicesp++) = index_offset + num_of_vtx + 0;
- *(indicesp++) = index_offset + num_of_vtx + 1;
- *(indicesp++) = index_offset + num_of_vtx + 2;
- num_of_vtx += 3;
- }
- }
- }
- }
-
-
- LLPipeline::sCompiles++;
- return TRUE;
-}
-
-
-
-BOOL LLVOWater::updateGeometryHeightFieldSimple(LLDrawable *drawable)
-{
- LLVector3 position_agent = getPositionAgent();
- const LLVector3 region_size = getScale();
- const LLVector3 region_origin = position_agent - region_size * 0.5f;
-
- S32 patch_origx = llround(region_origin.mV[VX] - sGrid->mRegionOrigin.mV[VX]) / sGrid->mRegionWidth;
- S32 patch_origy = llround(region_origin.mV[VY] - sGrid->mRegionOrigin.mV[VY]) / sGrid->mRegionWidth;
- S32 patch_dimx = llround(region_size.mV[VX]) / sGrid->mRegionWidth;
- S32 patch_dimy = llround(region_size.mV[VY]) / sGrid->mRegionWidth;
-
- static S32 res = sGrid->mPatchRes;
- if (patch_origx < 0)
- {
- patch_dimx -= - patch_origx;
- if (patch_dimx < 1)
- {
- return TRUE;
- }
- patch_origx = 0;
- }
- if (patch_origy < 0)
- {
- patch_dimy -= - patch_origy;
- if (patch_dimy < 1)
- {
- return TRUE;
- }
- patch_origy = 0;
- }
- if (patch_origx >= res)
- {
- return TRUE;
- }
- if (patch_origy >= res)
- {
- return TRUE;
- }
-
- patch_dimx = llmin<U32>(patch_dimx, res - patch_origx);
- patch_dimy = llmin<U32>(patch_dimy, res - patch_origy);
-
-
- U32 num_of_regions = 0;
- S32 px, py;
-
- for (py = patch_origy; py < patch_origy + patch_dimy; py++)
- {
- for (px = patch_origx; px < patch_origx + patch_dimx; px++)
- {
- // if (sGrid->mTab[px][py] != 0)
- // bool stop = true;
- if (sGrid->mPatches[py * sGrid->mPatchRes + px].visible() && sGrid->mTab[px][py] == 0)
- {
- num_of_regions++;
- sGrid->mTab[px][py] = this;
- }
- }
- }
-
- if (num_of_regions == 0)
- {
- return TRUE;
- }
-
- if (drawable->getNumFaces() < 1)
- {
- drawable->addFace((LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER),
- gWorldp->getDefaultWaterTexture());
- }
-
- LLFace *face;
-
- face = drawable->getFace(0);
- face->mCenterAgent = position_agent;
-
- LLStrider<LLVector3> verticesp, normalsp;
- LLStrider<LLVector2> texCoordsp;
- U32 *indicesp;
- S32 index_offset;
-
- const F32 water_height = getRegion()->getWaterHeight();
-
- const U32 steps_in_region = sGrid->mStepsInRegion / sGrid->mResDecrease;
- const U32 num_quads = steps_in_region * steps_in_region * num_of_regions;
-
- face->setPrimType(LLTriangles);
- face->setSize(4*num_quads, 6*num_quads);
- index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
- if (-1 == index_offset)
- {
- return TRUE;
- }
-
- U32 num_of_vtx = 0;
-
- for (py = patch_origy; py < patch_origy + patch_dimy; py++)
- {
- for (px = patch_origx; px < patch_origx + patch_dimx; px++)
- {
- if (!sGrid->mPatches[py * sGrid->mPatchRes + px].visible() || sGrid->mTab[px][py] != this)
- {
- continue;
- }
-
- U32 orig_indx = px * sGrid->mStepsInRegion;
- U32 orig_indy = py * sGrid->mStepsInRegion;
-
- for (U32 qy = 0; qy < steps_in_region; qy++)
- {
- for (U32 qx = 0; qx < steps_in_region; qx++)
- {
- const S32 x0 = orig_indx + qx * sGrid->mResDecrease;
- const S32 y0 = orig_indy + qy * sGrid->mResDecrease;
- const S32 x1 = x0 + sGrid->mResDecrease;
- const S32 y1 = y0 + sGrid->mResDecrease;
-
- sGrid->setVertex(x0, y1, water_height, *(verticesp));
- verticesp++;
- sGrid->setVertex(x0, y0, water_height, *(verticesp));
- verticesp++;
- sGrid->setVertex(x1, y1, water_height, *(verticesp));
- verticesp++;
- sGrid->setVertex(x1, y0, water_height, *(verticesp));
- verticesp++;
- /*
- *(verticesp++) = sGrid->vtx(x0, y1, water_height);
- *(verticesp++) = sGrid->vtx(x0, y0, water_height);
- *(verticesp++) = sGrid->vtx(x1, y1, water_height);
- *(verticesp++) = sGrid->vtx(x1, y0, water_height);
- */
- *(normalsp++) = sGrid->norm(x0, y1);
- *(normalsp++) = sGrid->norm(x0, y0);
- *(normalsp++) = sGrid->norm(x1, y1);
- *(normalsp++) = sGrid->norm(x1, y0);
-
- const S32 curr_index_offset = index_offset + num_of_vtx;
-
- *indicesp++ = curr_index_offset + 0;
- *indicesp++ = curr_index_offset + 1;
- *indicesp++ = curr_index_offset + 2;
-
- *indicesp++ = curr_index_offset + 1;
- *indicesp++ = curr_index_offset + 3;
- *indicesp++ = curr_index_offset + 2;
- num_of_vtx += 4;
- }
- }
- }
- }
-
-
+ mDrawable->movePartition();
LLPipeline::sCompiles++;
return TRUE;
}
void LLVOWater::initClass()
{
- sGrid = new LLWaterGrid;
}
void LLVOWater::cleanupClass()
{
- if (sGrid)
- {
- sGrid->cleanup();
- delete sGrid;
- sGrid = 0;
- }
-}
-
-
-LLWaterGrid::LLWaterGrid() : mResIncrease(1)//0.5)
-{
- init();
}
-
-void LLWaterGrid::init()
-{
- //mRegionOrigin = LLVector3(-2 * mRegionWidth, -2 * mRegionWidth, 0);
- mRegionWidth = 256;
- mPatchRes = 5;
- mMaxGridSize = mPatchRes * mRegionWidth;
- mMinStep = (U32)(WAVE_STEP * mResIncrease);
-
- LLWaterTri::sMinStep = mMinStep;
- LLWaterTri::sQueues = &mRoam;
-
- setGridDim(mMaxGridSize / mMinStep);
-
- mVtx = new LLVector3[mGridDim1 * mGridDim1];
- mNorms = new LLVector3[mGridDim1 * mGridDim1];
-
- mPatches = new LLWaterPatch[mPatchRes * mPatchRes];
-
- mStepsInRegion = mRegionWidth / mMinStep;
- const U32 max_div_level = 2 * (U32)(log((F32)mStepsInRegion) / log(2.0f));
-
- for (U32 y = 0; y < mPatchRes; y++)
- {
- for (U32 x = 0; x < mPatchRes; x++)
- {
- LLVector3 patch_center(mRegionWidth * (x + 0.5f), mRegionWidth * (y + 0.5f), 0);
-
- mPatches[y * mPatchRes + x].set(x * mStepsInRegion, y * mStepsInRegion,
- mStepsInRegion, mRegionWidth, patch_center, max_div_level);
- if (x > 0)
- {
- mPatches[y * mPatchRes + x].left()->setRight(mPatches[y * mPatchRes + x - 1].right());
- mPatches[y * mPatchRes + x - 1].right()->setRight(mPatches[y * mPatchRes + x].left());
- }
- if (y > 0)
- {
- mPatches[y * mPatchRes + x].left()->setLeft(mPatches[(y - 1) * mPatchRes + x].right());
- mPatches[(y - 1) * mPatchRes + x].right()->setLeft(mPatches[y * mPatchRes + x].left());
- }
- }
- }
-}
-
-void LLWaterGrid::cleanup()
-{
- delete[] mVtx;
- mVtx = NULL;
-
- delete[] mNorms;
- mNorms = NULL;
-
- delete[] mPatches;
- mPatches = NULL;
-}
-
-
void setVecZ(LLVector3& v)
{
v.mV[VX] = 0;
@@ -616,413 +240,31 @@ void setVecZ(LLVector3& v)
v.mV[VZ] = 1;
}
-void LLWaterGrid::update()
-{
- static LLViewerRegion* prev_region = gAgent.getRegion();
- LLViewerRegion* region = gAgent.getRegion();
-
- mRegionOrigin = region->getOriginAgent();
- mRegionOrigin.mV[VX] -= 2 * mRegionWidth;
- mRegionOrigin.mV[VY] -= 2 * mRegionWidth;
- mRegionOrigin.mV[VZ] = 0;
-
- const F32 clip_far = gCamera->getFar() - 31;
- const F32 clip_far2 = clip_far * clip_far;
-
- const LLVector3 camera_pos = gAgent.getCameraPositionAgent();
- const LLVector3 look_at = gCamera->getAtAxis();
-
-
- if (camera_pos.mV[VZ] > 200)
- {
- mResDecrease = 4;
- }
- else if (camera_pos.mV[VZ] > 100)
- {
- mResDecrease = 2;
- }
- else
- {
- mResDecrease = 1;
- }
-
-
- //U32 mResDecrease = res_decrease;
- U32 res_decrease = 1;
-
- const F32 res_change = mResIncrease;// * res_decrease ;
-
- F32 height;
-
- // Set the grid
-
- //U32 fractions = 1;
- U32 fractions_res = res_decrease;
- if (res_change < 1)
- {
- //fractions = llround(1. / res_change);
- fractions_res = llround(1.f / mResIncrease);
- }
-
-
- //const U32 fractions_res = fractions * res_decrease;
-
- LLVector3 cur_pos;
- U32 x, y;
- U32 ind = 0;
- for (y = 0; y < mGridDim1; y += fractions_res)
- {
- const F32 dispy = (F32)(y * mMinStep);//step;
- for (x = 0; x < mGridDim1; x += fractions_res)
- {
- const F32 dispx = (F32)(x * mMinStep);//step;
- cur_pos = mRegionOrigin;
- cur_pos.mV[VX] += dispx;
- cur_pos.mV[VY] += dispy;
-
- const F32 x_dist = cur_pos.mV[VX] - camera_pos.mV[VX];
- const F32 y_dist = cur_pos.mV[VY] - camera_pos.mV[VY];
-
- if (x_dist * look_at.mV[VX] + y_dist * look_at.mV[VY] < 0)
- {
- mVtx[ind] = cur_pos;
- setVecZ(mNorms[ind]);
- ind++;
- continue;
- }
-
- const F32 dist_to_vtx2 = x_dist * x_dist + y_dist * y_dist;
- if (dist_to_vtx2 > .81 * clip_far2)
- {
- mVtx[ind] = cur_pos;
- setVecZ(mNorms[ind]);
- ind++;
- continue;
- }
-
- mWater.getIntegerHeightAndNormal(llround(WAVE_STEP_INV * dispx),
- llround(WAVE_STEP_INV * dispy), height, mNorms[ind]);
-
- cur_pos.mV[VZ] += height;
- mVtx[ind] = cur_pos;
- ind++;
- }
- }
-
- if (res_change < 1)
- {
- U32 fractions = llround(1.f / mResIncrease);
- for (y = 0; y < mGridDim1; y += fractions_res)
- {
- for (x = 0; x < mGridDim; x += fractions_res)
- {
- const U32 ind00 = index(x, y);
- const U32 ind01 = ind00 + fractions_res;
- for (U32 frx = 1; frx < fractions; frx += res_decrease)
- {
- const U32 ind = ind00 + frx;
- mNorms[ind] = LERP(mNorms[ind00], mNorms[ind01], frx * res_change);
- mVtx[ind] = LERP( mVtx[ind00], mVtx[ind01], frx * res_change);
- }
- }
- }
- for (x = 0; x < mGridDim1; x += res_decrease)
- {
- for (y = 0; y < mGridDim; y += fractions_res)
- {
- const U32 ind00 = index(x, y);
- const U32 ind10 = ind00 + fractions_res * mGridDim1;//(y + fractions) * quad_resx1 + x;
- for (U32 fry = 1; fry < fractions; fry += res_decrease)
- {
- const U32 ind = ind00 + fry * mGridDim1;//(y + fry) * quad_resx1 + x;
- mNorms[ind] = LERP(mNorms[ind00], mNorms[ind10], fry * res_change);
- mVtx[ind] = LERP( mVtx[ind00], mVtx[ind10], fry * res_change);
- }
- }
- }
- }
-
- if (gUseRoam)
- {
- updateTree(camera_pos, look_at, clip_far, prev_region != region);
- }
- else
- {
- updateVisibility(camera_pos, look_at, clip_far);
- }
-
- prev_region = region;
-
-
- //mTab[0][0] = 0;
- for (y = 0; y < mPatchRes; y++)
- {
- for (x = 0; x < mPatchRes; x++)
- mTab[x][y] = 0;
- }
-
-}
-
-void LLWaterGrid::updateTree(const LLVector3 &camera_pos, const LLVector3 &look_at, F32 clip_far,
- BOOL restart = FALSE)
-{
- static S8 recalculate_frame = 0;
-
- if (restart)
- {
- recalculate_frame = 0;
- }
-
- if (recalculate_frame == 0)
- {
- LLWaterTri::nextRound();
- setCamPosition(LLWaterTri::sCam, camera_pos);
- LLWaterTri::sClipFar = clip_far;
-
-
- const U32 step = (U32)(WAVE_STEP * mResIncrease * mResDecrease);
- const U32 steps_in_region = mRegionWidth / step;
- LLWaterTri::sMaxDivLevel = 2 * llround(log((F32)steps_in_region) / log(2.0f));
-
- for (U32 y = 0; y < mPatchRes; y++)
- {
- for (U32 x = 0; x < mPatchRes; x++)
- {
- U32 patch_ind = y * mPatchRes + x;
- mPatches[patch_ind].updateTree(camera_pos, look_at, mRegionOrigin);
- }
- }
-
- mRoam.process();
-
- // debug
- /*
- for (y = 0; y < mPatchRes; y++)
- {
- for (U32 x = 0; x < mPatchRes; x++)
- {
- //mPatches[y * mPatchRes + x].checkUpToDate();
- //mPatches[y * mPatchRes + x].checkConsistensy();
- mPatches[y * mPatchRes + x].checkCount();
- }
- }
- */
- }
- ++recalculate_frame;
- recalculate_frame = recalculate_frame % 2;
-}
-
-void LLWaterGrid::updateVisibility(const LLVector3 &camera_pos, const LLVector3 &look_at, F32 clip_far)
-{
- for (U32 y = 0; y < mPatchRes; y++)
- {
- for (U32 x = 0; x < mPatchRes; x++)
- {
- mPatches[y * mPatchRes + x].updateVisibility(camera_pos, look_at, mRegionOrigin);
- }
- }
-}
-
-
void LLVOWater::setUseTexture(const BOOL use_texture)
{
mUseTexture = use_texture;
}
-F32 LLWaterSurface::agentDepth() const
+void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax)
{
- const LLViewerRegion* region = gAgent.getRegion();
- LLVector3 position_agent = region->getOriginAgent();// getPositionAgent();
- const LLVector3 region_origin = position_agent;
- const LLVector3 camera_pos = gAgent.getCameraPositionAgent();
+ LLVector3 pos = getPositionAgent();
+ LLVector3 scale = getScale();
- F32 height;
- LLVector3 normal;
+ newMin = pos - scale * 0.5f;
+ newMax = pos + scale * 0.5f;
- getHeightAndNormal(WAVE_STEP_INV * camera_pos.mV[VX],
- WAVE_STEP_INV * camera_pos.mV[VY], height, normal);
- F32 agent_water_height = gAgent.getRegion()->getWaterHeight();
- return camera_pos.mV[VZ] - (agent_water_height + height);
+ mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
}
-////////////////////////////////////////////////
-
-
-void LLWaterSurface::getHeightAndNormal(F32 i, F32 j, F32& wave_height, LLVector3& normal) const
-{
- S32 i_ind = llfloor(i);
- S32 j_ind = llfloor(j);
- F32 i_fr = i - i_ind;
- F32 j_fr = j - j_ind;
-
- i_ind = i_ind % N_RES;
- j_ind = j_ind % N_RES;
-
- S32 i_ind_next = i_ind + 1;
- S32 j_ind_next = j_ind + 1;
- if (i_ind_next == (S32)N_RES) i_ind_next = 0;
- if (j_ind_next == (S32)N_RES) j_ind_next = 0;
-
- const F32 i_fr1 = 1 - i_fr;
- const F32 j_fr1 = 1 - j_fr;
-
- const F32 hi0 = i_fr1 * height(i_ind, j_ind) + i_fr * height(i_ind_next, j_ind);
- const F32 hi1 = i_fr1 * height(i_ind, j_ind_next) + i_fr * height(i_ind_next, j_ind_next);
- wave_height = j_fr1 * hi0 + j_fr * hi1;
-
- normal = i_fr1 * mNorms[i_ind][j_ind];
- normal += i_fr * mNorms[i_ind_next][j_ind];
- LLVector3 vi1 = i_fr1 * mNorms[i_ind][j_ind_next];
- vi1 += i_fr * mNorms[i_ind_next][j_ind_next];
- normal *= j_fr1;
- normal += j_fr * vi1;
-
- //normal.normVec();
-}
-
-void LLWaterSurface::getIntegerHeightAndNormal(S32 i, S32 j, F32& wave_height, LLVector3& normal) const
-{
- S32 i_ind = i % N_RES;
- S32 j_ind = j % N_RES;
-
- wave_height = height(i_ind, j_ind);
- normal = mNorms[i_ind][j_ind];
+U32 LLVOWater::getPartitionType() const
+{
+ return LLPipeline::PARTITION_WATER;
}
-F32 LLWaterSurface::phillips(const LLVector2& k, const LLVector2& wind_n, F32 L, F32 L_small)
+LLWaterPartition::LLWaterPartition()
+: LLSpatialPartition(0)
{
- F32 k2 = k * k;
- F32 k_dot_wind = k * wind_n;
- F32 spectrum = mA * (F32) exp(-1 / (L * L * k2)) / (k2 * k2) * (k_dot_wind * k_dot_wind / k2);
-
- if (k_dot_wind < 0) spectrum *= .25f; // scale down waves that move opposite to the wind
-
- F32 damp = (F32) exp(- k2 * L_small * L_small);
-
- return (spectrum * damp);
+ mRenderByGroup = FALSE;
+ mDrawableType = LLPipeline::RENDER_TYPE_WATER;
+ mPartitionType = LLPipeline::PARTITION_WATER;
}
-
-
-
-void LLWaterSurface::initAmplitudes()
-{
- U16 i, j;
- LLVector2 k;
- F32 sqrtPhillips;
-
- const LLVector2 wind(mWind.mV);
-
- LLVector2 wind_n = wind;
- const F32 wind_vel = wind_n.normVec();
-
- const F32 L = wind_vel * wind_vel / g; // largest wave arising from constant wind of speed wind_vel
-
- const F32 L_small = L / 70; // eliminate waves with very small length (L_small << L)
-
-
- for (i = 0; i <= N_RES; i++)
- {
- k.mV[VX] = (- (S32)N_RES_HALF + i) * (F_TWO_PI / WIDTH);
- for (j = 0; j <= N_RES; j++)
- {
- k.mV[VY] = (- (S32)N_RES_HALF + j) * (F_TWO_PI / WIDTH);
-
- const F32 k_mag = k.magVec();
- mOmega[i][j] = (F32) sqrt(g * k_mag);
-
- if (k_mag < F_APPROXIMATELY_ZERO)
- sqrtPhillips = 0;
- else
- sqrtPhillips = (F32) sqrt(phillips(k, wind_n, L, L_small));
-
- //const F32 r1 = rand() / (F32) RAND_MAX;
- //const F32 r2 = rand() / (F32) RAND_MAX;
- const F32 r1 = randGauss(0, 1);
- const F32 r2 = randGauss(0, 1);
-
- mHtilda0[i][j].re = sqrtPhillips * r1 * OO_SQRT2;
- mHtilda0[i][j].im = sqrtPhillips * r2 * OO_SQRT2;
-
- }
- }
-
- mPlan.init(N_RES, N_RES);
- mInitialized = 1; // initialization complete
-}
-
-void LLWaterSurface::generateWaterHeightField(F64 t)
-{
- S32 i, j;
- S32 mi, mj; // -K indices
- COMPLEX plus, minus;
-
- if (!mInitialized) initAmplitudes();
-
- for (i = 0; i < (S32)N_RES_HALF; i++)
- {
- mi = N_RES - i;
- for (j = 0; j < (S32)N_RES ; j++)
- {
- mj = N_RES - j;
-
- const F32 cos_wt = cosf(mOmega[i][j] * t); // = cos(-mOmega[i][j] * t)
- const F32 sin_wt = sinf(mOmega[i][j] * t); // = -sin(-mOmega[i][j] * t)
- plus.re = mHtilda0[i][j].re * cos_wt - mHtilda0[i][j].im * sin_wt;
- plus.im = mHtilda0[i][j].re * sin_wt + mHtilda0[i][j].im * cos_wt;
- minus.re = mHtilda0[mi][mj].re * cos_wt - mHtilda0[mi][mj].im * sin_wt;
- minus.im = -mHtilda0[mi][mj].re * sin_wt - mHtilda0[mi][mj].im * cos_wt;
-
- // now sum the plus and minus waves to get the total wave amplitude h
- mHtilda[i * N_RES + j].re = plus.re + minus.re;
- mHtilda[i * N_RES + j].im = plus.im + minus.im;
- if (mi < (S32)N_RES && mj < (S32)N_RES)
- {
- mHtilda[mi * N_RES + mj].re = plus.re + minus.re;
- mHtilda[mi * N_RES + mj].im = -plus.im - minus.im;
- }
- }
- }
-
- inverse_fft(mPlan, mHtilda, N_RES, N_RES);
-
- calcNormals();
-}
-
-
-/*
- * Computer normals by taking finite differences.
- */
-
-void LLWaterSurface::calcNormals()
-{
- LLVector3 n;
-
- for (U32 i = 0; i < N_RES; i++)
- {
- for (U32 j = 0; j < N_RES; j++)
- {
- F32 px = heightWrapped(i + 1, j);
- F32 mx = heightWrapped(i - 1, j);
- F32 py = heightWrapped(i, j + 1);
- F32 my = heightWrapped(i, j - 1);
- F32 pxpy = heightWrapped(i + 1, j + 1);
- F32 pxmy = heightWrapped(i + 1, j - 1);
- F32 mxpy = heightWrapped(i - 1, j + 1);
- F32 mxmy = heightWrapped(i - 1, j - 1);
-
- n.mV[VX] = -((2 * px + pxpy + pxmy) - (2 * mx + mxpy + mxmy));
- n.mV[VY] = -((2 * py + pxpy + mxpy) - (2 * my + pxmy + mxmy));
- n.mV[VZ] = 8 * WIDTH / (F32) N_RES;
- n.normVec();
-
- mNorms[i][j] = n;
- }
- }
-}
-
-void LLVOWater::generateNewWaves(F64 time)
-{
- getWaterSurface()->generateWaterHeightField(time);
- sGrid->update();
-}
-