PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

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