PageRenderTime 425ms CodeModel.GetById 93ms app.highlight 113ms RepoModel.GetById 107ms app.codeStats 0ms

/indra/newview/llagentpilot.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 406 lines | 334 code | 45 blank | 27 comment | 38 complexity | c3abf728dc9b8b6ecb2059ebbc45ac41 MD5 | raw file
  1/** 
  2 * @file llagentpilot.cpp
  3 * @brief LLAgentPilot class implementation
  4 *
  5 * $LicenseInfo:firstyear=2002&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 <iostream>
 30#include <fstream>
 31#include <iomanip>
 32
 33#include "llagentpilot.h"
 34#include "llagent.h"
 35#include "llappviewer.h"
 36#include "llviewercontrol.h"
 37#include "llviewercamera.h"
 38#include "llsdserialize.h"
 39#include "llsdutil_math.h"
 40
 41LLAgentPilot gAgentPilot;
 42
 43LLAgentPilot::LLAgentPilot() :
 44	mNumRuns(-1),
 45	mQuitAfterRuns(FALSE),
 46	mRecording(FALSE),
 47	mLastRecordTime(0.f),
 48	mStarted(FALSE),
 49	mPlaying(FALSE),
 50	mCurrentAction(0),
 51	mOverrideCamera(FALSE),
 52	mLoop(TRUE),
 53	mReplaySession(FALSE)
 54{
 55}
 56
 57LLAgentPilot::~LLAgentPilot()
 58{
 59}
 60
 61void LLAgentPilot::load()
 62{
 63	std::string txt_filename = gSavedSettings.getString("StatsPilotFile");
 64	std::string xml_filename = gSavedSettings.getString("StatsPilotXMLFile");
 65	if (LLFile::isfile(xml_filename))
 66	{
 67		loadXML(xml_filename);
 68	}
 69	else if (LLFile::isfile(txt_filename))
 70	{
 71		loadTxt(txt_filename);
 72	}
 73	else
 74	{
 75		lldebugs << "no autopilot file found" << llendl;
 76		return;
 77	}
 78}
 79
 80void LLAgentPilot::loadTxt(const std::string& filename)
 81{
 82	if(filename.empty())
 83	{
 84		return;
 85	}
 86	
 87	llifstream file(filename);
 88
 89	if (!file)
 90	{
 91		lldebugs << "Couldn't open " << filename
 92			<< ", aborting agentpilot load!" << llendl;
 93		return;
 94	}
 95	else
 96	{
 97		llinfos << "Opening pilot file " << filename << llendl;
 98	}
 99
100	mActions.reset();
101	S32 num_actions;
102
103	file >> num_actions;
104
105	for (S32 i = 0; i < num_actions; i++)
106	{
107		S32 action_type;
108		Action new_action;
109		file >> new_action.mTime >> action_type;
110		file >> new_action.mTarget.mdV[VX] >> new_action.mTarget.mdV[VY] >> new_action.mTarget.mdV[VZ];
111		new_action.mType = (EActionType)action_type;
112		mActions.put(new_action);
113	}
114
115	mOverrideCamera = false;
116	
117	file.close();
118}
119
120void LLAgentPilot::loadXML(const std::string& filename)
121{
122	if(filename.empty())
123	{
124		return;
125	}
126	
127	llifstream file(filename);
128
129	if (!file)
130	{
131		lldebugs << "Couldn't open " << filename
132			<< ", aborting agentpilot load!" << llendl;
133		return;
134	}
135	else
136	{
137		llinfos << "Opening pilot file " << filename << llendl;
138	}
139
140	mActions.reset();
141	LLSD record;
142	while (!file.eof() && LLSDSerialize::fromXML(record, file))
143	{
144		Action action;
145		action.mTime = record["time"].asReal();
146		action.mType = (EActionType)record["type"].asInteger();
147		action.mCameraView = record["camera_view"].asReal();
148		action.mTarget = ll_vector3d_from_sd(record["target"]);
149		action.mCameraOrigin = ll_vector3_from_sd(record["camera_origin"]);
150		action.mCameraXAxis = ll_vector3_from_sd(record["camera_xaxis"]);
151		action.mCameraYAxis = ll_vector3_from_sd(record["camera_yaxis"]);
152		action.mCameraZAxis = ll_vector3_from_sd(record["camera_zaxis"]);
153		mActions.put(action);
154	}
155	mOverrideCamera = true;
156	file.close();
157}
158
159void LLAgentPilot::save()
160{
161	std::string txt_filename = gSavedSettings.getString("StatsPilotFile");
162	std::string xml_filename = gSavedSettings.getString("StatsPilotXMLFile");
163	saveTxt(txt_filename);
164	saveXML(xml_filename);
165}
166
167void LLAgentPilot::saveTxt(const std::string& filename)
168{
169	llofstream file;
170	file.open(filename);
171
172	if (!file)
173	{
174		llinfos << "Couldn't open " << filename << ", aborting agentpilot save!" << llendl;
175	}
176
177	file << mActions.count() << '\n';
178
179	S32 i;
180	for (i = 0; i < mActions.count(); i++)
181	{
182		file << mActions[i].mTime << "\t" << mActions[i].mType << "\t";
183		file << std::setprecision(32) << mActions[i].mTarget.mdV[VX] << "\t" << mActions[i].mTarget.mdV[VY] << "\t" << mActions[i].mTarget.mdV[VZ];
184		file << '\n';
185	}
186
187	file.close();
188}
189
190void LLAgentPilot::saveXML(const std::string& filename)
191{
192	llofstream file;
193	file.open(filename);
194
195	if (!file)
196	{
197		llinfos << "Couldn't open " << filename << ", aborting agentpilot save!" << llendl;
198	}
199
200	S32 i;
201	for (i = 0; i < mActions.count(); i++)
202	{
203		Action& action = mActions[i];
204		LLSD record;
205		record["time"] = (LLSD::Real)action.mTime;
206		record["type"] = (LLSD::Integer)action.mType;
207		record["camera_view"] = (LLSD::Real)action.mCameraView;
208		record["target"] = ll_sd_from_vector3d(action.mTarget);
209		record["camera_origin"] = ll_sd_from_vector3(action.mCameraOrigin);
210		record["camera_xaxis"] = ll_sd_from_vector3(action.mCameraXAxis);
211		record["camera_yaxis"] = ll_sd_from_vector3(action.mCameraYAxis);
212		record["camera_zaxis"] = ll_sd_from_vector3(action.mCameraZAxis);
213		LLSDSerialize::toXML(record, file);
214	}
215	file.close();
216}
217
218void LLAgentPilot::startRecord()
219{
220	mActions.reset();
221	mTimer.reset();
222	addAction(STRAIGHT);
223	mRecording = TRUE;
224}
225
226void LLAgentPilot::stopRecord()
227{
228	gAgentPilot.addAction(STRAIGHT);
229	gAgentPilot.save();
230	mRecording = FALSE;
231}
232
233void LLAgentPilot::addAction(enum EActionType action_type)
234{
235	llinfos << "Adding waypoint: " << gAgent.getPositionGlobal() << llendl;
236	Action action;
237	action.mType = action_type;
238	action.mTarget = gAgent.getPositionGlobal();
239	action.mTime = mTimer.getElapsedTimeF32();
240	LLViewerCamera *cam = LLViewerCamera::getInstance();
241	action.mCameraView = cam->getView();
242	action.mCameraOrigin = cam->getOrigin();
243	action.mCameraXAxis = cam->getXAxis();
244	action.mCameraYAxis = cam->getYAxis();
245	action.mCameraZAxis = cam->getZAxis();
246	mLastRecordTime = (F32)action.mTime;
247	mActions.put(action);
248}
249
250void LLAgentPilot::startPlayback()
251{
252	if (!mPlaying)
253	{
254		mPlaying = TRUE;
255		mCurrentAction = 0;
256		mTimer.reset();
257
258		if (mActions.count())
259		{
260			llinfos << "Starting playback, moving to waypoint 0" << llendl;
261			gAgent.startAutoPilotGlobal(mActions[0].mTarget);
262			moveCamera();
263			mStarted = FALSE;
264		}
265		else
266		{
267			llinfos << "No autopilot data, cancelling!" << llendl;
268			mPlaying = FALSE;
269		}
270	}
271}
272
273void LLAgentPilot::stopPlayback()
274{
275	if (mPlaying)
276	{
277		mPlaying = FALSE;
278		mCurrentAction = 0;
279		mTimer.reset();
280		gAgent.stopAutoPilot();
281	}
282
283	if (mReplaySession)
284	{
285		LLAppViewer::instance()->forceQuit();
286	}
287}
288
289void LLAgentPilot::moveCamera()
290{
291	if (!getOverrideCamera())
292		return;
293
294	if (mCurrentAction<mActions.count())
295	{
296		S32 start_index = llmax(mCurrentAction-1,0);
297		S32 end_index = mCurrentAction;
298		F32 t = 0.0;
299		F32 timedelta = mActions[end_index].mTime - mActions[start_index].mTime;
300		F32 tickelapsed = mTimer.getElapsedTimeF32()-mActions[start_index].mTime;
301		if (timedelta > 0.0)
302		{
303			t = tickelapsed/timedelta;
304		}
305
306		if ((t<0.0)||(t>1.0))
307		{
308			llwarns << "mCurrentAction is invalid, t = " << t << llendl;
309			return;
310		}
311		
312		Action& start = mActions[start_index];
313		Action& end = mActions[end_index];
314
315		F32 view = lerp(start.mCameraView, end.mCameraView, t);
316		LLVector3 origin = lerp(start.mCameraOrigin, end.mCameraOrigin, t);
317		LLQuaternion start_quat(start.mCameraXAxis, start.mCameraYAxis, start.mCameraZAxis);
318		LLQuaternion end_quat(end.mCameraXAxis, end.mCameraYAxis, end.mCameraZAxis);
319		LLQuaternion quat = nlerp(t, start_quat, end_quat);
320		LLMatrix3 mat(quat);
321	
322		LLViewerCamera::getInstance()->setView(view);
323		LLViewerCamera::getInstance()->setOrigin(origin);
324		LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]);
325		LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]);
326		LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]);
327	}
328}
329
330void LLAgentPilot::updateTarget()
331{
332	if (mPlaying)
333	{
334		if (mCurrentAction < mActions.count())
335		{
336			if (0 == mCurrentAction)
337			{
338				if (gAgent.getAutoPilot())
339				{
340					// Wait until we get to the first location before starting.
341					return;
342				}
343				else
344				{
345					if (!mStarted)
346					{
347						llinfos << "At start, beginning playback" << llendl;
348						mTimer.reset();
349						mStarted = TRUE;
350					}
351				}
352			}
353			if (mTimer.getElapsedTimeF32() > mActions[mCurrentAction].mTime)
354			{
355				//gAgent.stopAutoPilot();
356				mCurrentAction++;
357
358				if (mCurrentAction < mActions.count())
359				{
360					gAgent.startAutoPilotGlobal(mActions[mCurrentAction].mTarget);
361					moveCamera();
362				}
363				else
364				{
365					stopPlayback();
366					mNumRuns--;
367					if (mLoop)
368					{
369						if ((mNumRuns < 0) || (mNumRuns > 0))
370						{
371							llinfos << "Looping, restarting playback" << llendl;
372							startPlayback();
373						}
374						else if (mQuitAfterRuns)
375						{
376							llinfos << "Done with all runs, quitting viewer!" << llendl;
377							LLAppViewer::instance()->forceQuit();
378						}
379						else
380						{
381							llinfos << "Done with all runs, disabling pilot" << llendl;
382							stopPlayback();
383						}
384					}
385				}
386			}
387		}
388		else
389		{
390			stopPlayback();
391		}
392	}
393	else if (mRecording)
394	{
395		if (mTimer.getElapsedTimeF32() - mLastRecordTime > 1.f)
396		{
397			addAction(STRAIGHT);
398		}
399	}
400}
401
402void LLAgentPilot::addWaypoint()
403{
404	addAction(STRAIGHT);
405}
406