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