llvosky.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /**
  2. * @file llvosky.h
  3. * @brief LLVOSky class header file
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLVOSKY_H
  33. #define LL_LLVOSKY_H
  34. #include "stdtypes.h"
  35. #include "llcolor3.h"
  36. #include "llcolor4u.h"
  37. #include "llframetimer.h"
  38. #include "llimage.h"
  39. #include "llquaternion.h"
  40. #include "llsettingssky.h"
  41. #include "llviewerobject.h"
  42. #include "llviewertexture.h"
  43. class LLCubeMap;
  44. class LLFace;
  45. ///////////////////////////////////////////////////////////////////////////////
  46. // Lots of constants. Will clean these up at some point...
  47. constexpr F32 HORIZON_DIST = 1024.0f;
  48. constexpr F32 SKY_BOX_MULT = 16.0f;
  49. constexpr F32 HEAVENLY_BODY_DIST = HORIZON_DIST - 10.f;
  50. constexpr F32 HEAVENLY_BODY_FACTOR = 0.1f;
  51. constexpr F32 HEAVENLY_BODY_SCALE = HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
  52. constexpr F32 EARTH_RADIUS = 6.4e6f; // Eact radius = 6.37 x 10^6 m
  53. constexpr F32 ATM_EXP_FALLOFF = 0.000126f;
  54. constexpr F32 ATM_SEA_LEVEL_NDENS = 2.55e25f;
  55. // Somewhat arbitrary:
  56. constexpr F32 ATM_HEIGHT = 100000.f;
  57. constexpr F32 FIRST_STEP = 5000.f;
  58. constexpr F32 INV_FIRST_STEP = 1.f / FIRST_STEP;
  59. constexpr S32 NO_STEPS = 15;
  60. constexpr F32 INV_NO_STEPS = 1.f / NO_STEPS;
  61. // Constants used in calculation of scattering coeff of clear air
  62. constexpr F32 sigma = 0.035f;
  63. constexpr F32 fsigma = (6.f + 3.f * sigma) / (6.f - 7.f * sigma);
  64. constexpr F64 Ndens = 2.55e25;
  65. constexpr F64 Ndens2 = Ndens * Ndens;
  66. constexpr F32 NIGHTTIME_ELEVATION = -8.f; // Degrees
  67. // While gcc allows to compute sinf(NIGHTTIME_ELEVATION * DEG_TO_RAD) at
  68. // compile time, clang does not, so we cannot use constexpr here... :-(
  69. extern const F32 NIGHTTIME_ELEVATION_COS;
  70. // *HACK: allow server to change Sun and Moon Ids. I cannot figure out how to
  71. // pass the appropriate information into the LLVOSky constructor. JC
  72. extern LLUUID gSunTextureID;
  73. extern LLUUID gMoonTextureID;
  74. class LLSkyTex
  75. {
  76. friend class LLVOSky;
  77. public:
  78. LL_INLINE static F32 getInterpVal() { return sInterpVal; }
  79. LL_INLINE static void setInterpVal(F32 v) { sInterpVal = v; }
  80. LL_INLINE static bool doInterpolate() { return sInterpVal > 0.001f; }
  81. void bindTexture(bool curr = true);
  82. protected:
  83. LLSkyTex();
  84. void init(bool shiny);
  85. void cleanupGL();
  86. void restoreGL();
  87. ~LLSkyTex();
  88. LL_INLINE static S32 getResolution() { return sResolution; }
  89. LL_INLINE static S32 getCurrent() { return sCurrent; }
  90. LL_INLINE static S32 stepCurrent()
  91. {
  92. ++sCurrent;
  93. sCurrent &= 1;
  94. return sCurrent;
  95. }
  96. LL_INLINE static S32 getNext() { return ((sCurrent + 1) & 1); }
  97. LL_INLINE static S32 getWhich(bool curr) { return curr ? sCurrent : getNext(); }
  98. void initEmpty(S32 tex);
  99. void create();
  100. LL_INLINE void setDir(const LLVector3& dir, S32 i, S32 j)
  101. {
  102. S32 offset = i * sResolution + j;
  103. mSkyDirs[offset] = dir;
  104. }
  105. LL_INLINE const LLVector3& getDir(S32 i, S32 j) const
  106. {
  107. S32 offset = i * sResolution + j;
  108. return mSkyDirs[offset];
  109. }
  110. LL_INLINE void setPixel(const LLColor4& col, S32 i, S32 j)
  111. {
  112. S32 offset = i * sResolution + j;
  113. mSkyData[offset] = LLColor4U(col);
  114. }
  115. LL_INLINE void setPixel(const LLColor4U& col, S32 i, S32 j)
  116. {
  117. S32 offset = (i * sResolution + j) * sComponents;
  118. U32* pix = (U32*)&(mImageRaw[sCurrent]->getData()[offset]);
  119. *pix = col.asRGBA();
  120. }
  121. LL_INLINE LLColor4U getPixel(S32 i, S32 j)
  122. {
  123. LLColor4U col;
  124. S32 offset = (i * sResolution + j) * sComponents;
  125. U32* pix = (U32*)&(mImageRaw[sCurrent]->getData()[offset]);
  126. col.fromRGBA(*pix);
  127. return col;
  128. }
  129. LL_INLINE LLImageRaw* getImageRaw(bool curr = true) { return mImageRaw[getWhich(curr)]; }
  130. void createGLImage(S32 tex);
  131. private:
  132. LLPointer<LLViewerTexture> mTexture[2];
  133. LLPointer<LLImageRaw> mImageRaw[2];
  134. LLColor4U* mSkyData;
  135. LLVector3* mSkyDirs; // Cache of sky direction vectors
  136. bool mIsShiny;
  137. static S32 sResolution;
  138. static S32 sComponents;
  139. static S32 sCurrent;
  140. static F32 sInterpVal;
  141. };
  142. /// TODO Move into the stars draw pool (and rename them appropriately).
  143. class LLHeavenBody
  144. {
  145. public:
  146. LLHeavenBody(F32 rad)
  147. : mIntensity(0.f),
  148. mDiskRadius(rad),
  149. mHorizonVisibility(1.f),
  150. mVisibility(1.f),
  151. mVisible(false),
  152. mDraw(false)
  153. {
  154. mColor.setToBlack();
  155. mColorCached.setToBlack();
  156. }
  157. LL_INLINE const LLVector3& getDirection() const { return mDirection; }
  158. LL_INLINE void setDirection(const LLVector3& direction) { mDirection = direction; }
  159. LL_INLINE void setAngularVelocity(const LLVector3& av) { mAngularVelocity = av; }
  160. LL_INLINE const LLVector3& getAngularVelocity() const { return mAngularVelocity; }
  161. LL_INLINE void setRotation(const LLQuaternion& rot) { mRotation = rot; }
  162. LL_INLINE const LLQuaternion& getRotation() const { return mRotation; }
  163. LL_INLINE const LLVector3& getDirectionCached() const { return mDirectionCached; }
  164. LL_INLINE void renewDirection() { mDirectionCached = mDirection; }
  165. LL_INLINE const LLColor3& getColorCached() const { return mColorCached; }
  166. LL_INLINE void setColorCached(const LLColor3& c) { mColorCached = c; }
  167. LL_INLINE const LLColor3& getColor() const { return mColor; }
  168. LL_INLINE void setColor(const LLColor3& c) { mColor = c; }
  169. LL_INLINE void renewColor() { mColorCached = mColor; }
  170. LL_INLINE static F32 interpVal() { return sInterpVal; }
  171. LL_INLINE static void setInterpVal(F32 v) { sInterpVal = v; }
  172. LL_INLINE LLColor3 getInterpColor() const
  173. {
  174. return sInterpVal * mColor + (1 - sInterpVal) * mColorCached;
  175. }
  176. LL_INLINE const F32& getHorizonVisibility() const { return mHorizonVisibility; }
  177. LL_INLINE void setHorizonVisibility(F32 c = 1) { mHorizonVisibility = c; }
  178. LL_INLINE const F32& getVisibility() const { return mVisibility; }
  179. LL_INLINE void setVisibility(F32 c = 1) { mVisibility = c; }
  180. LL_INLINE F32 getHaloBrighness() const
  181. {
  182. return llmax(0.f, llmin(0.9f, mHorizonVisibility)) * mVisibility;
  183. }
  184. LL_INLINE bool isVisible() const { return mVisible; }
  185. LL_INLINE void setVisible(bool v) { mVisible = v; }
  186. LL_INLINE const F32& getIntensity() const { return mIntensity; }
  187. LL_INLINE void setIntensity(F32 c) { mIntensity = c; }
  188. LL_INLINE void setDiskRadius(F32 radius) { mDiskRadius = radius; }
  189. LL_INLINE F32 getDiskRadius() const { return mDiskRadius; }
  190. LL_INLINE void setDraw(bool draw) { mDraw = draw; }
  191. LL_INLINE bool getDraw() const { return mDraw; }
  192. LL_INLINE const LLVector3& corner(S32 n) const { return mQuadCorner[n]; }
  193. LL_INLINE LLVector3& corner(S32 n) { return mQuadCorner[n]; }
  194. LL_INLINE const LLVector3* corners() const { return mQuadCorner; }
  195. LL_INLINE const LLVector3& getU() const { return mU; }
  196. LL_INLINE const LLVector3& getV() const { return mV; }
  197. LL_INLINE void setU(const LLVector3& u) { mU = u; }
  198. LL_INLINE void setV(const LLVector3& v) { mV = v; }
  199. protected:
  200. // *HACK: for events that should not happen every frame
  201. LLVector3 mDirectionCached;
  202. LLColor3 mColor;
  203. LLColor3 mColorCached;
  204. F32 mIntensity;
  205. LLVector3 mDirection; // Direction of the local heavenly body
  206. LLVector3 mAngularVelocity; // Velocity of the local heavenly body
  207. LLQuaternion mRotation;
  208. F32 mDiskRadius;
  209. // Number [0, 1] due to how horizon
  210. F32 mHorizonVisibility;
  211. // Same but due to other objects being in throng.
  212. F32 mVisibility;
  213. LLVector3 mQuadCorner[4];
  214. LLVector3 mU;
  215. LLVector3 mV;
  216. LLVector3 mO;
  217. bool mDraw; // When false, do not draw.
  218. bool mVisible;
  219. static F32 sInterpVal;
  220. };
  221. class LLVOSky final : public LLStaticViewerObject
  222. {
  223. public:
  224. enum
  225. {
  226. FACE_SIDE0,
  227. FACE_SIDE1,
  228. FACE_SIDE2,
  229. FACE_SIDE3,
  230. FACE_SIDE4,
  231. FACE_SIDE5,
  232. FACE_SUN, // was 6
  233. FACE_MOON, // was 7
  234. FACE_BLOOM, // was 8
  235. FACE_REFLECTION, // was 10
  236. FACE_COUNT
  237. };
  238. LLVOSky(const LLUUID& id, LLViewerRegion* regionp);
  239. // Initialize/delete data that is only inited once per class.
  240. void init();
  241. void cleanupGL();
  242. void restoreGL();
  243. // Nothing to do.
  244. LL_INLINE void idleUpdate(F64) override {}
  245. bool updateSky();
  246. void updateTextures() override;
  247. LLDrawable* createDrawable() override;
  248. bool updateGeometry(LLDrawable* drawable) override;
  249. LL_INLINE const LLHeavenBody& getSun() const { return mSun; }
  250. LL_INLINE const LLHeavenBody& getMoon() const { return mMoon; }
  251. LL_INLINE const LLVector3& getToSunLast() const { return mSun.getDirectionCached(); }
  252. LL_INLINE const LLVector3& getToSun() const { return mSun.getDirection(); }
  253. LL_INLINE const LLVector3& getToMoon() const { return mMoon.getDirection(); }
  254. LL_INLINE const LLVector3& getToMoonLast() const { return mMoon.getDirectionCached(); }
  255. void initSunDirection(const LLVector3& sun_dir);
  256. void setSunDirection(const LLVector3& sun_dir,
  257. const LLVector3& sun_ang_velocity);
  258. // Directions provided should already be in CFR coord sys (+x at, +z up,
  259. // +y right)
  260. void setSunDirectionCFR(const LLVector3& sun_direction);
  261. void setMoonDirectionCFR(const LLVector3& moon_dir);
  262. LL_INLINE void setSunAndMoonDirectionsCFR(const LLVector3& sun_dir,
  263. const LLVector3& moon_dir)
  264. {
  265. mMoon.setDirection(moon_dir);
  266. setSunDirectionCFR(sun_dir);
  267. }
  268. LL_INLINE F32 getWorldScale() const { return mWorldScale; }
  269. LL_INLINE void setWorldScale(F32 s) { mWorldScale = s; }
  270. void updateFog(F32 distance);
  271. LL_INLINE void setCloudDensity(F32 cloud_density) { mCloudDensity = cloud_density; }
  272. LL_INLINE void setWind(const LLVector3& wind) { mWind = wind.length(); }
  273. LL_INLINE const LLVector3& getCameraPosAgent() const { return mCameraPosAgent; }
  274. LL_INLINE LLVector3 getEarthCenter() const { return mEarthCenter; }
  275. LL_INLINE LLCubeMap* getCubeMap() const { return mCubeMap; }
  276. LL_INLINE S32 getDrawRefl() const { return mDrawRefl; }
  277. LL_INLINE void setDrawRefl(S32 r) { mDrawRefl = r; }
  278. LL_INLINE bool isReflFace(LLFace* face) const { return face == mFace[FACE_REFLECTION]; }
  279. LL_INLINE LLFace* getReflFace() const { return mFace[FACE_REFLECTION]; }
  280. LL_INLINE void setSunScale(F32 scale) { mSunScale = scale; }
  281. LL_INLINE void setMoonScale(F32 scale) { mMoonScale = scale; }
  282. LL_INLINE LLViewerTexture* getSunTex() const { return mSunTexturep[0].get(); }
  283. LL_INLINE LLViewerTexture* getMoonTex() const { return mMoonTexturep[0].get(); }
  284. LL_INLINE LLViewerTexture* getBloomTex() const { return mBloomTexturep[0].get(); }
  285. LL_INLINE LLViewerTexture* getCloudNoiseTex() const { return mCloudNoiseTexturep[0].get(); }
  286. LL_INLINE LLViewerTexture* getSunTexNext() const { return mSunTexturep[1].get(); }
  287. LL_INLINE LLViewerTexture* getMoonTexNext() const { return mMoonTexturep[1].get(); }
  288. LL_INLINE LLViewerTexture* getBloomTexNext() const { return mBloomTexturep[1].get(); }
  289. LL_INLINE LLViewerTexture* getCloudNoiseTexNext() const { return mCloudNoiseTexturep[1].get(); }
  290. void setSunTextures(const LLUUID& sun_tex1, const LLUUID& sun_tex2);
  291. void setMoonTextures(const LLUUID& moon_tex1, const LLUUID& moon_tex2);
  292. void setCloudNoiseTextures(const LLUUID& cld_tex1, const LLUUID& cld_tex2);
  293. void setBloomTextures(const LLUUID& bloom_tex1, const LLUUID& bloom_tex2);
  294. LL_INLINE LLViewerTexture* getRainbowTex() const { return mRainbowMap.get(); }
  295. LL_INLINE LLViewerTexture* getHaloTex() const { return mHaloMap.get(); }
  296. LL_INLINE void forceSkyUpdate() { mForceUpdate = true; }
  297. LL_INLINE F32 getInterpVal() const { return mInterpVal; }
  298. protected:
  299. ~LLVOSky() override;
  300. private:
  301. void initCubeMap();
  302. void initAtmospherics(const LLSettingsSky::ptr_t& skyp);
  303. void calcAtmospherics(); // AKA calc() in LL's viewer
  304. void updateDirections(const LLSettingsSky::ptr_t& skyp);
  305. void initSkyTextureDirs(S32 side, S32 tile);
  306. void createSkyTexture(const LLSettingsSky::ptr_t& skyp, S32 side,
  307. S32 tile);
  308. LLColor4 calcSkyColorInDir(const LLSettingsSky::ptr_t& skyp,
  309. const LLVector3& dir, bool is_shiny = false);
  310. void calcSkyColorVert(LLVector3& pn);
  311. bool haveValuesChanged();
  312. void saveCurrentValues();
  313. LL_INLINE F32 cosHorizon() const
  314. {
  315. const F32 sin_angle = EARTH_RADIUS /
  316. (EARTH_RADIUS + mCameraPosAgent.mV[2]);
  317. return -sqrtf(1.f - sin_angle * sin_angle);
  318. }
  319. bool updateHeavenlyBodyGeometry(LLDrawable* drawable, bool is_sun,
  320. LLHeavenBody& hb, F32 sin_max_angle,
  321. const LLVector3& up,
  322. const LLVector3& right);
  323. void updateReflectionGeometry(LLDrawable* drawable, F32 h,
  324. const LLHeavenBody& hb);
  325. protected:
  326. typedef LLPointer<LLViewerFetchedTexture> tex_ptr_t;
  327. tex_ptr_t mSunTexturep[2];
  328. tex_ptr_t mMoonTexturep[2];
  329. tex_ptr_t mBloomTexturep[2];
  330. tex_ptr_t mCloudNoiseTexturep[2];
  331. tex_ptr_t mRainbowMap;
  332. tex_ptr_t mHaloMap;
  333. static S32 sResolution;
  334. static S32 sTileResX;
  335. static S32 sTileResY;
  336. LLSkyTex mSkyTex[6];
  337. LLSkyTex mShinyTex[6];
  338. LLHeavenBody mSun;
  339. LLHeavenBody mMoon;
  340. F32 mSunScale;
  341. F32 mMoonScale;
  342. LLVector3 mSunAngVel;
  343. LLVector3 mEarthCenter;
  344. LLVector3 mCameraPosAgent;
  345. LLColor3 mBrightestPoint;
  346. LLColor3 mBrightestPointNew;
  347. LLColor3 mBrightestPointGuess;
  348. F32 mBrightnessScale;
  349. F32 mBrightnessScaleNew;
  350. F32 mBrightnessScaleGuess;
  351. F32 mCloudDensity;
  352. F32 mWind;
  353. F32 mAtmHeight;
  354. LLVector3 mLastLightingDirection;
  355. LLColor3 mLastTotalAmbient;
  356. LLColor3 mNightColorShift;
  357. F32 mAmbientScale;
  358. F32 mInterpVal;
  359. LLColor4 mFogColor;
  360. LLColor4 mGLFogCol;
  361. F32 mWorldScale;
  362. LLPointer<LLCubeMap> mCubeMap; // Cube map for the environment
  363. // State of cubemap uodate: -1 idle; 0-5 per-face updates; 6 finalizing
  364. S32 mCubeMapUpdateStage;
  365. // Do partial work to amortize cost of updating
  366. S32 mCubeMapUpdateTile;
  367. S32 mDrawRefl;
  368. LLFrameTimer mUpdateTimer;
  369. LLTimer mForceUpdateThrottle;
  370. // Windlight parameters
  371. F32 mDomeRadius;
  372. F32 mDomeOffset;
  373. F32 mGamma;
  374. F32 mHazeDensity;
  375. F32 mHazeHorizon;
  376. F32 mDensityMultiplier;
  377. F32 mMaxY;
  378. F32 mCloudShadow;
  379. LLVector4 mSunNorm;
  380. LLVector4 mUnClampedSunNorm;
  381. LLColor3 mGlow;
  382. LLColor3 mSunlight;
  383. LLColor3 mAmbient;
  384. LLColor3 mBlueDensity;
  385. LLColor3 mBlueHorizon;
  386. // Extended environment parameters
  387. LLColor3 mHazeColor;
  388. LLColor3 mLightAttenuation;
  389. LLColor3 mLightTransmittance;
  390. LLColor3 mTotalDensity;
  391. #if 0 // 'hazeColorBelowCloud' in LL's EEP viewer (which would be
  392. // mHazeColorBelowCloud for the Cool VL Viewer) is computed but never
  393. // truly used (excepted in what would be in haveValuesChanged() for
  394. // us)...
  395. LLColor3 mHazeColorBelowCloud;
  396. #endif
  397. // Old values of above parameters, used to detect a needed update
  398. F32 mOldGamma;
  399. F32 mOldHazeDensity;
  400. F32 mOldHazeHorizon;
  401. F32 mOldDensityMultiplier;
  402. F32 mOldMaxY;
  403. F32 mOldCloudShadow;
  404. LLVector4 mOldSunNorm;
  405. LLColor3 mOldGlow;
  406. LLColor3 mOldSunlight;
  407. LLColor3 mOldAmbient;
  408. LLColor3 mOldBlueDensity;
  409. LLColor3 mOldBlueHorizon;
  410. #if 0 // These components are derived from the above ones, so need to save
  411. // and test them... HB
  412. LLColor3 mOldLightAttenuation;
  413. LLColor3 mOldLightTransmittance;
  414. LLColor3 mOldTotalDensity;
  415. #endif
  416. // Various flags
  417. bool mWeatherChange;
  418. bool mInitialized;
  419. bool mForceUpdate; // Flag to force update of cubemap
  420. bool mNeedUpdate; // Flag to update of cubemap
  421. bool mHeavenlyBodyUpdated;
  422. public:
  423. LLFace* mFace[FACE_COUNT];
  424. LLVector3 mBumpSunDir;
  425. };
  426. #endif