llsettingswater.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /**
  2. * @file llsettingswater.cpp
  3. * @brief The water settings asset support class.
  4. *
  5. * $LicenseInfo:firstyear=2018&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2019, 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. #include "linden_common.h"
  33. #include "llsettingswater.h"
  34. #include "imageids.h"
  35. const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER = "blur_multiplier";
  36. const std::string LLSettingsWater::SETTING_FOG_COLOR = "water_fog_color";
  37. const std::string LLSettingsWater::SETTING_FOG_DENSITY = "water_fog_density";
  38. const std::string LLSettingsWater::SETTING_FOG_MOD = "underwater_fog_mod";
  39. const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET = "fresnel_offset";
  40. const std::string LLSettingsWater::SETTING_FRESNEL_SCALE = "fresnel_scale";
  41. const std::string LLSettingsWater::SETTING_TRANSPARENT_TEXTURE = "transparent_texture";
  42. const std::string LLSettingsWater::SETTING_NORMAL_MAP = "normal_map";
  43. const std::string LLSettingsWater::SETTING_NORMAL_SCALE = "normal_scale";
  44. const std::string LLSettingsWater::SETTING_SCALE_ABOVE = "scale_above";
  45. const std::string LLSettingsWater::SETTING_SCALE_BELOW = "scale_below";
  46. const std::string LLSettingsWater::SETTING_WAVE1_DIR = "wave1_direction";
  47. const std::string LLSettingsWater::SETTING_WAVE2_DIR = "wave2_direction";
  48. const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPLIER = "blurMultiplier";
  49. const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR = "waterFogColor";
  50. const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY = "waterFogDensity";
  51. const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD = "underWaterFogMod";
  52. const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET = "fresnelOffset";
  53. const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE = "fresnelScale";
  54. const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP = "normalMap";
  55. const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE = "normScale";
  56. const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE = "scaleAbove";
  57. const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW = "scaleBelow";
  58. const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR = "wave1Dir";
  59. const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR = "wave2Dir";
  60. const LLUUID LLSettingsWater::DEFAULT_ASSET_ID("59d1a851-47e7-0e5f-1ed7-6b715154f41a");
  61. LLSettingsWater::LLSettingsWater(const LLSD& data)
  62. : LLSettingsBase(data),
  63. mBlurMultiplier(1.f),
  64. mFresnelOffset(0.f),
  65. mFresnelScale(1.f),
  66. mScaleAbove(1.f),
  67. mScaleBelow(1.f),
  68. mWaterFogDensity(1.f)
  69. {
  70. }
  71. LLSettingsWater::LLSettingsWater()
  72. : LLSettingsBase(),
  73. mBlurMultiplier(1.f),
  74. mFresnelOffset(0.f),
  75. mFresnelScale(1.f),
  76. mScaleAbove(1.f),
  77. mScaleBelow(1.f),
  78. mWaterFogDensity(1.f)
  79. {
  80. }
  81. //static
  82. LLSD LLSettingsWater::defaults(F32 position)
  83. {
  84. static LLSD defaults;
  85. if (defaults.size() == 0)
  86. {
  87. // Magic constants copied form defaults.xml
  88. defaults[SETTING_BLUR_MULTIPLIER] = LLSD::Real(0.04);
  89. defaults[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.149f,
  90. 0.2509f).getValue();
  91. defaults[SETTING_FOG_DENSITY] = LLSD::Real(2.0);
  92. defaults[SETTING_FOG_MOD] = LLSD::Real(0.25);
  93. defaults[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5);
  94. defaults[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999);
  95. defaults[SETTING_TRANSPARENT_TEXTURE] =
  96. getDefaultTransparentTextureAssetId();
  97. defaults[SETTING_NORMAL_MAP] = getDefaultWaterNormalAssetId();
  98. defaults[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299);
  99. defaults[SETTING_SCALE_BELOW] = LLSD::Real(0.2);
  100. defaults[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42f).getValue();
  101. defaults[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16f).getValue();
  102. defaults[SETTING_TYPE] = "water";
  103. }
  104. // Give the normal scale offset some variability over track time...
  105. F32 norm_scale_offset = position * 0.5f - 0.25f;
  106. defaults[SETTING_NORMAL_SCALE] =
  107. LLVector3(2.f + norm_scale_offset, 2.f + norm_scale_offset,
  108. 2.f + norm_scale_offset).getValue();
  109. return defaults;
  110. }
  111. //static
  112. void LLSettingsWater::adjustTime(LLSD& settings, F32 position)
  113. {
  114. if (!settings.has(SETTING_NORMAL_SCALE))
  115. {
  116. // Settings empty or invalid: use default settings.
  117. settings = defaults(position);
  118. return;
  119. }
  120. // Give the normal scale offset some variability over track time...
  121. F32 offset = position * 0.5f - 0.25f;
  122. settings[SETTING_NORMAL_SCALE] =
  123. LLVector3(2.f + offset, 2.f + offset, 2.f + offset).getValue();
  124. }
  125. LLSD LLSettingsWater::translateLegacySettings(const LLSD& legacy)
  126. {
  127. bool converted_something(false);
  128. LLSD newsettings(defaults());
  129. if (legacy.has(SETTING_LEGACY_BLUR_MULTIPLIER))
  130. {
  131. newsettings[SETTING_BLUR_MULTIPLIER] =
  132. LLSD::Real(legacy[SETTING_LEGACY_BLUR_MULTIPLIER].asReal());
  133. converted_something = true;
  134. }
  135. if (legacy.has(SETTING_LEGACY_FOG_COLOR))
  136. {
  137. newsettings[SETTING_FOG_COLOR] =
  138. LLColor3(legacy[SETTING_LEGACY_FOG_COLOR]).getValue();
  139. converted_something = true;
  140. }
  141. if (legacy.has(SETTING_LEGACY_FOG_DENSITY))
  142. {
  143. newsettings[SETTING_FOG_DENSITY] =
  144. LLSD::Real(legacy[SETTING_LEGACY_FOG_DENSITY]);
  145. converted_something = true;
  146. }
  147. if (legacy.has(SETTING_LEGACY_FOG_MOD))
  148. {
  149. newsettings[SETTING_FOG_MOD] =
  150. LLSD::Real(legacy[SETTING_LEGACY_FOG_MOD].asReal());
  151. converted_something = true;
  152. }
  153. if (legacy.has(SETTING_LEGACY_FRESNEL_OFFSET))
  154. {
  155. newsettings[SETTING_FRESNEL_OFFSET] =
  156. LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_OFFSET].asReal());
  157. converted_something = true;
  158. }
  159. if (legacy.has(SETTING_LEGACY_FRESNEL_SCALE))
  160. {
  161. newsettings[SETTING_FRESNEL_SCALE] =
  162. LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_SCALE].asReal());
  163. converted_something = true;
  164. }
  165. if (legacy.has(SETTING_LEGACY_NORMAL_MAP))
  166. {
  167. newsettings[SETTING_NORMAL_MAP] =
  168. LLSD::UUID(legacy[SETTING_LEGACY_NORMAL_MAP].asUUID());
  169. converted_something = true;
  170. }
  171. if (legacy.has(SETTING_LEGACY_NORMAL_SCALE))
  172. {
  173. newsettings[SETTING_NORMAL_SCALE] =
  174. LLVector3(legacy[SETTING_LEGACY_NORMAL_SCALE]).getValue();
  175. converted_something = true;
  176. }
  177. if (legacy.has(SETTING_LEGACY_SCALE_ABOVE))
  178. {
  179. newsettings[SETTING_SCALE_ABOVE] =
  180. LLSD::Real(legacy[SETTING_LEGACY_SCALE_ABOVE].asReal());
  181. converted_something = true;
  182. }
  183. if (legacy.has(SETTING_LEGACY_SCALE_BELOW))
  184. {
  185. newsettings[SETTING_SCALE_BELOW] =
  186. LLSD::Real(legacy[SETTING_LEGACY_SCALE_BELOW].asReal());
  187. converted_something = true;
  188. }
  189. if (legacy.has(SETTING_LEGACY_WAVE1_DIR))
  190. {
  191. newsettings[SETTING_WAVE1_DIR] =
  192. LLVector2(legacy[SETTING_LEGACY_WAVE1_DIR]).getValue();
  193. converted_something = true;
  194. }
  195. if (legacy.has(SETTING_LEGACY_WAVE2_DIR))
  196. {
  197. newsettings[SETTING_WAVE2_DIR] =
  198. LLVector2(legacy[SETTING_LEGACY_WAVE2_DIR]).getValue();
  199. converted_something = true;
  200. }
  201. return converted_something ? newsettings : LLSD();
  202. }
  203. void LLSettingsWater::updateSettings()
  204. {
  205. // Base class clears dirty flag so as to not trigger recursive update.
  206. // NOTE: this *must* be invoked first in this method ! HB
  207. LLSettingsBase::updateSettings();
  208. mBlurMultiplier = mSettings[SETTING_BLUR_MULTIPLIER].asReal();
  209. mFresnelOffset = mSettings[SETTING_FRESNEL_OFFSET].asReal();
  210. mFresnelScale = mSettings[SETTING_FRESNEL_SCALE].asReal();
  211. mNormalScale.setValue(mSettings[SETTING_NORMAL_SCALE]);
  212. mScaleAbove = mSettings[SETTING_SCALE_ABOVE].asReal();
  213. mScaleBelow = mSettings[SETTING_SCALE_BELOW].asReal();
  214. mWave1Dir.setValue(mSettings[SETTING_WAVE1_DIR]);
  215. mWave2Dir.setValue(mSettings[SETTING_WAVE2_DIR]);
  216. mWaterFogColor.setValue(mSettings[SETTING_FOG_COLOR]);
  217. mWaterFogDensity = mSettings[SETTING_FOG_DENSITY].asReal();
  218. }
  219. void LLSettingsWater::blend(const LLSettingsBase::ptr_t& end, F64 blendf)
  220. {
  221. LLSettingsWater::ptr_t other =
  222. std::static_pointer_cast<LLSettingsWater>(end);
  223. if (other)
  224. {
  225. LLSD blenddata = interpolateSDMap(mSettings, other->mSettings,
  226. other->getParameterMap(), blendf);
  227. replaceSettings(blenddata);
  228. mNextNormalMapID = other->getNormalMapID();
  229. mNextTransparentTextureID = other->getTransparentTextureID();
  230. }
  231. else
  232. {
  233. llwarns << "Could not cast end settings to water. No blend performed."
  234. << llendl;
  235. }
  236. setBlendFactor(blendf);
  237. }
  238. void LLSettingsWater::replaceSettings(const LLSD& settings)
  239. {
  240. LLSettingsBase::replaceSettings(settings);
  241. mNextNormalMapID.setNull();
  242. mNextTransparentTextureID.setNull();
  243. }
  244. void LLSettingsWater::replaceWithWater(LLSettingsWater::ptr_t other)
  245. {
  246. replaceWith(other);
  247. mNextNormalMapID = other->mNextNormalMapID;
  248. mNextTransparentTextureID = other->mNextTransparentTextureID;
  249. }
  250. //virtual
  251. const LLSettingsWater::validation_list_t& LLSettingsWater::getValidationList() const
  252. {
  253. return LLSettingsWater::validationList();
  254. }
  255. //static
  256. const LLSettingsWater::validation_list_t& LLSettingsWater::validationList()
  257. {
  258. static validation_list_t validation;
  259. if (validation.empty())
  260. {
  261. validation.emplace_back(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
  262. boost::bind(&Validator::verifyFloatRange,
  263. _1, _2, llsd::array(-0.5f, 0.5f)));
  264. validation.emplace_back(SETTING_FOG_COLOR, true, LLSD::TypeArray,
  265. boost::bind(&Validator::verifyVectorMinMax,
  266. _1, _2,
  267. llsd::array(0.0, 0.0, 0.0, 1.0),
  268. llsd::array(1.0, 1.0, 1.0, 1.0)));
  269. validation.emplace_back(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
  270. boost::bind(&Validator::verifyFloatRange,
  271. _1, _2, llsd::array(-10.0, 10.0)));
  272. validation.emplace_back(SETTING_FOG_MOD, true, LLSD::TypeReal,
  273. boost::bind(&Validator::verifyFloatRange,
  274. _1, _2, llsd::array(0.0, 20.0)));
  275. validation.emplace_back(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
  276. boost::bind(&Validator::verifyFloatRange,
  277. _1, _2, llsd::array(0.0, 1.0)));
  278. validation.emplace_back(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
  279. boost::bind(&Validator::verifyFloatRange,
  280. _1, _2, llsd::array(0.0, 1.0)));
  281. validation.emplace_back(SETTING_NORMAL_MAP, true, LLSD::TypeUUID);
  282. validation.emplace_back(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
  283. boost::bind(&Validator::verifyVectorMinMax,
  284. _1, _2, llsd::array(0.0, 0.0, 0.0),
  285. llsd::array(10.0, 10.0, 10.0)));
  286. validation.emplace_back(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
  287. boost::bind(&Validator::verifyFloatRange,
  288. _1, _2, llsd::array(0.0, 3.0)));
  289. validation.emplace_back(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
  290. boost::bind(&Validator::verifyFloatRange,
  291. _1, _2, llsd::array(0.0, 3.0)));
  292. validation.emplace_back(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
  293. boost::bind(&Validator::verifyVectorMinMax,
  294. _1, _2, llsd::array(-20.0, -20.0),
  295. llsd::array(20.0, 20.0)));
  296. validation.emplace_back(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
  297. boost::bind(&Validator::verifyVectorMinMax,
  298. _1, _2, llsd::array(-20.0, -20.0),
  299. llsd::array(20.0, 20.0)));
  300. }
  301. return validation;
  302. }
  303. const LLUUID& LLSettingsWater::getDefaultAssetId()
  304. {
  305. return DEFAULT_ASSET_ID;
  306. }
  307. const LLUUID& LLSettingsWater::getDefaultWaterNormalAssetId()
  308. {
  309. return DEFAULT_WATER_NORMAL;
  310. }
  311. const LLUUID& LLSettingsWater::getDefaultTransparentTextureAssetId()
  312. {
  313. return DEFAULT_WATER_TEXTURE;
  314. }
  315. const LLUUID& LLSettingsWater::getDefaultOpaqueTextureAssetId()
  316. {
  317. return DEFAULT_WATER_OPAQUE;
  318. }
  319. F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const
  320. {
  321. F32 fog_density = getWaterFogDensity();
  322. F32 underwater_fog_mod = getFogMod();
  323. if (underwater && underwater_fog_mod > 0.f)
  324. {
  325. underwater_fog_mod = llclamp(underwater_fog_mod, 0.f, 10.f);
  326. // BUG-233797/BUG-233798: negative underwater fog density can cause
  327. // (unrecoverable) blackout; raising a negative number to a non-
  328. // integral power results in a non-real result (which NaN for our
  329. // purposes). So we force density to be an arbitrary non-negative
  330. // (i.e. 1) when underwater and modifier is not an integer (1 was
  331. // chosen as it gives at least some notion of fog in the transition).
  332. if (fog_density < 0.f &&
  333. underwater_fog_mod != (F32)(S32(underwater_fog_mod)))
  334. {
  335. fog_density = 1.f;
  336. }
  337. else
  338. {
  339. fog_density = powf(fog_density, underwater_fog_mod);
  340. }
  341. }
  342. return fog_density;
  343. }