00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llvowater.h"
00035
00036 #include "imageids.h"
00037 #include "llviewercontrol.h"
00038
00039 #include "llagent.h"
00040 #include "lldrawable.h"
00041 #include "lldrawpoolwater.h"
00042 #include "llface.h"
00043 #include "llsky.h"
00044 #include "llsurface.h"
00045 #include "llvosky.h"
00046 #include "llviewercamera.h"
00047 #include "llviewerimagelist.h"
00048 #include "llviewerregion.h"
00049 #include "llworld.h"
00050 #include "pipeline.h"
00051
00052 const BOOL gUseRoam = FALSE;
00053
00054
00056
00057 #include "randgauss.h"
00058
00059 template<class T> inline T LERP(T a, T b, F32 factor)
00060 {
00061 return a + (b - a) * factor;
00062 }
00063
00064 const U32 N_RES_HALF = (N_RES >> 1);
00065
00066 const U32 WIDTH = (N_RES * WAVE_STEP);
00067 const F32 WAVE_STEP_INV = (1. / WAVE_STEP);
00068
00069 const F32 g = 9.81f;
00070
00071 LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00072 : LLStaticViewerObject(id, LL_VO_WATER, regionp)
00073 {
00074
00075 mbCanSelect = FALSE;
00076 setScale(LLVector3(256.f, 256.f, 0.f));
00077
00078 mUseTexture = TRUE;
00079 }
00080
00081
00082 void LLVOWater::markDead()
00083 {
00084 LLViewerObject::markDead();
00085 }
00086
00087
00088 BOOL LLVOWater::isActive() const
00089 {
00090 return FALSE;
00091 }
00092
00093
00094 void LLVOWater::setPixelAreaAndAngle(LLAgent &agent)
00095 {
00096 mAppAngle = 50;
00097 mPixelArea = 500*500;
00098 }
00099
00100
00101
00102 void LLVOWater::updateTextures(LLAgent &agent)
00103 {
00104 }
00105
00106
00107 BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
00108 {
00109 if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER)))
00110 {
00111 return TRUE;
00112 }
00113 if (mDrawable)
00114 {
00115 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
00116 }
00117 return TRUE;
00118 }
00119
00120 LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
00121 {
00122 pipeline->allocDrawable(this);
00123 mDrawable->setLit(FALSE);
00124 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_WATER);
00125
00126 LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
00127
00128 if (mUseTexture)
00129 {
00130 mDrawable->setNumFaces(1, pool, mRegionp->getLand().getWaterTexture());
00131 }
00132 else
00133 {
00134 mDrawable->setNumFaces(1, pool, gWorldp->getDefaultWaterTexture());
00135 }
00136
00137 return mDrawable;
00138 }
00139
00140 BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
00141 {
00142 LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
00143 LLFace *face;
00144
00145 if (drawable->getNumFaces() < 1)
00146 {
00147 LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
00148 drawable->addFace(poolp, NULL);
00149 }
00150 face = drawable->getFace(0);
00151
00152 LLVector2 uvs[4];
00153 LLVector3 vtx[4];
00154
00155 LLStrider<LLVector3> verticesp, normalsp;
00156 LLStrider<LLVector2> texCoordsp;
00157 LLStrider<U32> indicesp;
00158 S32 index_offset;
00159
00160 S32 size = 16;
00161
00162 if (face->mVertexBuffer.isNull())
00163 {
00164 S32 num_quads = size*size;
00165 face->setSize(4*num_quads, 6*num_quads);
00166
00167 face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
00168 face->mVertexBuffer->allocateBuffer(4*num_quads, 6*num_quads, TRUE);
00169 face->setIndicesIndex(0);
00170 face->setGeomIndex(0);
00171 }
00172 else
00173 {
00174 face->mVertexBuffer->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
00175 }
00176
00177 index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
00178 if (-1 == index_offset)
00179 {
00180 return TRUE;
00181 }
00182
00183 LLVector3 position_agent;
00184 position_agent = getPositionAgent();
00185 face->mCenterAgent = position_agent;
00186 face->mCenterLocal = position_agent;
00187
00188 S32 x, y;
00189 F32 step_x = getScale().mV[0] / size;
00190 F32 step_y = getScale().mV[1] / size;
00191
00192 const LLVector3 up(0.f, step_y * 0.5f, 0.f);
00193 const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
00194 const LLVector3 normal(0.f, 0.f, 1.f);
00195
00196 F32 size_inv = 1.f / size;
00197
00198 for (y = 0; y < size; y++)
00199 {
00200 for (x = 0; x < size; x++)
00201 {
00202 S32 toffset = index_offset + 4*(y*size + x);
00203 position_agent = getPositionAgent() - getScale() * 0.5f;
00204 position_agent.mV[VX] += (x + 0.5f) * step_x;
00205 position_agent.mV[VY] += (y + 0.5f) * step_y;
00206
00207 vtx[0] = position_agent - right + up;
00208 vtx[1] = position_agent - right - up;
00209 vtx[2] = position_agent + right + up;
00210 vtx[3] = position_agent + right - up;
00211
00212 *(verticesp++) = vtx[0];
00213 *(verticesp++) = vtx[1];
00214 *(verticesp++) = vtx[2];
00215 *(verticesp++) = vtx[3];
00216
00217 uvs[0].setVec(x*size_inv, (y+1)*size_inv);
00218 uvs[1].setVec(x*size_inv, y*size_inv);
00219 uvs[2].setVec((x+1)*size_inv, (y+1)*size_inv);
00220 uvs[3].setVec((x+1)*size_inv, y*size_inv);
00221
00222 *(texCoordsp) = uvs[0];
00223 texCoordsp++;
00224 *(texCoordsp) = uvs[1];
00225 texCoordsp++;
00226 *(texCoordsp) = uvs[2];
00227 texCoordsp++;
00228 *(texCoordsp) = uvs[3];
00229 texCoordsp++;
00230
00231 *(normalsp++) = normal;
00232 *(normalsp++) = normal;
00233 *(normalsp++) = normal;
00234 *(normalsp++) = normal;
00235
00236 *indicesp++ = toffset + 0;
00237 *indicesp++ = toffset + 1;
00238 *indicesp++ = toffset + 2;
00239
00240 *indicesp++ = toffset + 1;
00241 *indicesp++ = toffset + 3;
00242 *indicesp++ = toffset + 2;
00243 }
00244 }
00245
00246 mDrawable->movePartition();
00247 LLPipeline::sCompiles++;
00248 return TRUE;
00249 }
00250
00251 void LLVOWater::initClass()
00252 {
00253 }
00254
00255 void LLVOWater::cleanupClass()
00256 {
00257 }
00258
00259 void setVecZ(LLVector3& v)
00260 {
00261 v.mV[VX] = 0;
00262 v.mV[VY] = 0;
00263 v.mV[VZ] = 1;
00264 }
00265
00266 void LLVOWater::setUseTexture(const BOOL use_texture)
00267 {
00268 mUseTexture = use_texture;
00269 }
00270
00271 void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax)
00272 {
00273 LLVector3 pos = getPositionAgent();
00274 LLVector3 scale = getScale();
00275
00276 newMin = pos - scale * 0.5f;
00277 newMax = pos + scale * 0.5f;
00278
00279 mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
00280 }
00281
00282 U32 LLVOWater::getPartitionType() const
00283 {
00284 return LLPipeline::PARTITION_WATER;
00285 }
00286
00287 LLWaterPartition::LLWaterPartition()
00288 : LLSpatialPartition(0)
00289 {
00290 mRenderByGroup = FALSE;
00291 mDrawableType = LLPipeline::RENDER_TYPE_WATER;
00292 mPartitionType = LLPipeline::PARTITION_WATER;
00293 }