PageRenderTime 37ms CodeModel.GetById 2ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llvowater.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 311 lines | 208 code | 63 blank | 40 comment | 7 complexity | 2ef3910561e6804a97669959657ad10f MD5 | raw file
  1/** 
  2 * @file llvowater.cpp
  3 * @brief LLVOWater class implementation
  4 *
  5 * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "llvowater.h"
 30
 31#include "imageids.h"
 32#include "llviewercontrol.h"
 33
 34#include "lldrawable.h"
 35#include "lldrawpoolwater.h"
 36#include "llface.h"
 37#include "llsky.h"
 38#include "llsurface.h"
 39#include "llvosky.h"
 40#include "llviewercamera.h"
 41#include "llviewertexturelist.h"
 42#include "llviewerregion.h"
 43#include "llworld.h"
 44#include "pipeline.h"
 45#include "llspatialpartition.h"
 46
 47const BOOL gUseRoam = FALSE;
 48
 49
 50///////////////////////////////////
 51
 52template<class T> inline T LERP(T a, T b, F32 factor)
 53{
 54	return a + (b - a) * factor;
 55}
 56
 57const U32 N_RES_HALF	= (N_RES >> 1);
 58
 59const U32 WIDTH			= (N_RES * WAVE_STEP); //128.f //64		// width of wave tile, in meters
 60const F32 WAVE_STEP_INV	= (1. / WAVE_STEP);
 61
 62
 63LLVOWater::LLVOWater(const LLUUID &id, 
 64					 const LLPCode pcode, 
 65					 LLViewerRegion *regionp) :
 66	LLStaticViewerObject(id, pcode, regionp),
 67	mRenderType(LLPipeline::RENDER_TYPE_WATER)
 68{
 69	// Terrain must draw during selection passes so it can block objects behind it.
 70	mbCanSelect = FALSE;
 71	setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility.
 72
 73	mUseTexture = TRUE;
 74	mIsEdgePatch = FALSE;
 75}
 76
 77
 78void LLVOWater::markDead()
 79{
 80	LLViewerObject::markDead();
 81}
 82
 83
 84BOOL LLVOWater::isActive() const
 85{
 86	return FALSE;
 87}
 88
 89
 90void LLVOWater::setPixelAreaAndAngle(LLAgent &agent)
 91{
 92	mAppAngle = 50;
 93	mPixelArea = 500*500;
 94}
 95
 96
 97// virtual
 98void LLVOWater::updateTextures()
 99{
100}
101
102// Never gets called
103BOOL LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
104{
105 	/*if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER)))
106	{
107		return TRUE;
108	}
109	if (mDrawable) 
110	{
111		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
112	}*/
113	return TRUE;
114}
115
116LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline)
117{
118	pipeline->allocDrawable(this);
119	mDrawable->setLit(FALSE);
120	mDrawable->setRenderType(mRenderType);
121
122	LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
123
124	if (mUseTexture)
125	{
126		mDrawable->setNumFaces(1, pool, mRegionp->getLand().getWaterTexture());
127	}
128	else
129	{
130		mDrawable->setNumFaces(1, pool, LLWorld::getInstance()->getDefaultWaterTexture());
131	}
132
133	return mDrawable;
134}
135
136static LLFastTimer::DeclareTimer FTM_UPDATE_WATER("Update Water");
137
138BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
139{
140	LLFastTimer ftm(FTM_UPDATE_WATER);
141	LLFace *face;
142
143	if (drawable->getNumFaces() < 1)
144	{
145		LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
146		drawable->addFace(poolp, NULL);
147	}
148	face = drawable->getFace(0);
149
150//	LLVector2 uvs[4];
151//	LLVector3 vtx[4];
152
153	LLStrider<LLVector3> verticesp, normalsp;
154	LLStrider<LLVector2> texCoordsp;
155	LLStrider<U16> indicesp;
156	U16 index_offset;
157
158
159	// A quad is 4 vertices and 6 indices (making 2 triangles)
160	static const unsigned int vertices_per_quad = 4;
161	static const unsigned int indices_per_quad = 6;
162
163	const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") && !LLGLSLShader::sNoFixedFunction ? 16 : 1;
164
165	const S32 num_quads = size * size;
166	face->setSize(vertices_per_quad * num_quads,
167				  indices_per_quad * num_quads);
168	
169	LLVertexBuffer* buff = face->getVertexBuffer();
170	if (!buff)
171	{
172		buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
173		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
174		face->setIndicesIndex(0);
175		face->setGeomIndex(0);
176		face->setVertexBuffer(buff);
177	}
178	else
179	{
180		buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
181	}
182		
183	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
184		
185	LLVector3 position_agent;
186	position_agent = getPositionAgent();
187	face->mCenterAgent = position_agent;
188	face->mCenterLocal = position_agent;
189
190	S32 x, y;
191	F32 step_x = getScale().mV[0] / size;
192	F32 step_y = getScale().mV[1] / size;
193
194	const LLVector3 up(0.f, step_y * 0.5f, 0.f);
195	const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
196	const LLVector3 normal(0.f, 0.f, 1.f);
197
198	F32 size_inv = 1.f / size;
199
200	for (y = 0; y < size; y++)
201	{
202		for (x = 0; x < size; x++)
203		{
204			S32 toffset = index_offset + 4*(y*size + x);
205			position_agent = getPositionAgent() - getScale() * 0.5f;
206			position_agent.mV[VX] += (x + 0.5f) * step_x;
207			position_agent.mV[VY] += (y + 0.5f) * step_y;
208
209			*verticesp++  = position_agent - right + up;
210			*verticesp++  = position_agent - right - up;
211			*verticesp++  = position_agent + right + up;
212			*verticesp++  = position_agent + right - up;
213
214			*texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv);
215			*texCoordsp++ = LLVector2(x*size_inv, y*size_inv);
216			*texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv);
217			*texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv);
218			
219			*normalsp++   = normal;
220			*normalsp++   = normal;
221			*normalsp++   = normal;
222			*normalsp++   = normal;
223
224			*indicesp++ = toffset + 0;
225			*indicesp++ = toffset + 1;
226			*indicesp++ = toffset + 2;
227
228			*indicesp++ = toffset + 1;
229			*indicesp++ = toffset + 3;
230			*indicesp++ = toffset + 2;
231		}
232	}
233	
234	buff->flush();
235
236	mDrawable->movePartition();
237	LLPipeline::sCompiles++;
238	return TRUE;
239}
240
241void LLVOWater::initClass()
242{
243}
244
245void LLVOWater::cleanupClass()
246{
247}
248
249void setVecZ(LLVector3& v)
250{
251	v.mV[VX] = 0;
252	v.mV[VY] = 0;
253	v.mV[VZ] = 1;
254}
255
256void LLVOWater::setUseTexture(const BOOL use_texture)
257{
258	mUseTexture = use_texture;
259}
260
261void LLVOWater::setIsEdgePatch(const BOOL edge_patch)
262{
263	mIsEdgePatch = edge_patch;
264}
265
266void LLVOWater::updateSpatialExtents(LLVector4a &newMin, LLVector4a& newMax)
267{
268	LLVector4a pos;
269	pos.load3(getPositionAgent().mV);
270	LLVector4a scale;
271	scale.load3(getScale().mV);
272	scale.mul(0.5f);
273
274	newMin.setSub(pos, scale);
275	newMax.setAdd(pos, scale);
276	
277	pos.setAdd(newMin,newMax);
278	pos.mul(0.5f);
279
280	mDrawable->setPositionGroup(pos);
281}
282
283U32 LLVOWater::getPartitionType() const
284{ 
285	if (mIsEdgePatch)
286	{
287		return LLViewerRegion::PARTITION_VOIDWATER;
288	}
289
290	return LLViewerRegion::PARTITION_WATER; 
291}
292
293U32 LLVOVoidWater::getPartitionType() const
294{
295	return LLViewerRegion::PARTITION_VOIDWATER;
296}
297
298LLWaterPartition::LLWaterPartition()
299: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
300{
301	mInfiniteFarClip = TRUE;
302	mDrawableType = LLPipeline::RENDER_TYPE_WATER;
303	mPartitionType = LLViewerRegion::PARTITION_WATER;
304}
305
306LLVoidWaterPartition::LLVoidWaterPartition()
307{
308	mOcclusionEnabled = FALSE;
309	mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER;
310	mPartitionType = LLViewerRegion::PARTITION_VOIDWATER;
311}