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