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 #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); //128.f //64             // width of wave tile, in meters
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         // 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         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 // virtual
00103 void LLVOWater::updateTextures(LLAgent &agent)
00104 {
00105 }
00106 
00107 // Never gets called
00108 BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
00109 {
00110         /*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER)))
00111         {
00112                 return TRUE;
00113         }
00114         if (mDrawable) 
00115         {
00116                 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
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 //      LLVector2 uvs[4];
00154 //      LLVector3 vtx[4];
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 }

Generated on Fri May 16 08:34:24 2008 for SecondLife by  doxygen 1.5.5