PageRenderTime 80ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llwlparamset.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 388 lines | 264 code | 55 blank | 69 comment | 63 complexity | 71730a7ec6c478613eafe2a23eab2c5c MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llwlparamset.cpp
  3. * @brief Implementation for the LLWLParamSet class.
  4. *
  5. * $LicenseInfo:firstyear=2005&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. #include "llviewerprecompiledheaders.h"
  27. #include "llwlparamset.h"
  28. #include "llwlanimator.h"
  29. #include "llwlparammanager.h"
  30. #include "llglslshader.h"
  31. #include "lluictrlfactory.h"
  32. #include "llsliderctrl.h"
  33. #include <llgl.h>
  34. #include <sstream>
  35. LLWLParamSet::LLWLParamSet(void) :
  36. mName("Unnamed Preset"),
  37. mCloudScrollXOffset(0.f), mCloudScrollYOffset(0.f)
  38. {
  39. /* REMOVE or init the LLSD
  40. const std::map<std::string, LLVector4>::value_type hardcodedPreset[] = {
  41. std::make_pair("lightnorm", LLVector4(0.f, 0.707f, -0.707f, 0.f)),
  42. std::make_pair("sunlight_color", LLVector4(0.6f, 0.6f, 2.83f, 2.27f)),
  43. std::make_pair("ambient", LLVector4(0.27f, 0.33f, 0.44f, 1.19f)),
  44. std::make_pair("blue_horizon", LLVector4(0.3f, 0.4f, 0.9f, 1.f)),
  45. std::make_pair("blue_density", LLVector4(0.3f, 0.4f, 0.8f, 1.f)),
  46. std::make_pair("haze_horizon", LLVector4(0.6f, 0.6f, 0.6f, 1.f)),
  47. std::make_pair("haze_density", LLVector4(0.3f, 0.3f, 0.3f, 1.f)),
  48. std::make_pair("cloud_shadow", LLVector4(0.f, 0.f, 0.f, 0.f)),
  49. std::make_pair("density_multiplier", LLVector4(0.001f, 0.001f, 0.001f, 0.001f)),
  50. std::make_pair("distance_multiplier", LLVector4(1.f, 1.f, 1.f, 1.f)),
  51. std::make_pair("max_y", LLVector4(600.f, 600.f, 600.f, 0.f)),
  52. std::make_pair("glow", LLVector4(15.f, 0.001f, -0.03125f, 0.f)),
  53. std::make_pair("cloud_color", LLVector4(0.0f, 0.0f, 0.0f, 0.0f)),
  54. std::make_pair("cloud_pos_density1", LLVector4(0.f, 0.f, 0.f, 1.f)),
  55. std::make_pair("cloud_pos_density2", LLVector4(0.f, 0.f, 0.f, 1.f)),
  56. std::make_pair("cloud_scale", LLVector4(0.42f, 0.f, 0.f, 1.f)),
  57. std::make_pair("gamma", LLVector4(2.0f, 2.0f, 2.0f, 0.0f)),
  58. };
  59. std::map<std::string, LLVector4>::value_type const * endHardcodedPreset =
  60. hardcodedPreset + LL_ARRAY_SIZE(hardcodedPreset);
  61. mParamValues.insert(hardcodedPreset, endHardcodedPreset);
  62. */
  63. }
  64. static LLFastTimer::DeclareTimer FTM_WL_PARAM_UPDATE("WL Param Update");
  65. void LLWLParamSet::update(LLGLSLShader * shader) const
  66. {
  67. LLFastTimer t(FTM_WL_PARAM_UPDATE);
  68. for(LLSD::map_const_iterator i = mParamValues.beginMap();
  69. i != mParamValues.endMap();
  70. ++i)
  71. {
  72. const std::string& param = i->first;
  73. if( param == "star_brightness" || param == "preset_num" || param == "sun_angle" ||
  74. param == "east_angle" || param == "enable_cloud_scroll" ||
  75. param == "cloud_scroll_rate" || param == "lightnorm" )
  76. {
  77. continue;
  78. }
  79. if(param == "cloud_pos_density1")
  80. {
  81. LLVector4 val;
  82. val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
  83. val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
  84. val.mV[2] = (F32) i->second[2].asReal();
  85. val.mV[3] = (F32) i->second[3].asReal();
  86. stop_glerror();
  87. shader->uniform4fv(param, 1, val.mV);
  88. stop_glerror();
  89. }
  90. else // param is the uniform name
  91. {
  92. LLVector4 val;
  93. // handle all the different cases
  94. if(i->second.isArray() && i->second.size() == 4)
  95. {
  96. val.mV[0] = (F32) i->second[0].asReal();
  97. val.mV[1] = (F32) i->second[1].asReal();
  98. val.mV[2] = (F32) i->second[2].asReal();
  99. val.mV[3] = (F32) i->second[3].asReal();
  100. }
  101. else if(i->second.isReal())
  102. {
  103. val.mV[0] = (F32) i->second.asReal();
  104. }
  105. else if(i->second.isInteger())
  106. {
  107. val.mV[0] = (F32) i->second.asReal();
  108. }
  109. else if(i->second.isBoolean())
  110. {
  111. val.mV[0] = i->second.asBoolean();
  112. }
  113. stop_glerror();
  114. shader->uniform4fv(param, 1, val.mV);
  115. stop_glerror();
  116. }
  117. }
  118. }
  119. void LLWLParamSet::set(const std::string& paramName, float x)
  120. {
  121. // handle case where no array
  122. if(mParamValues[paramName].isReal())
  123. {
  124. mParamValues[paramName] = x;
  125. }
  126. // handle array
  127. else if(mParamValues[paramName].isArray() &&
  128. mParamValues[paramName][0].isReal())
  129. {
  130. mParamValues[paramName][0] = x;
  131. }
  132. }
  133. void LLWLParamSet::set(const std::string& paramName, float x, float y) {
  134. mParamValues[paramName][0] = x;
  135. mParamValues[paramName][1] = y;
  136. }
  137. void LLWLParamSet::set(const std::string& paramName, float x, float y, float z)
  138. {
  139. mParamValues[paramName][0] = x;
  140. mParamValues[paramName][1] = y;
  141. mParamValues[paramName][2] = z;
  142. }
  143. void LLWLParamSet::set(const std::string& paramName, float x, float y, float z, float w)
  144. {
  145. mParamValues[paramName][0] = x;
  146. mParamValues[paramName][1] = y;
  147. mParamValues[paramName][2] = z;
  148. mParamValues[paramName][3] = w;
  149. }
  150. void LLWLParamSet::set(const std::string& paramName, const float * val)
  151. {
  152. mParamValues[paramName][0] = val[0];
  153. mParamValues[paramName][1] = val[1];
  154. mParamValues[paramName][2] = val[2];
  155. mParamValues[paramName][3] = val[3];
  156. }
  157. void LLWLParamSet::set(const std::string& paramName, const LLVector4 & val)
  158. {
  159. mParamValues[paramName][0] = val.mV[0];
  160. mParamValues[paramName][1] = val.mV[1];
  161. mParamValues[paramName][2] = val.mV[2];
  162. mParamValues[paramName][3] = val.mV[3];
  163. }
  164. void LLWLParamSet::set(const std::string& paramName, const LLColor4 & val)
  165. {
  166. mParamValues[paramName][0] = val.mV[0];
  167. mParamValues[paramName][1] = val.mV[1];
  168. mParamValues[paramName][2] = val.mV[2];
  169. mParamValues[paramName][3] = val.mV[3];
  170. }
  171. LLVector4 LLWLParamSet::getVector(const std::string& paramName, bool& error)
  172. {
  173. // test to see if right type
  174. LLSD cur_val = mParamValues.get(paramName);
  175. if (!cur_val.isArray())
  176. {
  177. error = true;
  178. return LLVector4(0,0,0,0);
  179. }
  180. LLVector4 val;
  181. val.mV[0] = (F32) cur_val[0].asReal();
  182. val.mV[1] = (F32) cur_val[1].asReal();
  183. val.mV[2] = (F32) cur_val[2].asReal();
  184. val.mV[3] = (F32) cur_val[3].asReal();
  185. error = false;
  186. return val;
  187. }
  188. F32 LLWLParamSet::getFloat(const std::string& paramName, bool& error)
  189. {
  190. // test to see if right type
  191. LLSD cur_val = mParamValues.get(paramName);
  192. if (cur_val.isArray() && cur_val.size() != 0)
  193. {
  194. error = false;
  195. return (F32) cur_val[0].asReal();
  196. }
  197. if(cur_val.isReal())
  198. {
  199. error = false;
  200. return (F32) cur_val.asReal();
  201. }
  202. error = true;
  203. return 0;
  204. }
  205. void LLWLParamSet::setSunAngle(float val)
  206. {
  207. // keep range 0 - 2pi
  208. if(val > F_TWO_PI || val < 0)
  209. {
  210. F32 num = val / F_TWO_PI;
  211. num -= floor(num);
  212. val = F_TWO_PI * num;
  213. }
  214. mParamValues["sun_angle"] = val;
  215. }
  216. void LLWLParamSet::setEastAngle(float val)
  217. {
  218. // keep range 0 - 2pi
  219. if(val > F_TWO_PI || val < 0)
  220. {
  221. F32 num = val / F_TWO_PI;
  222. num -= floor(num);
  223. val = F_TWO_PI * num;
  224. }
  225. mParamValues["east_angle"] = val;
  226. }
  227. void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
  228. {
  229. // set up the iterators
  230. // keep cloud positions and coverage the same
  231. /// TODO masking will do this later
  232. F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
  233. F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
  234. F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
  235. F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
  236. F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();
  237. LLSD srcVal;
  238. LLSD destVal;
  239. // Iterate through values
  240. for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
  241. {
  242. // If param exists in both src and dest, set the holder variables, otherwise skip
  243. if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first))
  244. {
  245. srcVal = src.mParamValues[iter->first];
  246. destVal = dest.mParamValues[iter->first];
  247. }
  248. else
  249. {
  250. continue;
  251. }
  252. if(iter->second.isReal()) // If it's a real, interpolate directly
  253. {
  254. iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight);
  255. }
  256. else if(iter->second.isArray() && iter->second[0].isReal() // If it's an array of reals, loop through the reals and interpolate on those
  257. && iter->second.size() == srcVal.size() && iter->second.size() == destVal.size())
  258. {
  259. // Actually do interpolation: old value + (difference in values * factor)
  260. for(int i=0; i < iter->second.size(); ++i)
  261. {
  262. // iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal(); // old way of doing it -- equivalent but one more operation
  263. iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight);
  264. }
  265. }
  266. else // Else, skip
  267. {
  268. continue;
  269. }
  270. }
  271. // now mix the extra parameters
  272. setStarBrightness((1 - weight) * (F32) src.getStarBrightness()
  273. + weight * (F32) dest.getStarBrightness());
  274. llassert(src.getSunAngle() >= - F_PI &&
  275. src.getSunAngle() <= 3 * F_PI);
  276. llassert(dest.getSunAngle() >= - F_PI &&
  277. dest.getSunAngle() <= 3 * F_PI);
  278. llassert(src.getEastAngle() >= 0 &&
  279. src.getEastAngle() <= 4 * F_PI);
  280. llassert(dest.getEastAngle() >= 0 &&
  281. dest.getEastAngle() <= 4 * F_PI);
  282. // sun angle and east angle require some handling to make sure
  283. // they go in circles. Yes quaternions would work better.
  284. F32 srcSunAngle = src.getSunAngle();
  285. F32 destSunAngle = dest.getSunAngle();
  286. F32 srcEastAngle = src.getEastAngle();
  287. F32 destEastAngle = dest.getEastAngle();
  288. if(fabsf(srcSunAngle - destSunAngle) > F_PI)
  289. {
  290. if(srcSunAngle > destSunAngle)
  291. {
  292. destSunAngle += 2 * F_PI;
  293. }
  294. else
  295. {
  296. srcSunAngle += 2 * F_PI;
  297. }
  298. }
  299. if(fabsf(srcEastAngle - destEastAngle) > F_PI)
  300. {
  301. if(srcEastAngle > destEastAngle)
  302. {
  303. destEastAngle += 2 * F_PI;
  304. }
  305. else
  306. {
  307. srcEastAngle += 2 * F_PI;
  308. }
  309. }
  310. setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
  311. setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);
  312. // now setup the sun properly
  313. // reset those cloud positions
  314. mParamValues["cloud_pos_density1"][0] = cloudPos1X;
  315. mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
  316. mParamValues["cloud_pos_density2"][0] = cloudPos2X;
  317. mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
  318. mParamValues["cloud_shadow"][0] = cloudCover;
  319. }
  320. void LLWLParamSet::updateCloudScrolling(void)
  321. {
  322. static LLTimer s_cloud_timer;
  323. F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();
  324. if(getEnableCloudScrollX())
  325. {
  326. mCloudScrollXOffset += F32(delta_t * (getCloudScrollX() - 10.f) / 100.f);
  327. }
  328. if(getEnableCloudScrollY())
  329. {
  330. mCloudScrollYOffset += F32(delta_t * (getCloudScrollY() - 10.f) / 100.f);
  331. }
  332. }