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 "llvostars.h"
00059 #include "llcubemap.h"
00060 #include "llviewercontrol.h"
00061 
00062 extern LLPipeline gPipeline;
00063 
00064 F32 azimuth_from_vector(const LLVector3 &v);
00065 F32 elevation_from_vector(const LLVector3 &v);
00066 
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         mVOStarsp = NULL;
00095         mVOGroundp = NULL;
00096 }
00097 
00098 void LLSky::destroyGL()
00099 {
00100         if (!mVOSkyp.isNull() && mVOSkyp->getCubeMap())
00101         {
00102                 mVOSkyp->cleanupGL();
00103         }
00104 }
00105 
00106 void LLSky::restoreGL()
00107 {
00108         if (mVOSkyp)
00109         {
00110                 mVOSkyp->restoreGL();
00111         }
00112 }
00113 
00114 void LLSky::setOverrideSun(BOOL override)
00115 {
00116         if (!mOverrideSimSunPosition && override)
00117         {
00118                 mLastSunDirection = getSunDirection();
00119         }
00120         else if (mOverrideSimSunPosition && !override)
00121         {
00122                 setSunDirection(mLastSunDirection, LLVector3::zero);
00123         }
00124         mOverrideSimSunPosition = override;
00125 }
00126 
00127 void LLSky::setSunDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
00128 {
00129         mVOSkyp->setSunDirection(sun_direction, sun_ang_velocity);
00130 }
00131 
00132 
00133 void LLSky::setSunTargetDirection(const LLVector3 &sun_direction, const LLVector3 &sun_ang_velocity)
00134 {
00135         mSunTargDir = sun_direction;
00136 }
00137 
00138 
00139 LLVector3 LLSky::getSunDirection() const
00140 {
00141         if (mVOSkyp)
00142         {
00143                 return mVOSkyp->getToSun();
00144         }
00145         else
00146         {
00147                 return LLVector3::z_axis;
00148         }
00149 }
00150 
00151 
00152 LLVector3 LLSky::getMoonDirection() const
00153 {
00154         if (mVOSkyp)
00155         {
00156                 return mVOSkyp->getToMoon();
00157         }
00158         else
00159         {
00160                 return LLVector3::z_axis;
00161         }
00162 }
00163 
00164 
00165 LLColor4 LLSky::getSunDiffuseColor() const
00166 {
00167         if (mVOSkyp)
00168         {
00169                 return LLColor4(mVOSkyp->getSunDiffuseColor());
00170         }
00171         else
00172         {
00173                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00174         }
00175 }
00176 
00177 
00178 LLColor4 LLSky::getMoonDiffuseColor() const
00179 {
00180         if (mVOSkyp)
00181         {
00182                 return LLColor4(mVOSkyp->getMoonDiffuseColor());
00183         }
00184         else
00185         {
00186                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00187         }
00188 }
00189 
00190 
00191 LLColor4 LLSky::getTotalAmbientColor() const
00192 {
00193         if (mVOSkyp)
00194         {
00195                 return mVOSkyp->getTotalAmbientColor();
00196         }
00197         else
00198         {
00199                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00200         }
00201 }
00202 
00203 
00204 BOOL LLSky::sunUp() const
00205 {
00206         if (mVOSkyp)
00207         {
00208                 return mVOSkyp->isSunUp();
00209         }
00210         else
00211         {
00212                 return TRUE;
00213         }
00214 }
00215 
00216 
00217 LLColor4 LLSky::calcInScatter(LLColor4& transp, const LLVector3 &point, F32 exag) const
00218 {
00219         if (mVOSkyp)
00220         {
00221                 return mVOSkyp->calcInScatter(transp, point, exag);
00222         }
00223         else
00224         {
00225                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00226         }
00227 }
00228 
00229 
00230 LLColor4U LLSky::getFadeColor() const
00231 {
00232         if (mVOSkyp)
00233         {
00234                 return mVOSkyp->getFadeColor();
00235         }
00236         else
00237         {
00238                 return LLColor4(1.f, 1.f, 1.f, 1.f);
00239         }
00240 }
00241 
00242 
00244 // Public Methods
00246 
00247 
00248 void LLSky::init(const LLVector3 &sun_direction)
00249 {
00250         mVOSkyp = (LLVOSky *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_SKY, gAgent.getRegion());
00251         mVOSkyp->initSunDirection(sun_direction, LLVector3());
00252         gPipeline.addObject((LLViewerObject *)mVOSkyp);
00253 
00254         mVOStarsp = (LLVOStars *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_STARS, gAgent.getRegion());
00255         gPipeline.addObject((LLViewerObject *)mVOStarsp);
00256         
00257         mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, gAgent.getRegion());
00258         LLVOGround *groundp = mVOGroundp;
00259         gPipeline.addObject((LLViewerObject *)groundp);
00260 
00261         gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));
00262         
00264         //
00265         // Legacy code, ignore
00266         //
00267         //
00268 
00269         // Get the parameters.
00270         mSunDefaultPosition = gSavedSettings.getVector3("SkySunDefaultPosition");
00271 
00272 
00273         if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition") || mOverrideSimSunPosition)
00274         {
00275                 setSunDirection(mSunDefaultPosition, LLVector3(0.f, 0.f, 0.f));
00276         }
00277         else
00278         {
00279                 setSunDirection(sun_direction, LLVector3(0.f, 0.f, 0.f));
00280         }
00281         
00282         mUpdatedThisFrame = TRUE;
00283 }
00284 
00285 
00286 void LLSky::setCloudDensityAtAgent(F32 cloud_density)
00287 {
00288         if (mVOSkyp)
00289         {
00290                 mVOSkyp->setCloudDensity(cloud_density);
00291         }
00292 }
00293 
00294 
00295 void LLSky::setWind(const LLVector3& average_wind)
00296 {
00297         if (mVOSkyp)
00298         {
00299                 mVOSkyp->setWind(average_wind);
00300         }
00301 }
00302 
00303 
00304 void LLSky::propagateHeavenlyBodies(F32 dt)
00305 {
00306         if (!mOverrideSimSunPosition)
00307         {
00308                 LLVector3 curr_dir = getSunDirection();
00309                 LLVector3 diff = mSunTargDir - curr_dir;
00310                 const F32 dist = diff.normVec();
00311                 if (dist > 0)
00312                 {
00313                         const F32 step = llmin (dist, 0.00005f);
00314                         //const F32 step = min (dist, 0.0001);
00315                         diff *= step;
00316                         curr_dir += diff;
00317                         curr_dir.normVec();
00318                         if (mVOSkyp)
00319                         {
00320                                 mVOSkyp->setSunDirection(curr_dir, LLVector3());
00321                         }
00322                 }
00323         }
00324 }
00325 
00326 F32 LLSky::getSunPhase() const
00327 {
00328         return mSunPhase;
00329 }
00330 
00331 void LLSky::setSunPhase(const F32 phase)
00332 {
00333         mSunPhase = phase;
00334 }
00335 
00337 // Private Methods
00339 
00340 
00341 LLColor4 LLSky::getFogColor() const
00342 {
00343         if (mVOSkyp)
00344         {
00345                 return mVOSkyp->getFogColor();
00346         }
00347 
00348         return LLColor4(1.f, 1.f, 1.f, 1.f);
00349 }
00350 
00351 
00352 void LLSky::updateFog(const F32 distance)
00353 {
00354         if (mVOSkyp)
00355         {
00356                 mVOSkyp->updateFog(distance);
00357         }
00358 }
00359 
00360 void LLSky::updateCull()
00361 {
00362         /*if (mVOSkyp.notNull() && mVOSkyp->mDrawable.notNull())
00363         {
00364                 gPipeline.markVisible(mVOSkyp->mDrawable);
00365         }
00366         else
00367         {
00368                 llinfos << "No sky drawable!" << llendl;
00369         }*/
00370 
00371         if (mVOStarsp.notNull() && mVOStarsp->mDrawable.notNull())
00372         {
00373                 gPipeline.markVisible(mVOStarsp->mDrawable, *gCamera);
00374         }
00375         else
00376         {
00377                 llinfos << "No stars drawable!" << llendl;
00378         }
00379 
00380         /*if (mVOGroundp.notNull() && mVOGroundp->mDrawable.notNull())
00381         {
00382                 gPipeline.markVisible(mVOGroundp->mDrawable);
00383         }*/
00384 }
00385 
00386 void LLSky::updateSky()
00387 {
00388         if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
00389         {
00390                 return;
00391         }
00392         if (mVOSkyp)
00393         {
00394                 mVOSkyp->updateSky();
00395         }
00396         if (mVOStarsp)
00397         {
00398                 //if (mVOStarsp->mDrawable)
00399                 //{
00400                 //      gPipeline.markRebuild(mVOStarsp->mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
00401                 //}
00402         }
00403 }
00404 
00405 
00406 void LLSky::setFogRatio(const F32 fog_ratio)
00407 {
00408         if (mVOSkyp)
00409         {
00410                 mVOSkyp->setFogRatio(fog_ratio);
00411         }
00412 }
00413 
00414 
00415 F32 LLSky::getFogRatio() const
00416 {
00417         if (mVOSkyp)
00418         {
00419                 return mVOSkyp->getFogRatio();
00420         }
00421         else
00422         {
00423                 return 0.f;
00424         }
00425 }
00426 
00427 
00428 // Returns angle (DEGREES) between the horizontal plane and "v", 
00429 // where the angle is negative when v.mV[VZ] < 0.0f
00430 F32 elevation_from_vector(const LLVector3 &v)
00431 {
00432         F32 elevation = 0.0f;
00433         F32 xy_component = (F32) sqrt(v.mV[VX] * v.mV[VX] + v.mV[VY] * v.mV[VY]);
00434         if (xy_component != 0.0f)
00435         {
00436                 elevation = RAD_TO_DEG * (F32) atan(v.mV[VZ]/xy_component);
00437         }
00438         else
00439         {
00440                 if (v.mV[VZ] > 0.f)
00441                 {
00442                         elevation = 90.f;
00443                 }
00444                 else
00445                 {
00446                         elevation = -90.f;
00447                 }
00448         }
00449         return elevation;
00450 }

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