/indra/newview/llwlanimator.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 313 lines · 208 code · 49 blank · 56 comment · 41 complexity · 70b0c39d75bc9cf348f8963f86c78a5c MD5 · raw file

  1. /**
  2. * @file llwlanimator.cpp
  3. * @brief Implementation for the LLWLAnimator class.
  4. *
  5. * $LicenseInfo:firstyear=2007&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 "llwlanimator.h"
  28. #include "llsky.h"
  29. #include "pipeline.h"
  30. #include "llwlparammanager.h"
  31. #include "llwaterparammanager.h"
  32. extern LLControlGroup gSavedSettings;
  33. F64 LLWLAnimator::INTERP_TOTAL_SECONDS = 3.f;
  34. LLWLAnimator::LLWLAnimator() : mStartTime(0.f), mDayRate(1.f), mDayTime(0.f),
  35. mIsRunning(FALSE), mIsInterpolating(FALSE), mTimeType(TIME_LINDEN),
  36. mInterpStartTime(), mInterpEndTime()
  37. {
  38. mInterpBeginWL = new LLWLParamSet();
  39. mInterpBeginWater = new LLWaterParamSet();
  40. mInterpEndWater = new LLWaterParamSet();
  41. }
  42. void LLWLAnimator::update(LLWLParamSet& curParams)
  43. {
  44. //llassert(mUseLindenTime != mUseLocalTime);
  45. F64 curTime;
  46. curTime = getDayTime();
  47. // don't do anything if empty
  48. if(mTimeTrack.size() == 0)
  49. {
  50. return;
  51. }
  52. // start it off
  53. mFirstIt = mTimeTrack.begin();
  54. mSecondIt = mTimeTrack.begin();
  55. mSecondIt++;
  56. // grab the two tween iterators
  57. while(mSecondIt != mTimeTrack.end() && curTime > mSecondIt->first)
  58. {
  59. mFirstIt++;
  60. mSecondIt++;
  61. }
  62. // scroll it around when you get to the end
  63. if(mSecondIt == mTimeTrack.end() || mFirstIt->first > curTime)
  64. {
  65. mSecondIt = mTimeTrack.begin();
  66. mFirstIt = mTimeTrack.end();
  67. mFirstIt--;
  68. }
  69. F32 weight = 0;
  70. if(mFirstIt->first < mSecondIt->first)
  71. {
  72. // get the delta time and the proper weight
  73. weight = F32 (curTime - mFirstIt->first) /
  74. (mSecondIt->first - mFirstIt->first);
  75. // handle the ends
  76. }
  77. else if(mFirstIt->first > mSecondIt->first)
  78. {
  79. // right edge of time line
  80. if(curTime >= mFirstIt->first)
  81. {
  82. weight = F32 (curTime - mFirstIt->first) /
  83. ((1 + mSecondIt->first) - mFirstIt->first);
  84. // left edge of time line
  85. }
  86. else
  87. {
  88. weight = F32 ((1 + curTime) - mFirstIt->first) /
  89. ((1 + mSecondIt->first) - mFirstIt->first);
  90. }
  91. // handle same as whatever the last one is
  92. }
  93. else
  94. {
  95. weight = 1;
  96. }
  97. if(mIsInterpolating)
  98. {
  99. // *TODO_JACOB: this is kind of laggy. Not sure why. The part that lags is the curParams.mix call, and none of the other mixes. It works, though.
  100. clock_t current = clock();
  101. if(current >= mInterpEndTime)
  102. {
  103. mIsInterpolating = false;
  104. return;
  105. }
  106. // determine moving target for final interpolation value
  107. // *TODO: this will not work with lazy loading of sky presets.
  108. LLWLParamSet buf = LLWLParamSet();
  109. buf.setAll(LLWLParamManager::getInstance()->mParamList[mFirstIt->second].getAll()); // just give it some values, otherwise it has no params to begin with (see comment in constructor)
  110. buf.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight); // mix to determine moving target for interpolation finish (as below)
  111. // mix from previous value to moving target
  112. weight = (current - mInterpStartTime) / (INTERP_TOTAL_SECONDS * CLOCKS_PER_SEC);
  113. curParams.mix(*mInterpBeginWL, buf, weight);
  114. // mix water
  115. LLWaterParamManager::getInstance()->mCurParams.mix(*mInterpBeginWater, *mInterpEndWater, weight);
  116. }
  117. else
  118. {
  119. // do the interpolation and set the parameters
  120. // *TODO: this will not work with lazy loading of sky presets.
  121. curParams.mix(LLWLParamManager::getInstance()->mParamList[mFirstIt->second], LLWLParamManager::getInstance()->mParamList[mSecondIt->second], weight);
  122. }
  123. }
  124. F64 LLWLAnimator::getDayTime()
  125. {
  126. if(!mIsRunning)
  127. {
  128. return mDayTime;
  129. }
  130. else if(mTimeType == TIME_LINDEN)
  131. {
  132. F32 phase = gSky.getSunPhase() / F_PI;
  133. // we're not solving the non-linear equation that determines sun phase
  134. // we're just linearly interpolating between the major points
  135. if (phase <= 5.0 / 4.0) {
  136. mDayTime = (1.0 / 3.0) * phase + (1.0 / 3.0);
  137. }
  138. else
  139. {
  140. mDayTime = phase - (1.0 / 2.0);
  141. }
  142. if(mDayTime > 1)
  143. {
  144. mDayTime--;
  145. }
  146. return mDayTime;
  147. }
  148. else if(mTimeType == TIME_LOCAL)
  149. {
  150. return getLocalTime();
  151. }
  152. // get the time;
  153. mDayTime = (LLTimer::getElapsedSeconds() - mStartTime) / mDayRate;
  154. // clamp it
  155. if(mDayTime < 0)
  156. {
  157. mDayTime = 0;
  158. }
  159. while(mDayTime > 1)
  160. {
  161. mDayTime--;
  162. }
  163. return (F32)mDayTime;
  164. }
  165. void LLWLAnimator::setDayTime(F64 dayTime)
  166. {
  167. //retroactively set start time;
  168. mStartTime = LLTimer::getElapsedSeconds() - dayTime * mDayRate;
  169. mDayTime = dayTime;
  170. // clamp it
  171. if(mDayTime < 0)
  172. {
  173. mDayTime = 0;
  174. }
  175. else if(mDayTime > 1)
  176. {
  177. mDayTime = 1;
  178. }
  179. }
  180. void LLWLAnimator::setTrack(std::map<F32, LLWLParamKey>& curTrack,
  181. F32 dayRate, F64 dayTime, bool run)
  182. {
  183. mTimeTrack = curTrack;
  184. mDayRate = dayRate;
  185. setDayTime(dayTime);
  186. mIsRunning = run;
  187. }
  188. void LLWLAnimator::startInterpolation(const LLSD& targetWater)
  189. {
  190. mInterpBeginWL->setAll(LLWLParamManager::getInstance()->mCurParams.getAll());
  191. mInterpBeginWater->setAll(LLWaterParamManager::getInstance()->mCurParams.getAll());
  192. mInterpStartTime = clock();
  193. mInterpEndTime = mInterpStartTime + clock_t(INTERP_TOTAL_SECONDS) * CLOCKS_PER_SEC;
  194. // Don't set any ending WL -- this is continuously calculated as the animator updates since it's a moving target
  195. mInterpEndWater->setAll(targetWater);
  196. mIsInterpolating = true;
  197. }
  198. std::string LLWLAnimator::timeToString(F32 curTime)
  199. {
  200. S32 hours;
  201. S32 min;
  202. bool isPM = false;
  203. // get hours and minutes
  204. hours = (S32) (24.0 * curTime);
  205. curTime -= ((F32) hours / 24.0f);
  206. min = llround(24.0f * 60.0f * curTime);
  207. // handle case where it's 60
  208. if(min == 60)
  209. {
  210. hours++;
  211. min = 0;
  212. }
  213. // set for PM
  214. if(hours >= 12 && hours < 24)
  215. {
  216. isPM = true;
  217. }
  218. // convert to non-military notation
  219. if(hours >= 24)
  220. {
  221. hours = 12;
  222. }
  223. else if(hours > 12)
  224. {
  225. hours -= 12;
  226. }
  227. else if(hours == 0)
  228. {
  229. hours = 12;
  230. }
  231. // make the string
  232. std::stringstream newTime;
  233. newTime << hours << ":";
  234. // double 0
  235. if(min < 10)
  236. {
  237. newTime << 0;
  238. }
  239. // finish it
  240. newTime << min << " ";
  241. if(isPM)
  242. {
  243. newTime << "PM";
  244. }
  245. else
  246. {
  247. newTime << "AM";
  248. }
  249. return newTime.str();
  250. }
  251. F64 LLWLAnimator::getLocalTime()
  252. {
  253. char buffer[9];
  254. time_t rawtime;
  255. struct tm* timeinfo;
  256. time(&rawtime);
  257. timeinfo = localtime(&rawtime);
  258. strftime(buffer, 9, "%H:%M:%S", timeinfo);
  259. std::string timeStr(buffer);
  260. F64 tod = ((F64)atoi(timeStr.substr(0,2).c_str())) / 24.f +
  261. ((F64)atoi(timeStr.substr(3,2).c_str())) / 1440.f +
  262. ((F64)atoi(timeStr.substr(6,2).c_str())) / 86400.f;
  263. return tod;
  264. }