llvowater.cpp

Go to the documentation of this file.
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); //128.f //64             // width of wave tile, in meters
00067 const F32 WAVE_STEP_INV = (1. / WAVE_STEP);
00068 
00069 const F32 g                             = 9.81f;          // gravitational constant (m/s^2)
00070 
00071 LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
00072 :       LLStaticViewerObject(id, LL_VO_WATER, regionp)
00073 {
00074         // Terrain must draw during selection passes so it can block objects behind it.
00075         mbCanSelect = FALSE;
00076         setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility.
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 // virtual
00102 void LLVOWater::updateTextures(LLAgent &agent)
00103 {
00104 }
00105 
00106 // Never gets called
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 }

Generated on Thu Jul 1 06:09:45 2010 for Second Life Viewer by  doxygen 1.4.7