PageRenderTime 479ms CodeModel.GetById 78ms app.highlight 210ms RepoModel.GetById 82ms app.codeStats 0ms

/indra/newview/llsky.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 481 lines | 346 code | 80 blank | 55 comment | 38 complexity | 2435c0d98c0de3b7f5655950a20ecc56 MD5 | raw file
  1/** 
  2 * @file llsky.cpp
  3 * @brief IndraWorld sky class 
  4 *
  5 * $LicenseInfo:firstyear=2000&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//	Ideas:
 28//		-haze should be controlled by global query from sims
 29//		-need secondary optical effects on sun (flare)
 30//		-stars should be brought down from sims
 31//		-star intensity should be driven by global ambient level from sims,
 32//		 so that eclipses, etc can be easily done.
 33//
 34
 35#include "llviewerprecompiledheaders.h"
 36
 37#include "llsky.h"
 38
 39// linden library includes
 40#include "llerror.h"
 41#include "llmath.h"
 42#include "math.h"
 43#include "v4color.h"
 44
 45#include "llviewerobjectlist.h"
 46#include "llviewerobject.h"
 47#include "llviewercamera.h"
 48#include "pipeline.h"
 49#include "lldrawpool.h"
 50
 51#include "llvosky.h"
 52#include "llcubemap.h"
 53#include "llviewercontrol.h"
 54
 55#include "llvowlsky.h"
 56
 57F32 azimuth_from_vector(const LLVector3 &v);
 58F32 elevation_from_vector(const LLVector3 &v);
 59
 60LLSky				gSky;
 61// ---------------- LLSky ----------------
 62
 63const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees
 64const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD);
 65
 66//////////////////////////////////////////////////////////////////////
 67// Construction/Destruction
 68//////////////////////////////////////////////////////////////////////
 69
 70LLSky::LLSky()
 71{
 72	// Set initial clear color to black
 73	// Set fog color 
 74	mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
 75	mFogColor.mV[VALPHA] = 0.0f;
 76
 77	mLightingGeneration = 0;
 78	mUpdatedThisFrame = TRUE;
 79	mOverrideSimSunPosition = FALSE;
 80	mSunPhase = 0.f;
 81}
 82
 83
 84LLSky::~LLSky()
 85{
 86}
 87
 88void LLSky::cleanup()
 89{
 90	mVOSkyp = NULL;
 91	mVOWLSkyp = NULL;
 92	mVOGroundp = NULL;
 93}
 94
 95void LLSky::destroyGL()
 96{
 97	if (!mVOSkyp.isNull() && mVOSkyp->getCubeMap())
 98	{
 99		mVOSkyp->cleanupGL();
100	}
101	if (mVOWLSkyp.notNull())
102	{
103		mVOWLSkyp->cleanupGL();
104	}
105}
106
107void LLSky::restoreGL()
108{
109	if (mVOSkyp)
110	{
111		mVOSkyp->restoreGL();
112	}
113	if (mVOWLSkyp)
114	{
115		mVOWLSkyp->restoreGL();
116	}
117}
118
119void LLSky::resetVertexBuffers()
120{
121	if (gSky.mVOSkyp.notNull())
122	{
123		gPipeline.resetVertexBuffers(gSky.mVOSkyp->mDrawable);
124		gPipeline.resetVertexBuffers(gSky.mVOGroundp->mDrawable);
125		gPipeline.markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
126		gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
127	}
128	if (gSky.mVOWLSkyp.notNull())
129	{
130		gSky.mVOWLSkyp->resetVertexBuffers();
131		gPipeline.resetVertexBuffers(gSky.mVOWLSkyp->mDrawable);
132		gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
133	}
134}
135
136void LLSky::setOverrideSun(BOOL override)
137{
138	if (!mOverrideSimSunPosition && override)
139	{
140		mLastSunDirection = getSunDirection();
141	}
142	else if (mOverrideSimSunPosition && !override)
143	{
144		setSunDirection(mLastSunDirection, LLVector3::zero);
145	}
146	mOverrideSimSunPosition = override;
147}
148
149void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
150{
151	if(mVOSkyp.notNull()) {
152		mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity);
153	}
154}
155
156
157void LLSky::setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
158{
159	mSunTargDir = sun_direction;
160}
161
162
163LLVector3 LLSky::getSunDirection() const
164{
165	if (mVOSkyp)
166	{
167		return mVOSkyp->getToSun();
168	}
169	else
170	{
171		return LLVector3::z_axis;
172	}
173}
174
175
176LLVector3 LLSky::getMoonDirection() const
177{
178	if (mVOSkyp)
179	{
180		return mVOSkyp->getToMoon();
181	}
182	else
183	{
184		return LLVector3::z_axis;
185	}
186}
187
188
189LLColor4 LLSky::getSunDiffuseColor() const
190{
191	if (mVOSkyp)
192	{
193		return LLColor4(mVOSkyp->getSunDiffuseColor());
194	}
195	else
196	{
197		return LLColor4(1.f, 1.f, 1.f, 1.f);
198	}
199}
200
201LLColor4 LLSky::getSunAmbientColor() const
202{
203	if (mVOSkyp)
204	{
205		return LLColor4(mVOSkyp->getSunAmbientColor());
206	}
207	else
208	{
209		return LLColor4(0.f, 0.f, 0.f, 1.f);
210	}
211}
212
213
214LLColor4 LLSky::getMoonDiffuseColor() const
215{
216	if (mVOSkyp)
217	{
218		return LLColor4(mVOSkyp->getMoonDiffuseColor());
219	}
220	else
221	{
222		return LLColor4(1.f, 1.f, 1.f, 1.f);
223	}
224}
225
226LLColor4 LLSky::getMoonAmbientColor() const
227{
228	if (mVOSkyp)
229	{
230		return LLColor4(mVOSkyp->getMoonAmbientColor());
231	}
232	else
233	{
234		return LLColor4(0.f, 0.f, 0.f, 0.f);
235	}
236}
237
238
239LLColor4 LLSky::getTotalAmbientColor() const
240{
241	if (mVOSkyp)
242	{
243		return mVOSkyp->getTotalAmbientColor();
244	}
245	else
246	{
247		return LLColor4(1.f, 1.f, 1.f, 1.f);
248	}
249}
250
251
252BOOL LLSky::sunUp() const
253{
254	if (mVOSkyp)
255	{
256		return mVOSkyp->isSunUp();
257	}
258	else
259	{
260		return TRUE;
261	}
262}
263
264
265LLColor4U LLSky::getFadeColor() const
266{
267	if (mVOSkyp)
268	{
269		return mVOSkyp->getFadeColor();
270	}
271	else
272	{
273		return LLColor4(1.f, 1.f, 1.f, 1.f);
274	}
275}
276
277
278//////////////////////////////////////////////////////////////////////
279// Public Methods
280//////////////////////////////////////////////////////////////////////
281
282void LLSky::init(const LLVector3 &sun_direction)
283{
284	LLGLState::checkStates();
285	LLGLState::checkTextureChannels();
286
287	mVOWLSkyp = static_cast<LLVOWLSky*>(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, NULL));
288	mVOWLSkyp->initSunDirection(sun_direction, LLVector3::zero);
289	gPipeline.createObject(mVOWLSkyp.get());
290
291	LLGLState::checkStates();
292	LLGLState::checkTextureChannels();
293
294	mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, NULL);
295
296	LLGLState::checkStates();
297	LLGLState::checkTextureChannels();
298
299	mVOSkyp->initSunDirection(sun_direction, LLVector3());
300
301	LLGLState::checkStates();
302	LLGLState::checkTextureChannels();
303
304	gPipeline.createObject((LLViewerObject *)mVOSkyp);
305
306	LLGLState::checkStates();
307	LLGLState::checkTextureChannels();
308
309	mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, NULL);
310	LLVOGround *groundp = mVOGroundp;
311	gPipeline.createObject((LLViewerObject *)groundp);
312
313	LLGLState::checkStates();
314	LLGLState::checkTextureChannels();
315
316	gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));	
317
318	////////////////////////////
319	//
320	// Legacy code, ignore
321	//
322	//
323
324	// Get the parameters.
325	mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition");
326
327	LLGLState::checkStates();
328	LLGLState::checkTextureChannels();
329
330	if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || mOverrideSimSunPosition)
331	{
332		setSunDirection(mSunDefaultPosition, LLVector3(0.f, 0.f, 0.f));
333	}
334	else
335	{
336		setSunDirection(sun_direction, LLVector3(0.f, 0.f, 0.f));
337	}
338
339	LLGLState::checkStates();
340	LLGLState::checkTextureChannels();
341
342	mUpdatedThisFrame = TRUE;
343}
344
345
346void LLSky::setCloudDensityAtAgent(F32 cloud_density)
347{
348	if (mVOSkyp)
349	{
350		mVOSkyp->setCloudDensity(cloud_density);
351	}
352}
353
354
355void LLSky::setWind(const LLVector3& average_wind)
356{
357	if (mVOSkyp)
358	{
359		mVOSkyp->setWind(average_wind);
360	}
361}
362
363
364void LLSky::propagateHeavenlyBodies(F32 dt)
365{
366	if (!mOverrideSimSunPosition)
367	{
368		LLVector3 curr_dir = getSunDirection();
369		LLVector3 diff = mSunTargDir - curr_dir;
370		const F32 dist = diff.normVec();
371		if (dist > 0)
372		{
373			const F32 step = llmin (dist, 0.00005f);
374			//const F32 step = min (dist, 0.0001);
375			diff *= step;
376			curr_dir += diff;
377			curr_dir.normVec();
378			if (mVOSkyp)
379			{
380				mVOSkyp->setSunDirection(curr_dir, LLVector3());
381			}
382		}
383	}
384}
385
386F32 LLSky::getSunPhase() const
387{
388	return mSunPhase;
389}
390
391void LLSky::setSunPhase(const F32 phase)
392{
393	mSunPhase = phase;
394}
395
396//////////////////////////////////////////////////////////////////////
397// Private Methods
398//////////////////////////////////////////////////////////////////////
399
400
401LLColor4 LLSky::getFogColor() const
402{
403	if (mVOSkyp)
404	{
405		return mVOSkyp->getFogColor();
406	}
407
408	return LLColor4(1.f, 1.f, 1.f, 1.f);
409}
410
411void LLSky::updateFog(const F32 distance)
412{
413	if (mVOSkyp)
414	{
415		mVOSkyp->updateFog(distance);
416	}
417}
418
419void LLSky::updateCull()
420{
421	// *TODO: do culling for wl sky properly -Brad
422}
423
424void LLSky::updateSky()
425{
426	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
427	{
428		return;
429	}
430	if (mVOSkyp)
431	{
432		mVOSkyp->updateSky();
433	}
434}
435
436
437void LLSky::setFogRatio(const F32 fog_ratio)
438{
439	if (mVOSkyp)
440	{
441		mVOSkyp->setFogRatio(fog_ratio);
442	}
443}
444
445
446F32 LLSky::getFogRatio() const
447{
448	if (mVOSkyp)
449	{
450		return mVOSkyp->getFogRatio();
451	}
452	else
453	{
454		return 0.f;
455	}
456}
457
458
459// Returns angle (DEGREES) between the horizontal plane and "v", 
460// where the angle is negative when v.mV[VZ] < 0.0f
461F32 elevation_from_vector(const LLVector3 &v)
462{
463	F32 elevation = 0.0f;
464	F32 xy_component = (F32) sqrt(v.mV[VX] * v.mV[VX] + v.mV[VY] * v.mV[VY]);
465	if (xy_component != 0.0f)
466	{
467		elevation = RAD_TO_DEG * (F32) atan(v.mV[VZ]/xy_component);
468	}
469	else
470	{
471		if (v.mV[VZ] > 0.f)
472		{
473			elevation = 90.f;
474		}
475		else
476		{
477			elevation = -90.f;
478		}
479	}
480	return elevation;
481}