llsky.cpp

Go to the documentation of this file.
00001 
00032 //      Ideas:
00033 //              -haze should be controlled by global query from sims
00034 //              -need secondary optical effects on sun (flare)
00035 //              -stars should be brought down from sims
00036 //              -star intensity should be driven by global ambient level from sims,
00037 //               so that eclipses, etc can be easily done.
00038 //
00039 
00040 #include "llviewerprecompiledheaders.h"
00041 
00042 #include "llsky.h"
00043 
00044 // linden library includes
00045 #include "llerror.h"
00046 #include "llmath.h"
00047 #include "math.h"
00048 #include "v4color.h"
00049 
00050 #include "llviewerobjectlist.h"
00051 #include "llviewerobject.h"
00052 #include "llviewercamera.h"
00053 #include "pipeline.h"
00054 #include "llagent.h"
00055 #include "lldrawpool.h"
00056 
00057 #include "llvosky.h"
00058 #include "llcubemap.h"
00059 #include "llviewercontrol.h"
00060 
00061 #include "llvowlsky.h"
00062 
00063 F32 azimuth_from_vector(const LLVector3 &v);
00064 F32 elevation_from_vector(const LLVector3 &v);
00065 
00066 LLSky                           gSky;
00067 // ---------------- LLSky ----------------
00068 
00070 // Construction/Destruction
00072 
00073 LLSky::LLSky()
00074 {
00075         // Set initial clear color to black
00076         // Set fog color 
00077         mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
00078         mFogColor.mV[VALPHA] = 0.0f;
00079 
00080         mLightingGeneration = 0;
00081         mUpdatedThisFrame = TRUE;
00082         mOverrideSimSunPosition = FALSE;
00083         mSunPhase = 0.f;
00084 }
00085 
00086 
00087 LLSky::~LLSky()
00088 {
00089 }
00090 
00091 void LLSky::cleanup()
00092 {
00093         mVOSkyp = NULL;
00094         mVOWLSkyp = NULL;
00095         mVOGroundp = NULL;
00096 }
00097 
00098 void LLSky::destroyGL()
00099 {
00100         if (!mVOSkyp.isNull() && mVOSkyp->getCubeMap())
00101         {
00102                 mVOSkyp->cleanupGL();
00103         }
00104         if (mVOWLSkyp.notNull())
00105         {
00106                 mVOWLSkyp->cleanupGL();
00107         }
00108 }
00109 
00110 void LLSky::restoreGL()
00111 {
00112         if (mVOSkyp)
00113         {
00114                 mVOSkyp->restoreGL();
00115         }
00116         if (mVOWLSkyp)
00117         {
00118                 mVOWLSkyp->restoreGL();
00119         }
00120 }
00121 
00122 void LLSky::resetVertexBuffers()
00123 {
00124         if (gSky.mVOSkyp.notNull())
00125         {
00126                 gPipeline.resetVertexBuffers(gSky.mVOSkyp->mDrawable);
00127                 gPipeline.resetVertexBuffers(gSky.mVOGroundp->mDrawable);
00128                 gPipeline.markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00129                 gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00130         }
00131         if (gSky.mVOWLSkyp.notNull())
00132         {
00133                 gSky.mVOWLSkyp->resetVertexBuffers();
00134                 gPipeline.resetVertexBuffers(gSky.mVOWLSkyp->mDrawable);
00135                 gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
00136         }
00137 }
00138 
00139 void LLSky::setOverrideSun(BOOL override)
00140 {
00141         if (!mOverrideSimSunPosition && override)
00142         {
00143                 mLastSunDirection = getSunDirection();
00144         }
00145         else if (mOverrideSimSunPosition && !override)
00146         {
00147                 setSunDirection(mLastSunDirection, LLVector3::zero);
00148         }
00149         mOverrideSimSunPosition = override;
00150 }
00151 
00152 void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
00153 {
00154         if(mVOSkyp.notNull()) {
00155                 mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity);
00156         }
00157 }
00158 
00159 
00160 void LLSky::setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
00161 {
00162         mSunTargDir = sun_direction;
00163 }
00164 
00165 
00166 LLVector3 LLSky::getSunDirection() const
00167 {
00168         if (mVOSkyp)
00169         {
00170                 return mVOSkyp->getToSun();
00171         }
00172         else
00173         {
00174                 return LLVector3::z_axis;
00175         }
00176 }
00177 
00178 
00179 LLVector3 LLSky::getMoonDirection() const
00180 {
00181         if (mVOSkyp)
00182         {
00183                 return mVOSkyp->getToMoon();
00184         }
00185         else
00186         {
00187                 return LLVector3::z_axis;
00188         }
00189 }
00190 
00191 
00192 LLColor4 LLSky::getSunDiffuseColor() const
00193 {
00194         if (mVOSkyp)
00195         {
00196                 return LLColor4(mVOSkyp->getSunDiffuseColor());
00197         }
00198         else
00199         {
00200                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00201         }
00202 }
00203 
00204 LLColor4 LLSky::getSunAmbientColor() const
00205 {
00206         if (mVOSkyp)
00207         {
00208                 return LLColor4(mVOSkyp->getSunAmbientColor());
00209         }
00210         else
00211         {
00212                 return LLColor4(0.f, 0.f, 0.f, 1.f);
00213         }
00214 }
00215 
00216 
00217 LLColor4 LLSky::getMoonDiffuseColor() const
00218 {
00219         if (mVOSkyp)
00220         {
00221                 return LLColor4(mVOSkyp->getMoonDiffuseColor());
00222         }
00223         else
00224         {
00225                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00226         }
00227 }
00228 
00229 LLColor4 LLSky::getMoonAmbientColor() const
00230 {
00231         if (mVOSkyp)
00232         {
00233                 return LLColor4(mVOSkyp->getMoonAmbientColor());
00234         }
00235         else
00236         {
00237                 return LLColor4(0.f, 0.f, 0.f, 0.f);
00238         }
00239 }
00240 
00241 
00242 LLColor4 LLSky::getTotalAmbientColor() const
00243 {
00244         if (mVOSkyp)
00245         {
00246                 return mVOSkyp->getTotalAmbientColor();
00247         }
00248         else
00249         {
00250                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00251         }
00252 }
00253 
00254 
00255 BOOL LLSky::sunUp() const
00256 {
00257         if (mVOSkyp)
00258         {
00259                 return mVOSkyp->isSunUp();
00260         }
00261         else
00262         {
00263                 return TRUE;
00264         }
00265 }
00266 
00267 
00268 LLColor4U LLSky::getFadeColor() const
00269 {
00270         if (mVOSkyp)
00271         {
00272                 return mVOSkyp->getFadeColor();
00273         }
00274         else
00275         {
00276                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00277         }
00278 }
00279 
00280 
00282 // Public Methods
00284 
00285 void LLSky::init(const LLVector3 &sun_direction)
00286 {
00287         mVOWLSkyp = static_cast<LLVOWLSky*>(gObjectList.createObjectViewer(LLViewerObject::LL_VO_WL_SKY, gAgent.getRegion()));
00288         mVOWLSkyp->initSunDirection(sun_direction, LLVector3::zero);
00289         gPipeline.addObject(mVOWLSkyp.get());
00290 
00291         mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, gAgent.getRegion());
00292         mVOSkyp->initSunDirection(sun_direction, LLVector3());
00293         gPipeline.addObject((LLViewerObject *)mVOSkyp);
00294 
00295 
00296         mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, gAgent.getRegion());
00297         LLVOGround *groundp = mVOGroundp;
00298         gPipeline.addObject((LLViewerObject *)groundp);
00299 
00300         gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));      
00301 
00303         //
00304         // Legacy code, ignore
00305         //
00306         //
00307 
00308         // Get the parameters.
00309         mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition");
00310 
00311 
00312         if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || mOverrideSimSunPosition)
00313         {
00314                 setSunDirection(mSunDefaultPosition, LLVector3(0.f, 0.f, 0.f));
00315         }
00316         else
00317         {
00318                 setSunDirection(sun_direction, LLVector3(0.f, 0.f, 0.f));
00319         }
00320 
00321 
00322         mUpdatedThisFrame = TRUE;
00323 }
00324 
00325 
00326 void LLSky::setCloudDensityAtAgent(F32 cloud_density)
00327 {
00328         if (mVOSkyp)
00329         {
00330                 mVOSkyp->setCloudDensity(cloud_density);
00331         }
00332 }
00333 
00334 
00335 void LLSky::setWind(const LLVector3& average_wind)
00336 {
00337         if (mVOSkyp)
00338         {
00339                 mVOSkyp->setWind(average_wind);
00340         }
00341 }
00342 
00343 
00344 void LLSky::propagateHeavenlyBodies(F32 dt)
00345 {
00346         if (!mOverrideSimSunPosition)
00347         {
00348                 LLVector3 curr_dir = getSunDirection();
00349                 LLVector3 diff = mSunTargDir - curr_dir;
00350                 const F32 dist = diff.normVec();
00351                 if (dist > 0)
00352                 {
00353                         const F32 step = llmin (dist, 0.00005f);
00354                         //const F32 step = min (dist, 0.0001);
00355                         diff *= step;
00356                         curr_dir += diff;
00357                         curr_dir.normVec();
00358                         if (mVOSkyp)
00359                         {
00360                                 mVOSkyp->setSunDirection(curr_dir, LLVector3());
00361                         }
00362                 }
00363         }
00364 }
00365 
00366 F32 LLSky::getSunPhase() const
00367 {
00368         return mSunPhase;
00369 }
00370 
00371 void LLSky::setSunPhase(const F32 phase)
00372 {
00373         mSunPhase = phase;
00374 }
00375 
00377 // Private Methods
00379 
00380 
00381 LLColor4 LLSky::getFogColor() const
00382 {
00383         if (mVOSkyp)
00384         {
00385                 return mVOSkyp->getFogColor();
00386         }
00387 
00388         return LLColor4(1.f, 1.f, 1.f, 1.f);
00389 }
00390 
00391 void LLSky::updateFog(const F32 distance)
00392 {
00393         if (mVOSkyp)
00394         {
00395                 mVOSkyp->updateFog(distance);
00396         }
00397 }
00398 
00399 void LLSky::updateCull()
00400 {
00401         /*if (mVOSkyp.notNull() && mVOSkyp->mDrawable.notNull())
00402         {
00403                 gPipeline.markVisible(mVOSkyp->mDrawable);
00404         }
00405         else
00406         {
00407                 llinfos << "No sky drawable!" << llendl;
00408         }*/
00409 
00410         /*if (mVOGroundp.notNull() && mVOGroundp->mDrawable.notNull())
00411         {
00412                 gPipeline.markVisible(mVOGroundp->mDrawable);
00413         }*/
00414 
00415         // *TODO: do culling for wl sky properly -Brad
00416 }
00417 
00418 void LLSky::updateSky()
00419 {
00420         if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
00421         {
00422                 return;
00423         }
00424         if (mVOSkyp)
00425         {
00426                 mVOSkyp->updateSky();
00427         }
00428 }
00429 
00430 
00431 void LLSky::setFogRatio(const F32 fog_ratio)
00432 {
00433         if (mVOSkyp)
00434         {
00435                 mVOSkyp->setFogRatio(fog_ratio);
00436         }
00437 }
00438 
00439 
00440 F32 LLSky::getFogRatio() const
00441 {
00442         if (mVOSkyp)
00443         {
00444                 return mVOSkyp->getFogRatio();
00445         }
00446         else
00447         {
00448                 return 0.f;
00449         }
00450 }
00451 
00452 
00453 // Returns angle (DEGREES) between the horizontal plane and "v", 
00454 // where the angle is negative when v.mV[VZ] < 0.0f
00455 F32 elevation_from_vector(const LLVector3 &v)
00456 {
00457         F32 elevation = 0.0f;
00458         F32 xy_component = (F32) sqrt(v.mV[VX] * v.mV[VX] + v.mV[VY] * v.mV[VY]);
00459         if (xy_component != 0.0f)
00460         {
00461                 elevation = RAD_TO_DEG * (F32) atan(v.mV[VZ]/xy_component);
00462         }
00463         else
00464         {
00465                 if (v.mV[VZ] > 0.f)
00466                 {
00467                         elevation = 90.f;
00468                 }
00469                 else
00470                 {
00471                         elevation = -90.f;
00472                 }
00473         }
00474         return elevation;
00475 }

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