PageRenderTime 84ms CodeModel.GetById 29ms app.highlight 37ms RepoModel.GetById 14ms app.codeStats 0ms

/indra/newview/llwlanimator.cpp

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