llkeyframemotionparam.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:14k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llkeyframemotionparam.cpp
  3.  * @brief Implementation of LLKeyframeMotion class.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. //-----------------------------------------------------------------------------
  33. // Header Files
  34. //-----------------------------------------------------------------------------
  35. #include "linden_common.h"
  36. #include "llkeyframemotionparam.h"
  37. #include "llcharacter.h"
  38. #include "llmath.h"
  39. #include "m3math.h"
  40. #include "lldir.h"
  41. #include "llanimationstates.h"
  42. //-----------------------------------------------------------------------------
  43. //-----------------------------------------------------------------------------
  44. // LLKeyframeMotionParam class
  45. //-----------------------------------------------------------------------------
  46. //-----------------------------------------------------------------------------
  47. //-----------------------------------------------------------------------------
  48. // LLKeyframeMotionParam()
  49. // Class Constructor
  50. //-----------------------------------------------------------------------------
  51. LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
  52. {
  53. mDefaultKeyframeMotion = NULL;
  54. mCharacter = NULL;
  55. mEaseInDuration = 0.f;
  56. mEaseOutDuration = 0.f;
  57. mDuration = 0.f;
  58. mPriority = LLJoint::LOW_PRIORITY;
  59. }
  60. //-----------------------------------------------------------------------------
  61. // ~LLKeyframeMotionParam()
  62. // Class Destructor
  63. //-----------------------------------------------------------------------------
  64. LLKeyframeMotionParam::~LLKeyframeMotionParam()
  65. {
  66. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  67.  iter != mParameterizedMotions.end(); ++iter)
  68. {
  69. motion_list_t& motionList = iter->second;
  70. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  71. {
  72. const ParameterizedMotion& paramMotion = *iter2;
  73. delete paramMotion.mMotion;
  74. }
  75. motionList.clear();
  76. }
  77. mParameterizedMotions.clear();
  78. }
  79. //-----------------------------------------------------------------------------
  80. // LLKeyframeMotionParam::onInitialize(LLCharacter *character)
  81. //-----------------------------------------------------------------------------
  82. LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
  83. {
  84. mCharacter = character;
  85. if (!loadMotions())
  86. {
  87. return STATUS_FAILURE;
  88. }
  89. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  90.  iter != mParameterizedMotions.end(); ++iter)
  91. {
  92. motion_list_t& motionList = iter->second;
  93. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  94. {
  95. const ParameterizedMotion& paramMotion = *iter2;
  96. LLMotion* motion = paramMotion.mMotion;
  97. motion->onInitialize(character);
  98. if (motion->getDuration() > mEaseInDuration)
  99. {
  100. mEaseInDuration = motion->getEaseInDuration();
  101. }
  102. if (motion->getEaseOutDuration() > mEaseOutDuration)
  103. {
  104. mEaseOutDuration = motion->getEaseOutDuration();
  105. }
  106. if (motion->getDuration() > mDuration)
  107. {
  108. mDuration = motion->getDuration();
  109. }
  110. if (motion->getPriority() > mPriority)
  111. {
  112. mPriority = motion->getPriority();
  113. }
  114. LLPose *pose = motion->getPose();
  115. mPoseBlender.addMotion(motion);
  116. for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
  117. {
  118. LLPose *blendedPose = mPoseBlender.getBlendedPose();
  119. blendedPose->addJointState(jsp);
  120. }
  121. }
  122. }
  123. return STATUS_SUCCESS;
  124. }
  125. //-----------------------------------------------------------------------------
  126. // LLKeyframeMotionParam::onActivate()
  127. //-----------------------------------------------------------------------------
  128. BOOL LLKeyframeMotionParam::onActivate()
  129. {
  130. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  131.  iter != mParameterizedMotions.end(); ++iter)
  132. {
  133. motion_list_t& motionList = iter->second;
  134. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  135. {
  136. const ParameterizedMotion& paramMotion = *iter2;
  137. paramMotion.mMotion->activate(mActivationTimestamp);
  138. }
  139. }
  140. return TRUE;
  141. }
  142. //-----------------------------------------------------------------------------
  143. // LLKeyframeMotionParam::onUpdate()
  144. //-----------------------------------------------------------------------------
  145. BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
  146. {
  147. F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
  148. // zero out all pose weights
  149. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  150.  iter != mParameterizedMotions.end(); ++iter)
  151. {
  152. motion_list_t& motionList = iter->second;
  153. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  154. {
  155. const ParameterizedMotion& paramMotion = *iter2;
  156. // llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl;
  157. paramMotion.mMotion->getPose()->setWeight(0.f);
  158. }
  159. }
  160. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  161.  iter != mParameterizedMotions.end(); ++iter)
  162. {
  163. const std::string& paramName = iter->first;
  164. F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
  165. if (NULL == paramValue) // unexpected, but...
  166. {
  167. llwarns << "paramValue == NULL" << llendl;
  168. continue;
  169. }
  170. // DANGER! Do not modify mParameterizedMotions while using these pointers!
  171. const ParameterizedMotion* firstMotion = NULL;
  172. const ParameterizedMotion* secondMotion = NULL;
  173. motion_list_t& motionList = iter->second;
  174. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  175. {
  176. const ParameterizedMotion& paramMotion = *iter2;
  177. paramMotion.mMotion->onUpdate(time, joint_mask);
  178. F32 distToParam = paramMotion.mParam - *paramValue;
  179. if ( distToParam <= 0.f)
  180. {
  181. // keep track of the motion closest to the parameter value
  182. firstMotion = &paramMotion;
  183. }
  184. else
  185. {
  186. // we've passed the parameter value
  187. // so store the first motion we find as the second one we want to blend...
  188. if (firstMotion && !secondMotion )
  189. {
  190. secondMotion = &paramMotion;
  191. }
  192. //...or, if we've seen no other motion so far, make sure we blend to this only
  193. else if (!firstMotion)
  194. {
  195. firstMotion = &paramMotion;
  196. secondMotion = &paramMotion;
  197. }
  198. }
  199. }
  200. LLPose *firstPose;
  201. LLPose *secondPose;
  202. if (firstMotion)
  203. firstPose = firstMotion->mMotion->getPose();
  204. else
  205. firstPose = NULL;
  206. if (secondMotion)
  207. secondPose = secondMotion->mMotion->getPose();
  208. else
  209. secondPose = NULL;
  210. // now modify weight of the subanim (only if we are blending between two motions)
  211. if (firstMotion && secondMotion)
  212. {
  213. if (firstMotion == secondMotion)
  214. {
  215. firstPose->setWeight(weightFactor);
  216. }
  217. else if (firstMotion->mParam == secondMotion->mParam)
  218. {
  219. firstPose->setWeight(0.5f * weightFactor);
  220. secondPose->setWeight(0.5f * weightFactor);
  221. }
  222. else
  223. {
  224. F32 first_weight = 1.f - 
  225. ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) / 
  226. (secondMotion->mParam - firstMotion->mParam));
  227. first_weight = llclamp(first_weight, 0.f, 1.f);
  228. F32 second_weight = 1.f - first_weight;
  229. firstPose->setWeight(first_weight * weightFactor);
  230. secondPose->setWeight(second_weight * weightFactor);
  231. // llinfos << "Parameter " << *paramName << ": " << *paramValue << llendl;
  232. // llinfos << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << llendl;
  233. }
  234. }
  235. else if (firstMotion && !secondMotion)
  236. {
  237. firstPose->setWeight(weightFactor);
  238. }
  239. }
  240. // blend poses
  241. mPoseBlender.blendAndApply();
  242. llinfos << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << llendl;
  243. return TRUE;
  244. }
  245. //-----------------------------------------------------------------------------
  246. // LLKeyframeMotionParam::onDeactivate()
  247. //-----------------------------------------------------------------------------
  248. void LLKeyframeMotionParam::onDeactivate()
  249. {
  250. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  251.  iter != mParameterizedMotions.end(); ++iter)
  252. {
  253. motion_list_t& motionList = iter->second;
  254. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  255. {
  256. const ParameterizedMotion& paramMotion = *iter2;
  257. paramMotion.mMotion->onDeactivate();
  258. }
  259. }
  260. }
  261. //-----------------------------------------------------------------------------
  262. // LLKeyframeMotionParam::addKeyframeMotion()
  263. //-----------------------------------------------------------------------------
  264. BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
  265. {
  266. LLMotion *newMotion = mCharacter->createMotion( id );
  267. if (!newMotion)
  268. {
  269. return FALSE;
  270. }
  271. newMotion->setName(name);
  272. // now add motion to this list
  273. mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
  274. return TRUE;
  275. }
  276. //-----------------------------------------------------------------------------
  277. // LLKeyframeMotionParam::setDefaultKeyframeMotion()
  278. //-----------------------------------------------------------------------------
  279. void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
  280. {
  281. for (motion_map_t::iterator iter = mParameterizedMotions.begin();
  282.  iter != mParameterizedMotions.end(); ++iter)
  283. {
  284. motion_list_t& motionList = iter->second;
  285. for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
  286. {
  287. const ParameterizedMotion& paramMotion = *iter2;
  288. if (paramMotion.mMotion->getName() == name)
  289. {
  290. mDefaultKeyframeMotion = paramMotion.mMotion;
  291. }
  292. }
  293. }
  294. }
  295. //-----------------------------------------------------------------------------
  296. // loadMotions()
  297. //-----------------------------------------------------------------------------
  298. BOOL LLKeyframeMotionParam::loadMotions()
  299. {
  300. //-------------------------------------------------------------------------
  301. // Load named file by concatenating the character prefix with the motion name.
  302. // Load data into a buffer to be parsed.
  303. //-------------------------------------------------------------------------
  304. //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
  305. // + "_" + getName() + ".llp";
  306. //RN: deprecated unused reference to "motion" directory
  307. std::string path;
  308. //-------------------------------------------------------------------------
  309. // open the file
  310. //-------------------------------------------------------------------------
  311. S32 fileSize = 0;
  312. LLAPRFile infile ;
  313. infile.open(path, LL_APR_R, NULL, &fileSize);
  314. apr_file_t* fp = infile.getFileHandle() ;
  315. if (!fp || fileSize == 0)
  316. {
  317. llinfos << "ERROR: can't open: " << path << llendl;
  318. return FALSE;
  319. }
  320. // allocate a text buffer
  321. std::vector<char> text(fileSize+1);
  322. //-------------------------------------------------------------------------
  323. // load data from file into buffer
  324. //-------------------------------------------------------------------------
  325. bool error = false;
  326. char *p = &text[0];
  327. while ( 1 )
  328. {
  329. if (apr_file_eof(fp) == APR_EOF)
  330. {
  331. break;
  332. }
  333. if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
  334. {
  335. error = true;
  336. break;
  337. }
  338. while ( *(++p) )
  339. ;
  340. }
  341. //-------------------------------------------------------------------------
  342. // close the file
  343. //-------------------------------------------------------------------------
  344. infile.close();
  345. //-------------------------------------------------------------------------
  346. // check for error
  347. //-------------------------------------------------------------------------
  348. llassert( p <= (&text[0] + fileSize) );
  349. if ( error )
  350. {
  351. llinfos << "ERROR: error while reading from " << path << llendl;
  352. return FALSE;
  353. }
  354. llinfos << "Loading parametric keyframe data for: " << getName() << llendl;
  355. //-------------------------------------------------------------------------
  356. // parse the text and build keyframe data structures
  357. //-------------------------------------------------------------------------
  358. p = &text[0];
  359. S32 num;
  360. char strA[80]; /* Flawfinder: ignore */
  361. char strB[80]; /* Flawfinder: ignore */
  362. F32 floatA = 0.0f;
  363. //-------------------------------------------------------------------------
  364. // get priority
  365. //-------------------------------------------------------------------------
  366. BOOL isFirstMotion = TRUE;
  367. num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
  368. while(1)
  369. {
  370. if (num == 0 || num == EOF) break;
  371. if ((num != 3))
  372. {
  373. llinfos << "WARNING: can't read parametric motion" << llendl;
  374. return FALSE;
  375. }
  376. addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA);
  377. if (isFirstMotion)
  378. {
  379. isFirstMotion = FALSE;
  380. setDefaultKeyframeMotion(strA);
  381. }
  382. p = strstr(p, "n");
  383. if (!p)
  384. {
  385. break;
  386. }
  387. p++;
  388. num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
  389. }
  390. return TRUE;
  391. }
  392. // End