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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llbvhloader.cpp
  3.  * @brief Translates a BVH files to LindenLabAnimation format.
  4.  *
  5.  * $LicenseInfo:firstyear=2004&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2004-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. #include "linden_common.h"
  33. #include "llbvhloader.h"
  34. #include <boost/tokenizer.hpp>
  35. #include "lldatapacker.h"
  36. #include "lldir.h"
  37. #include "llkeyframemotion.h"
  38. #include "llquantize.h"
  39. #include "llstl.h"
  40. #include "llapr.h"
  41. using namespace std;
  42. #define INCHES_TO_METERS 0.02540005f
  43. const F32 POSITION_KEYFRAME_THRESHOLD = 0.03f;
  44. const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f;
  45. const F32 POSITION_MOTION_THRESHOLD = 0.001f;
  46. const F32 ROTATION_MOTION_THRESHOLD = 0.001f;
  47. char gInFile[1024]; /* Flawfinder: ignore */
  48. char gOutFile[1024]; /* Flawfinder: ignore */
  49. /*
  50. //------------------------------------------------------------------------
  51. // Status Codes
  52. //------------------------------------------------------------------------
  53. const char *LLBVHLoader::ST_OK = "Ok";
  54. const char *LLBVHLoader::ST_EOF = "Premature end of file.";
  55. const char *LLBVHLoader::ST_NO_CONSTRAINT = "Can't read constraint definition.";
  56. const char *LLBVHLoader::ST_NO_FILE = "Can't open BVH file.";
  57. const char *LLBVHLoader::ST_NO_HIER = "Invalid HIERARCHY header.";
  58. const char *LLBVHLoader::ST_NO_JOINT = "Can't find ROOT or JOINT.";
  59. const char *LLBVHLoader::ST_NO_NAME = "Can't get JOINT name.";
  60. const char *LLBVHLoader::ST_NO_OFFSET = "Can't find OFFSET.";
  61. const char *LLBVHLoader::ST_NO_CHANNELS = "Can't find CHANNELS.";
  62. const char *LLBVHLoader::ST_NO_ROTATION = "Can't get rotation order.";
  63. const char *LLBVHLoader::ST_NO_AXIS = "Can't get rotation axis.";
  64. const char *LLBVHLoader::ST_NO_MOTION = "Can't find MOTION.";
  65. const char *LLBVHLoader::ST_NO_FRAMES = "Can't get number of frames.";
  66. const char *LLBVHLoader::ST_NO_FRAME_TIME = "Can't get frame time.";
  67. const char *LLBVHLoader::ST_NO_POS = "Can't get position values.";
  68. const char *LLBVHLoader::ST_NO_ROT = "Can't get rotation values.";
  69. const char *LLBVHLoader::ST_NO_XLT_FILE = "Can't open translation file.";
  70. const char *LLBVHLoader::ST_NO_XLT_HEADER = "Can't read translation header.";
  71. const char *LLBVHLoader::ST_NO_XLT_NAME = "Can't read translation names.";
  72. const char *LLBVHLoader::ST_NO_XLT_IGNORE = "Can't read translation ignore value.";
  73. const char *LLBVHLoader::ST_NO_XLT_RELATIVE = "Can't read translation relative value.";
  74. const char *LLBVHLoader::ST_NO_XLT_OUTNAME = "Can't read translation outname value.";
  75. const char *LLBVHLoader::ST_NO_XLT_MATRIX = "Can't read translation matrix.";
  76. const char *LLBVHLoader::ST_NO_XLT_MERGECHILD = "Can't get mergechild name.";
  77. const char *LLBVHLoader::ST_NO_XLT_MERGEPARENT = "Can't get mergeparent name.";
  78. const char *LLBVHLoader::ST_NO_XLT_PRIORITY = "Can't get priority value.";
  79. const char *LLBVHLoader::ST_NO_XLT_LOOP = "Can't get loop value.";
  80. const char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values.";
  81. const char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values.";
  82. const char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value.";
  83. const char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name.";
  84. const char *LLBVHLoader::ST_BAD_ROOT        = "Illegal ROOT joint.";
  85. */
  86. //------------------------------------------------------------------------
  87. // find_next_whitespace()
  88. //------------------------------------------------------------------------
  89. const char *find_next_whitespace(const char *p)
  90. {
  91. while(*p && isspace(*p)) p++;
  92. while(*p && !isspace(*p)) p++;
  93. return p;
  94. }
  95. //------------------------------------------------------------------------
  96. // bvhStringToOrder()
  97. //
  98. // XYZ order in BVH files must be passed to mayaQ() as ZYX.
  99. // This function reverses the input string before passing it on
  100. // to StringToOrder().
  101. //------------------------------------------------------------------------
  102. LLQuaternion::Order bvhStringToOrder( char *str )
  103. {
  104. char order[4]; /* Flawfinder: ignore */
  105. order[0] = str[2];
  106. order[1] = str[1];
  107. order[2] = str[0];
  108. order[3] = 0;
  109. LLQuaternion::Order retVal = StringToOrder( order );
  110. return retVal;
  111. }
  112. //-----------------------------------------------------------------------------
  113. // LLBVHLoader()
  114. //-----------------------------------------------------------------------------
  115. /*
  116.  LLBVHLoader::LLBVHLoader(const char* buffer)
  117. {
  118. reset();
  119. mStatus = loadTranslationTable("anim.ini");
  120. if (mStatus == LLBVHLoader::ST_NO_XLT_FILE)
  121. {
  122. llwarns << "NOTE: No translation table found." << llendl;
  123. return;
  124. }
  125. else
  126. {
  127. if (mStatus != LLBVHLoader::ST_OK)
  128. {
  129. llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl;
  130. return;
  131. }
  132. }
  133. char error_text[128]; // Flawfinder: ignore 
  134. S32 error_line;
  135. mStatus = loadBVHFile(buffer, error_text, error_line);
  136. if (mStatus != LLBVHLoader::ST_OK)
  137. {
  138. llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl;
  139. return;
  140. }
  141. applyTranslations();
  142. optimize();
  143. mInitialized = TRUE;
  144. }
  145. */
  146. LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine)
  147. {
  148. reset();
  149. errorLine = 0;
  150. mStatus = loadTranslationTable("anim.ini");
  151. loadStatus = mStatus;
  152. llinfos<<"Load Status 00 : "<< loadStatus << llendl;
  153. if (mStatus == E_ST_NO_XLT_FILE)
  154. {
  155. //llwarns << "NOTE: No translation table found." << llendl;
  156. loadStatus = mStatus;
  157. return;
  158. }
  159. else
  160. {
  161. if (mStatus != E_ST_OK)
  162. {
  163. //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl;
  164. errorLine = getLineNumber();
  165. loadStatus = mStatus;
  166. return;
  167. }
  168. }
  169. char error_text[128]; /* Flawfinder: ignore */
  170. S32 error_line;
  171. mStatus = loadBVHFile(buffer, error_text, error_line);
  172. if (mStatus != E_ST_OK)
  173. {
  174. //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl;
  175. loadStatus = mStatus;
  176. errorLine = getLineNumber();
  177. return;
  178. }
  179. applyTranslations();
  180. optimize();
  181. mInitialized = TRUE;
  182. }
  183. LLBVHLoader::~LLBVHLoader()
  184. {
  185. std::for_each(mJoints.begin(),mJoints.end(),DeletePointer());
  186. }
  187. //------------------------------------------------------------------------
  188. // LLBVHLoader::loadTranslationTable()
  189. //------------------------------------------------------------------------
  190. ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName)
  191. {
  192. mLineNumber = 0;
  193. mTranslations.clear();
  194. mConstraints.clear();
  195. //--------------------------------------------------------------------
  196. // open file
  197. //--------------------------------------------------------------------
  198. std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName);
  199. LLAPRFile infile ;
  200. infile.open(path, LL_APR_R);
  201. apr_file_t *fp = infile.getFileHandle();
  202. if (!fp)
  203. return E_ST_NO_XLT_FILE;
  204. llinfos << "NOTE: Loading translation table: " << fileName << llendl;
  205. //--------------------------------------------------------------------
  206. // register file to be closed on function exit
  207. //--------------------------------------------------------------------
  208. //--------------------------------------------------------------------
  209. // load header
  210. //--------------------------------------------------------------------
  211. if ( ! getLine(fp) )
  212. return E_ST_EOF;
  213. if ( strncmp(mLine, "Translations 1.0", 16) )
  214. return E_ST_NO_XLT_HEADER;
  215. //--------------------------------------------------------------------
  216. // load data one line at a time
  217. //--------------------------------------------------------------------
  218. BOOL loadingGlobals = FALSE;
  219. Translation *trans = NULL;
  220. while ( getLine(fp) )
  221. {
  222. //----------------------------------------------------------------
  223. // check the 1st token on the line to determine if it's empty or a comment
  224. //----------------------------------------------------------------
  225. char token[128]; /* Flawfinder: ignore */
  226. if ( sscanf(mLine, " %127s", token) != 1 ) /* Flawfinder: ignore */
  227. continue;
  228. if (token[0] == '#')
  229. continue;
  230. //----------------------------------------------------------------
  231. // check if a [jointName] or [GLOBALS] was specified.
  232. //----------------------------------------------------------------
  233. if (token[0] == '[')
  234. {
  235. char name[128]; /* Flawfinder: ignore */
  236. if ( sscanf(mLine, " [%127[^]]", name) != 1 )
  237. return E_ST_NO_XLT_NAME;
  238. if (strcmp(name, "GLOBALS")==0)
  239. {
  240. loadingGlobals = TRUE;
  241. continue;
  242. }
  243. else
  244. {
  245. loadingGlobals = FALSE;
  246. Translation &newTrans = mTranslations[ name ];
  247. trans = &newTrans;
  248. continue;
  249. }
  250. }
  251. //----------------------------------------------------------------
  252. // check for optional emote 
  253. //----------------------------------------------------------------
  254. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "emote")==0)
  255. {
  256. char emote_str[1024]; /* Flawfinder: ignore */
  257. if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */
  258. return E_ST_NO_XLT_EMOTE;
  259. mEmoteName.assign( emote_str );
  260. // llinfos << "NOTE: Emote: " << mEmoteName.c_str() << llendl;
  261. continue;
  262. }
  263. //----------------------------------------------------------------
  264. // check for global priority setting
  265. //----------------------------------------------------------------
  266. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "priority")==0)
  267. {
  268. S32 priority;
  269. if ( sscanf(mLine, " %*s = %d", &priority) != 1 )
  270. return E_ST_NO_XLT_PRIORITY;
  271. mPriority = priority;
  272. // llinfos << "NOTE: Priority: " << mPriority << llendl;
  273. continue;
  274. }
  275. //----------------------------------------------------------------
  276. // check for global loop setting
  277. //----------------------------------------------------------------
  278. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "loop")==0)
  279. {
  280. char trueFalse[128]; /* Flawfinder: ignore */
  281. trueFalse[0] = '';
  282. F32 loop_in = 0.f;
  283. F32 loop_out = 1.f;
  284. if ( sscanf(mLine, " %*s = %f %f", &loop_in, &loop_out) == 2 )
  285. {
  286. mLoop = TRUE;
  287. }
  288. else if ( sscanf(mLine, " %*s = %127s", trueFalse) == 1 ) /* Flawfinder: ignore */
  289. {
  290. mLoop = (LLStringUtil::compareInsensitive(trueFalse, "true")==0);
  291. }
  292. else
  293. {
  294. return E_ST_NO_XLT_LOOP;
  295. }
  296. mLoopInPoint = loop_in * mDuration;
  297. mLoopOutPoint = loop_out * mDuration;
  298. continue;
  299. }
  300. //----------------------------------------------------------------
  301. // check for global easeIn setting
  302. //----------------------------------------------------------------
  303. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easein")==0)
  304. {
  305. F32 duration;
  306. char type[128]; /* Flawfinder: ignore */
  307. if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */
  308. return E_ST_NO_XLT_EASEIN;
  309. mEaseIn = duration;
  310. continue;
  311. }
  312. //----------------------------------------------------------------
  313. // check for global easeOut setting
  314. //----------------------------------------------------------------
  315. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easeout")==0)
  316. {
  317. F32 duration;
  318. char type[128]; /* Flawfinder: ignore */
  319. if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */
  320. return E_ST_NO_XLT_EASEOUT;
  321. mEaseOut = duration;
  322. continue;
  323. }
  324. //----------------------------------------------------------------
  325. // check for global handMorph setting
  326. //----------------------------------------------------------------
  327. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "hand")==0)
  328. {
  329. S32 handMorph;
  330. if (sscanf(mLine, " %*s = %d", &handMorph) != 1)
  331. return E_ST_NO_XLT_HAND;
  332. mHand = handMorph;
  333. continue;
  334. }
  335. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "constraint")==0)
  336. {
  337. Constraint constraint;
  338. // try reading optional target direction
  339. if(sscanf( /* Flawfinder: ignore */
  340. mLine,
  341. " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", 
  342. &constraint.mChainLength,
  343. &constraint.mEaseInStart,
  344. &constraint.mEaseInStop,
  345. &constraint.mEaseOutStart,
  346. &constraint.mEaseOutStop,
  347. constraint.mSourceJointName,
  348. &constraint.mSourceOffset.mV[VX],
  349. &constraint.mSourceOffset.mV[VY],
  350. &constraint.mSourceOffset.mV[VZ],
  351. constraint.mTargetJointName,
  352. &constraint.mTargetOffset.mV[VX],
  353. &constraint.mTargetOffset.mV[VY],
  354. &constraint.mTargetOffset.mV[VZ],
  355. &constraint.mTargetDir.mV[VX],
  356. &constraint.mTargetDir.mV[VY],
  357. &constraint.mTargetDir.mV[VZ]) != 16)
  358. {
  359. if(sscanf( /* Flawfinder: ignore */
  360. mLine,
  361. " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", 
  362. &constraint.mChainLength,
  363. &constraint.mEaseInStart,
  364. &constraint.mEaseInStop,
  365. &constraint.mEaseOutStart,
  366. &constraint.mEaseOutStop,
  367. constraint.mSourceJointName,
  368. &constraint.mSourceOffset.mV[VX],
  369. &constraint.mSourceOffset.mV[VY],
  370. &constraint.mSourceOffset.mV[VZ],
  371. constraint.mTargetJointName,
  372. &constraint.mTargetOffset.mV[VX],
  373. &constraint.mTargetOffset.mV[VY],
  374. &constraint.mTargetOffset.mV[VZ]) != 13)
  375. {
  376. return E_ST_NO_CONSTRAINT;
  377. }
  378. }
  379. else
  380. {
  381. // normalize direction
  382. if (!constraint.mTargetDir.isExactlyZero())
  383. {
  384. constraint.mTargetDir.normVec();
  385. }
  386. }
  387. constraint.mConstraintType = CONSTRAINT_TYPE_POINT;
  388. mConstraints.push_back(constraint);
  389. continue;
  390. }
  391. if (loadingGlobals && LLStringUtil::compareInsensitive(token, "planar_constraint")==0)
  392. {
  393. Constraint constraint;
  394. // try reading optional target direction
  395. if(sscanf( /* Flawfinder: ignore */
  396. mLine,
  397. " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", 
  398. &constraint.mChainLength,
  399. &constraint.mEaseInStart,
  400. &constraint.mEaseInStop,
  401. &constraint.mEaseOutStart,
  402. &constraint.mEaseOutStop,
  403. constraint.mSourceJointName,
  404. &constraint.mSourceOffset.mV[VX],
  405. &constraint.mSourceOffset.mV[VY],
  406. &constraint.mSourceOffset.mV[VZ],
  407. constraint.mTargetJointName,
  408. &constraint.mTargetOffset.mV[VX],
  409. &constraint.mTargetOffset.mV[VY],
  410. &constraint.mTargetOffset.mV[VZ],
  411. &constraint.mTargetDir.mV[VX],
  412. &constraint.mTargetDir.mV[VY],
  413. &constraint.mTargetDir.mV[VZ]) != 16)
  414. {
  415. if(sscanf( /* Flawfinder: ignore */
  416. mLine,
  417. " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", 
  418. &constraint.mChainLength,
  419. &constraint.mEaseInStart,
  420. &constraint.mEaseInStop,
  421. &constraint.mEaseOutStart,
  422. &constraint.mEaseOutStop,
  423. constraint.mSourceJointName,
  424. &constraint.mSourceOffset.mV[VX],
  425. &constraint.mSourceOffset.mV[VY],
  426. &constraint.mSourceOffset.mV[VZ],
  427. constraint.mTargetJointName,
  428. &constraint.mTargetOffset.mV[VX],
  429. &constraint.mTargetOffset.mV[VY],
  430. &constraint.mTargetOffset.mV[VZ]) != 13)
  431. {
  432. return E_ST_NO_CONSTRAINT;
  433. }
  434. }
  435. else
  436. {
  437. // normalize direction
  438. if (!constraint.mTargetDir.isExactlyZero())
  439. {
  440. constraint.mTargetDir.normVec();
  441. }
  442. }
  443. constraint.mConstraintType = CONSTRAINT_TYPE_PLANE;
  444. mConstraints.push_back(constraint);
  445. continue;
  446. }
  447. //----------------------------------------------------------------
  448. // at this point there must be a valid trans pointer
  449. //----------------------------------------------------------------
  450. if ( ! trans )
  451. return E_ST_NO_XLT_NAME;
  452. //----------------------------------------------------------------
  453. // check for ignore flag
  454. //----------------------------------------------------------------
  455. if ( LLStringUtil::compareInsensitive(token, "ignore")==0 )
  456. {
  457. char trueFalse[128]; /* Flawfinder: ignore */
  458. if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */
  459. return E_ST_NO_XLT_IGNORE;
  460. trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0);
  461. continue;
  462. }
  463. //----------------------------------------------------------------
  464. // check for relativepos flag
  465. //----------------------------------------------------------------
  466. if ( LLStringUtil::compareInsensitive(token, "relativepos")==0 )
  467. {
  468. F32 x, y, z;
  469. char relpos[128]; /* Flawfinder: ignore */
  470. if ( sscanf(mLine, " %*s = %f %f %f", &x, &y, &z) == 3 )
  471. {
  472. trans->mRelativePosition.setVec( x, y, z );
  473. }
  474. else if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */
  475. {
  476. if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 )
  477. {
  478. trans->mRelativePositionKey = TRUE;
  479. }
  480. else
  481. {
  482. return E_ST_NO_XLT_RELATIVE;
  483. }
  484. }
  485. else
  486. {
  487. return E_ST_NO_XLT_RELATIVE;
  488. }
  489. continue;
  490. }
  491. //----------------------------------------------------------------
  492. // check for relativerot flag
  493. //----------------------------------------------------------------
  494. if ( LLStringUtil::compareInsensitive(token, "relativerot")==0 )
  495. {
  496. //F32 x, y, z;
  497. char relpos[128]; /* Flawfinder: ignore */
  498. if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */
  499. {
  500. if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 )
  501. {
  502. trans->mRelativeRotationKey = TRUE;
  503. }
  504. else
  505. {
  506. return E_ST_NO_XLT_RELATIVE;
  507. }
  508. }
  509. else
  510. {
  511. return E_ST_NO_XLT_RELATIVE;
  512. }
  513. continue;
  514. }
  515. //----------------------------------------------------------------
  516. // check for outname value
  517. //----------------------------------------------------------------
  518. if ( LLStringUtil::compareInsensitive(token, "outname")==0 )
  519. {
  520. char outName[128]; /* Flawfinder: ignore */
  521. if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */
  522. return E_ST_NO_XLT_OUTNAME;
  523. trans->mOutName = outName;
  524. continue;
  525. }
  526. //----------------------------------------------------------------
  527. // check for frame matrix value
  528. //----------------------------------------------------------------
  529. if ( LLStringUtil::compareInsensitive(token, "frame")==0 )
  530. {
  531. LLMatrix3 fm;
  532. if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f",
  533. &fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2],
  534. &fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2],
  535. &fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 )
  536. return E_ST_NO_XLT_MATRIX;
  537. trans->mFrameMatrix = fm;
  538. continue;
  539. }
  540. //----------------------------------------------------------------
  541. // check for offset matrix value
  542. //----------------------------------------------------------------
  543. if ( LLStringUtil::compareInsensitive(token, "offset")==0 )
  544. {
  545. LLMatrix3 om;
  546. if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f",
  547. &om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2],
  548. &om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2],
  549. &om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 )
  550. return E_ST_NO_XLT_MATRIX;
  551. trans->mOffsetMatrix = om;
  552. continue;
  553. }
  554. //----------------------------------------------------------------
  555. // check for mergeparent value
  556. //----------------------------------------------------------------
  557. if ( LLStringUtil::compareInsensitive(token, "mergeparent")==0 )
  558. {
  559. char mergeParentName[128]; /* Flawfinder: ignore */
  560. if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */
  561. return E_ST_NO_XLT_MERGEPARENT;
  562. trans->mMergeParentName = mergeParentName;
  563. continue;
  564. }
  565. //----------------------------------------------------------------
  566. // check for mergechild value
  567. //----------------------------------------------------------------
  568. if ( LLStringUtil::compareInsensitive(token, "mergechild")==0 )
  569. {
  570. char mergeChildName[128]; /* Flawfinder: ignore */
  571. if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */
  572. return E_ST_NO_XLT_MERGECHILD;
  573. trans->mMergeChildName = mergeChildName;
  574. continue;
  575. }
  576. //----------------------------------------------------------------
  577. // check for per-joint priority
  578. //----------------------------------------------------------------
  579. if ( LLStringUtil::compareInsensitive(token, "priority")==0 )
  580. {
  581. S32 priority;
  582. if ( sscanf(mLine, " %*s = %d", &priority) != 1 )
  583. return E_ST_NO_XLT_PRIORITY;
  584. trans->mPriorityModifier = priority;
  585. continue;
  586. }
  587. }
  588. infile.close() ;
  589. return E_ST_OK;
  590. }
  591. //------------------------------------------------------------------------
  592. // LLBVHLoader::loadBVHFile()
  593. //------------------------------------------------------------------------
  594. ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line)
  595. {
  596. std::string line;
  597. err_line = 0;
  598. error_text[127] = '';
  599. std::string str(buffer);
  600. typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
  601. boost::char_separator<char> sep("rn");
  602. tokenizer tokens(str, sep);
  603. tokenizer::iterator iter = tokens.begin();
  604. mLineNumber = 0;
  605. mJoints.clear();
  606. std::vector<S32> parent_joints;
  607. //--------------------------------------------------------------------
  608. // consume  hierarchy
  609. //--------------------------------------------------------------------
  610. if (iter == tokens.end())
  611. return E_ST_EOF;
  612. line = (*(iter++));
  613. err_line++;
  614. if ( !strstr(line.c_str(), "HIERARCHY") )
  615. {
  616. // llinfos << line << llendl;
  617. return E_ST_NO_HIER;
  618. }
  619. //--------------------------------------------------------------------
  620. // consume joints
  621. //--------------------------------------------------------------------
  622. while (TRUE)
  623. {
  624. //----------------------------------------------------------------
  625. // get next line
  626. //----------------------------------------------------------------
  627. if (iter == tokens.end())
  628. return E_ST_EOF;
  629. line = (*(iter++));
  630. err_line++;
  631. //----------------------------------------------------------------
  632. // consume }
  633. //----------------------------------------------------------------
  634. if ( strstr(line.c_str(), "}") )
  635. {
  636. if (parent_joints.size() > 0)
  637. {
  638. parent_joints.pop_back();
  639. }
  640. continue;
  641. }
  642. //----------------------------------------------------------------
  643. // if MOTION, break out
  644. //----------------------------------------------------------------
  645. if ( strstr(line.c_str(), "MOTION") )
  646. break;
  647. //----------------------------------------------------------------
  648. // it must be either ROOT or JOINT or EndSite
  649. //----------------------------------------------------------------
  650. if ( strstr(line.c_str(), "ROOT") )
  651. {
  652. }
  653. else if ( strstr(line.c_str(), "JOINT") )
  654. {
  655. }
  656. else if ( strstr(line.c_str(), "End Site") )
  657. {
  658. iter++; // {
  659. iter++; //     OFFSET
  660. S32 depth = 0;
  661. for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--)
  662. {
  663. Joint *joint = mJoints[parent_joints[j]];
  664. if (depth > joint->mChildTreeMaxDepth)
  665. {
  666. joint->mChildTreeMaxDepth = depth;
  667. }
  668. depth++;
  669. }
  670. continue;
  671. }
  672. else
  673. {
  674. strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */
  675. return E_ST_NO_JOINT;
  676. }
  677. //----------------------------------------------------------------
  678. // get the joint name
  679. //----------------------------------------------------------------
  680. char jointName[80]; /* Flawfinder: ignore */
  681. if ( sscanf(line.c_str(), "%*s %79s", jointName) != 1 ) /* Flawfinder: ignore */
  682. {
  683. strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */
  684. return E_ST_NO_NAME;
  685. }
  686. //---------------------------------------------------------------
  687. // we require the root joint be "hip" - DEV-26188
  688. //---------------------------------------------------------------
  689. const char* FORCED_ROOT_NAME = "hip";
  690. if ( (mJoints.size() == 0 ) && ( !strstr(jointName, FORCED_ROOT_NAME) ) )
  691. {
  692. strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */
  693. return E_ST_BAD_ROOT;
  694. }
  695. //----------------------------------------------------------------
  696. // add a set of keyframes for this joint
  697. //----------------------------------------------------------------
  698. mJoints.push_back( new Joint( jointName ) );
  699. Joint *joint = mJoints.back();
  700. S32 depth = 1;
  701. for (S32 j = (S32)parent_joints.size() - 1; j >= 0; j--)
  702. {
  703. Joint *pjoint = mJoints[parent_joints[j]];
  704. if (depth > pjoint->mChildTreeMaxDepth)
  705. {
  706. pjoint->mChildTreeMaxDepth = depth;
  707. }
  708. depth++;
  709. }
  710. //----------------------------------------------------------------
  711. // get next line
  712. //----------------------------------------------------------------
  713. if (iter == tokens.end())
  714. {
  715. return E_ST_EOF;
  716. }
  717. line = (*(iter++));
  718. err_line++;
  719. //----------------------------------------------------------------
  720. // it must be {
  721. //----------------------------------------------------------------
  722. if ( !strstr(line.c_str(), "{") )
  723. {
  724. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  725. return E_ST_NO_OFFSET;
  726. }
  727. else
  728. {
  729. parent_joints.push_back((S32)mJoints.size() - 1);
  730. }
  731. //----------------------------------------------------------------
  732. // get next line
  733. //----------------------------------------------------------------
  734. if (iter == tokens.end())
  735. {
  736. return E_ST_EOF;
  737. }
  738. line = (*(iter++));
  739. err_line++;
  740. //----------------------------------------------------------------
  741. // it must be OFFSET
  742. //----------------------------------------------------------------
  743. if ( !strstr(line.c_str(), "OFFSET") )
  744. {
  745. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  746. return E_ST_NO_OFFSET;
  747. }
  748. //----------------------------------------------------------------
  749. // get next line
  750. //----------------------------------------------------------------
  751. if (iter == tokens.end())
  752. {
  753. return E_ST_EOF;
  754. }
  755. line = (*(iter++));
  756. err_line++;
  757. //----------------------------------------------------------------
  758. // it must be CHANNELS
  759. //----------------------------------------------------------------
  760. if ( !strstr(line.c_str(), "CHANNELS") )
  761. {
  762. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  763. return E_ST_NO_CHANNELS;
  764. }
  765. //----------------------------------------------------------------
  766. // get rotation order
  767. //----------------------------------------------------------------
  768. const char *p = line.c_str();
  769. for (S32 i=0; i<3; i++)
  770. {
  771. p = strstr(p, "rotation");
  772. if (!p)
  773. {
  774. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  775. return E_ST_NO_ROTATION;
  776. }
  777. const char axis = *(p - 1);
  778. if ((axis != 'X') && (axis != 'Y') && (axis != 'Z'))
  779. {
  780. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  781. return E_ST_NO_AXIS;
  782. }
  783. joint->mOrder[i] = axis;
  784. p++;
  785. }
  786. }
  787. //--------------------------------------------------------------------
  788. // consume motion
  789. //--------------------------------------------------------------------
  790. if ( !strstr(line.c_str(), "MOTION") )
  791. {
  792. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  793. return E_ST_NO_MOTION;
  794. }
  795. //--------------------------------------------------------------------
  796. // get number of frames
  797. //--------------------------------------------------------------------
  798. if (iter == tokens.end())
  799. {
  800. return E_ST_EOF;
  801. }
  802. line = (*(iter++));
  803. err_line++;
  804. if ( !strstr(line.c_str(), "Frames:") )
  805. {
  806. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  807. return E_ST_NO_FRAMES;
  808. }
  809. if ( sscanf(line.c_str(), "Frames: %d", &mNumFrames) != 1 )
  810. {
  811. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  812. return E_ST_NO_FRAMES;
  813. }
  814. //--------------------------------------------------------------------
  815. // get frame time
  816. //--------------------------------------------------------------------
  817. if (iter == tokens.end())
  818. {
  819. return E_ST_EOF;
  820. }
  821. line = (*(iter++));
  822. err_line++;
  823. if ( !strstr(line.c_str(), "Frame Time:") )
  824. {
  825. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  826. return E_ST_NO_FRAME_TIME;
  827. }
  828. if ( sscanf(line.c_str(), "Frame Time: %f", &mFrameTime) != 1 )
  829. {
  830. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  831. return E_ST_NO_FRAME_TIME;
  832. }
  833. mDuration = (F32)mNumFrames * mFrameTime;
  834. if (!mLoop)
  835. {
  836. mLoopOutPoint = mDuration;
  837. }
  838. //--------------------------------------------------------------------
  839. // load frames
  840. //--------------------------------------------------------------------
  841. for (S32 i=0; i<mNumFrames; i++)
  842. {
  843. // get next line
  844. if (iter == tokens.end())
  845. {
  846. return E_ST_EOF;
  847. }
  848. line = (*(iter++));
  849. err_line++;
  850. // read and store values
  851. const char *p = line.c_str();
  852. for (U32 j=0; j<mJoints.size(); j++)
  853. {
  854. Joint *joint = mJoints[j];
  855. joint->mKeys.push_back( Key() );
  856. Key &key = joint->mKeys.back();
  857. // get 3 pos values for root joint only
  858. if (j==0)
  859. {
  860. if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 )
  861. {
  862. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  863. return E_ST_NO_POS;
  864. }
  865. }
  866. // skip to next 3 values in the line
  867. p = find_next_whitespace(p);
  868. if (!p) 
  869. {
  870. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  871. return E_ST_NO_ROT;
  872. }
  873. p = find_next_whitespace(++p);
  874. if (!p) 
  875. {
  876. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  877. return E_ST_NO_ROT;
  878. }
  879. p = find_next_whitespace(++p);
  880. if (!p)
  881. {
  882. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  883. return E_ST_NO_ROT;
  884. }
  885. // get 3 rot values for joint
  886. F32 rot[3];
  887. if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 )
  888. {
  889. strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/
  890. return E_ST_NO_ROT;
  891. }
  892. p++;
  893. key.mRot[ joint->mOrder[0]-'X' ] = rot[0];
  894. key.mRot[ joint->mOrder[1]-'X' ] = rot[1];
  895. key.mRot[ joint->mOrder[2]-'X' ] = rot[2];
  896. }
  897. }
  898. return E_ST_OK;
  899. }
  900. //------------------------------------------------------------------------
  901. // LLBVHLoader::applyTranslation()
  902. //------------------------------------------------------------------------
  903. void LLBVHLoader::applyTranslations()
  904. {
  905. JointVector::iterator ji;
  906. for (ji = mJoints.begin(); ji != mJoints.end(); ++ji )
  907. {
  908. Joint *joint = *ji;
  909. //----------------------------------------------------------------
  910. // Look for a translation for this joint.
  911. // If none, skip to next joint
  912. //----------------------------------------------------------------
  913. TranslationMap::iterator ti = mTranslations.find( joint->mName );
  914. if ( ti == mTranslations.end() )
  915. {
  916. continue;
  917. }
  918. Translation &trans = ti->second;
  919. //----------------------------------------------------------------
  920. // Set the ignore flag if necessary
  921. //----------------------------------------------------------------
  922. if ( trans.mIgnore )
  923. {
  924. //llinfos << "NOTE: Ignoring " << joint->mName.c_str() << llendl;
  925. joint->mIgnore = TRUE;
  926. continue;
  927. }
  928. //----------------------------------------------------------------
  929. // Set the output name
  930. //----------------------------------------------------------------
  931. if ( ! trans.mOutName.empty() )
  932. {
  933. //llinfos << "NOTE: Changing " << joint->mName.c_str() << " to " << trans.mOutName.c_str() << llendl;
  934. joint->mOutName = trans.mOutName;
  935. }
  936. //----------------------------------------------------------------
  937. // Set the ignorepos flag if necessary
  938. //----------------------------------------------------------------
  939. if ( joint->mOutName == std::string("mPelvis") )
  940. {
  941. joint->mIgnorePositions = FALSE;
  942. }
  943. //----------------------------------------------------------------
  944. // Set the relativepos flags if necessary
  945. //----------------------------------------------------------------
  946. if ( trans.mRelativePositionKey )
  947. {
  948. // llinfos << "NOTE: Removing 1st position offset from all keys for " << joint->mOutName.c_str() << llendl;
  949. joint->mRelativePositionKey = TRUE;
  950. }
  951. if ( trans.mRelativeRotationKey )
  952. {
  953. // llinfos << "NOTE: Removing 1st rotation from all keys for " << joint->mOutName.c_str() << llendl;
  954. joint->mRelativeRotationKey = TRUE;
  955. }
  956. if ( trans.mRelativePosition.magVec() > 0.0f )
  957. {
  958. joint->mRelativePosition = trans.mRelativePosition;
  959. // llinfos << "NOTE: Removing " <<
  960. // joint->mRelativePosition.mV[0] << " " <<
  961. // joint->mRelativePosition.mV[1] << " " <<
  962. // joint->mRelativePosition.mV[2] <<
  963. // " from all position keys in " <<
  964. // joint->mOutName.c_str() << llendl;
  965. }
  966. //----------------------------------------------------------------
  967. // Set change of coordinate frame
  968. //----------------------------------------------------------------
  969. joint->mFrameMatrix = trans.mFrameMatrix;
  970. joint->mOffsetMatrix = trans.mOffsetMatrix;
  971. //----------------------------------------------------------------
  972. // Set mergeparent name
  973. //----------------------------------------------------------------
  974. if ( ! trans.mMergeParentName.empty() )
  975. {
  976. // llinfos << "NOTE: Merging "  << joint->mOutName.c_str() << 
  977. // " with parent " << 
  978. // trans.mMergeParentName.c_str() << llendl;
  979. joint->mMergeParentName = trans.mMergeParentName;
  980. }
  981. //----------------------------------------------------------------
  982. // Set mergechild name
  983. //----------------------------------------------------------------
  984. if ( ! trans.mMergeChildName.empty() )
  985. {
  986. // llinfos << "NOTE: Merging " << joint->mName.c_str() <<
  987. // " with child " << trans.mMergeChildName.c_str() << llendl;
  988. joint->mMergeChildName = trans.mMergeChildName;
  989. }
  990. //----------------------------------------------------------------
  991. // Set joint priority
  992. //----------------------------------------------------------------
  993. joint->mPriority = mPriority + trans.mPriorityModifier;
  994. }
  995. }
  996. //-----------------------------------------------------------------------------
  997. // LLBVHLoader::optimize()
  998. //-----------------------------------------------------------------------------
  999. void LLBVHLoader::optimize()
  1000. {
  1001. //RN: assumes motion blend, which is the default now
  1002. if (!mLoop && mEaseIn + mEaseOut > mDuration && mDuration != 0.f)
  1003. {
  1004. F32 factor = mDuration / (mEaseIn + mEaseOut);
  1005. mEaseIn *= factor;
  1006. mEaseOut *= factor;
  1007. }
  1008. JointVector::iterator ji;
  1009. for (ji = mJoints.begin(); ji != mJoints.end(); ++ji)
  1010. {
  1011. Joint *joint = *ji;
  1012. BOOL pos_changed = FALSE;
  1013. BOOL rot_changed = FALSE;
  1014. if ( ! joint->mIgnore )
  1015. {
  1016. joint->mNumPosKeys = 0;
  1017. joint->mNumRotKeys = 0;
  1018. LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
  1019. KeyVector::iterator first_key = joint->mKeys.begin();
  1020. // no keys?
  1021. if (first_key == joint->mKeys.end())
  1022. {
  1023. joint->mIgnore = TRUE;
  1024. continue;
  1025. }
  1026. LLVector3 first_frame_pos(first_key->mPos);
  1027. LLQuaternion first_frame_rot = mayaQ( first_key->mRot[0], first_key->mRot[1], first_key->mRot[2], order);
  1028. // skip first key
  1029. KeyVector::iterator ki = joint->mKeys.begin();
  1030. if (joint->mKeys.size() == 1)
  1031. {
  1032. // *FIX: use single frame to move pelvis
  1033. // if only one keyframe force output for this joint
  1034. rot_changed = TRUE;
  1035. }
  1036. else
  1037. {
  1038. // if more than one keyframe, use first frame as reference and skip to second
  1039. first_key->mIgnorePos = TRUE;
  1040. first_key->mIgnoreRot = TRUE;
  1041. ++ki;
  1042. }
  1043. KeyVector::iterator ki_prev = ki;
  1044. KeyVector::iterator ki_last_good_pos = ki;
  1045. KeyVector::iterator ki_last_good_rot = ki;
  1046. S32 numPosFramesConsidered = 2;
  1047. S32 numRotFramesConsidered = 2;
  1048. F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f);
  1049. double diff_max = 0;
  1050. KeyVector::iterator ki_max = ki;
  1051. for (; ki != joint->mKeys.end(); ++ki)
  1052. {
  1053. if (ki_prev == ki_last_good_pos)
  1054. {
  1055. joint->mNumPosKeys++;
  1056. if (dist_vec(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD)
  1057. {
  1058. pos_changed = TRUE;
  1059. }
  1060. }
  1061. else
  1062. {
  1063. //check position for noticeable effect
  1064. LLVector3 test_pos(ki_prev->mPos);
  1065. LLVector3 last_good_pos(ki_last_good_pos->mPos);
  1066. LLVector3 current_pos(ki->mPos);
  1067. LLVector3 interp_pos = lerp(current_pos, last_good_pos, 1.f / (F32)numPosFramesConsidered);
  1068. if (dist_vec(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD)
  1069. {
  1070. pos_changed = TRUE;
  1071. }
  1072. if (dist_vec(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD)
  1073. {
  1074. ki_prev->mIgnorePos = TRUE;
  1075. numPosFramesConsidered++;
  1076. }
  1077. else
  1078. {
  1079. numPosFramesConsidered = 2;
  1080. ki_last_good_pos = ki_prev;
  1081. joint->mNumPosKeys++;
  1082. }
  1083. }
  1084. if (ki_prev == ki_last_good_rot)
  1085. {
  1086. joint->mNumRotKeys++;
  1087. LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order);
  1088. F32 x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot);
  1089. F32 y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot);
  1090. F32 rot_test = x_delta + y_delta;
  1091. if (rot_test > ROTATION_MOTION_THRESHOLD)
  1092. {
  1093. rot_changed = TRUE;
  1094. }
  1095. }
  1096. else
  1097. {
  1098. //check rotation for noticeable effect
  1099. LLQuaternion test_rot = mayaQ( ki_prev->mRot[0], ki_prev->mRot[1], ki_prev->mRot[2], order);
  1100. LLQuaternion last_good_rot = mayaQ( ki_last_good_rot->mRot[0], ki_last_good_rot->mRot[1], ki_last_good_rot->mRot[2], order);
  1101. LLQuaternion current_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
  1102. LLQuaternion interp_rot = lerp(1.f / (F32)numRotFramesConsidered, current_rot, last_good_rot);
  1103. F32 x_delta;
  1104. F32 y_delta;
  1105. F32 rot_test;
  1106. // Test if the rotation has changed significantly since the very first frame.  If false
  1107. // for all frames, then we'll just throw out this joint's rotation entirely.
  1108. x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot);
  1109. y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot);
  1110. rot_test = x_delta + y_delta;
  1111. if (rot_test > ROTATION_MOTION_THRESHOLD)
  1112. {
  1113. rot_changed = TRUE;
  1114. }
  1115. x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot);
  1116. y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot);
  1117. rot_test = x_delta + y_delta;
  1118. // Draw a line between the last good keyframe and current.  Test the distance between the last frame (current-1, i.e. ki_prev)
  1119. // and the line.  If it's greater than some threshold, then it represents a significant frame and we want to include it.
  1120. if (rot_test >= rot_threshold ||
  1121. (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2))
  1122. {
  1123. // Add the current test keyframe (which is technically the previous key, i.e. ki_prev).
  1124. numRotFramesConsidered = 2;
  1125. ki_last_good_rot = ki_prev;
  1126. joint->mNumRotKeys++;
  1127. // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e.
  1128. // had the largest deviation from the earlier tests).  Note that a more robust approach would be test all intermediate
  1129. // keyframes against the line between the last good keyframe and current, but we're settling for this other method
  1130. // because it's significantly faster.
  1131. if (diff_max > 0)
  1132. {
  1133. if (ki_max->mIgnoreRot == TRUE)
  1134. {
  1135. ki_max->mIgnoreRot = FALSE;
  1136. joint->mNumRotKeys++;
  1137. }
  1138. diff_max = 0;
  1139. }
  1140. }
  1141. else
  1142. {
  1143. // This keyframe isn't significant enough, throw it away.
  1144. ki_prev->mIgnoreRot = TRUE;
  1145. numRotFramesConsidered++;
  1146. // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later.
  1147. if (rot_test > diff_max)
  1148. {
  1149. diff_max = rot_test;
  1150. ki_max = ki;
  1151. }
  1152. }
  1153. }
  1154. ki_prev = ki;
  1155. }
  1156. }
  1157. // don't output joints with no motion
  1158. if (!(pos_changed || rot_changed))
  1159. {
  1160. //llinfos << "Ignoring joint " << joint->mName << llendl;
  1161. joint->mIgnore = TRUE;
  1162. }
  1163. }
  1164. }
  1165. void LLBVHLoader::reset()
  1166. {
  1167. mLineNumber = 0;
  1168. mNumFrames = 0;
  1169. mFrameTime = 0.0f;
  1170. mDuration = 0.0f;
  1171. mPriority = 2;
  1172. mLoop = FALSE;
  1173. mLoopInPoint = 0.f;
  1174. mLoopOutPoint = 0.f;
  1175. mEaseIn = 0.3f;
  1176. mEaseOut = 0.3f;
  1177. mHand = 1;
  1178. mInitialized = FALSE;
  1179. mEmoteName = "";
  1180. }
  1181. //------------------------------------------------------------------------
  1182. // LLBVHLoader::getLine()
  1183. //------------------------------------------------------------------------
  1184. BOOL LLBVHLoader::getLine(apr_file_t* fp)
  1185. {
  1186. if (apr_file_eof(fp) == APR_EOF)
  1187. {
  1188. return FALSE;
  1189. }
  1190. if ( apr_file_gets(mLine, BVH_PARSER_LINE_SIZE, fp) == APR_SUCCESS)
  1191. {
  1192. mLineNumber++;
  1193. return TRUE;
  1194. }
  1195. return FALSE;
  1196. }
  1197. // returns required size of output buffer
  1198. U32 LLBVHLoader::getOutputSize()
  1199. {
  1200. LLDataPackerBinaryBuffer dp;
  1201. serialize(dp);
  1202. return dp.getCurrentSize();
  1203. }
  1204. // writes contents to datapacker
  1205. BOOL LLBVHLoader::serialize(LLDataPacker& dp)
  1206. {
  1207. JointVector::iterator ji;
  1208. KeyVector::iterator ki;
  1209. F32 time;
  1210. // count number of non-ignored joints
  1211. S32 numJoints = 0;
  1212. for (ji=mJoints.begin(); ji!=mJoints.end(); ++ji)
  1213. {
  1214. Joint *joint = *ji;
  1215. if ( ! joint->mIgnore )
  1216. numJoints++;
  1217. }
  1218. // print header
  1219. dp.packU16(KEYFRAME_MOTION_VERSION, "version");
  1220. dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version");
  1221. dp.packS32(mPriority, "base_priority");
  1222. dp.packF32(mDuration, "duration");
  1223. dp.packString(mEmoteName, "emote_name");
  1224. dp.packF32(mLoopInPoint, "loop_in_point");
  1225. dp.packF32(mLoopOutPoint, "loop_out_point");
  1226. dp.packS32(mLoop, "loop");
  1227. dp.packF32(mEaseIn, "ease_in_duration");
  1228. dp.packF32(mEaseOut, "ease_out_duration");
  1229. dp.packU32(mHand, "hand_pose");
  1230. dp.packU32(numJoints, "num_joints");
  1231. for ( ji = mJoints.begin();
  1232. ji != mJoints.end();
  1233. ++ji )
  1234. {
  1235. Joint *joint = *ji;
  1236. // if ignored, skip it
  1237. if ( joint->mIgnore )
  1238. continue;
  1239. LLQuaternion first_frame_rot;
  1240. LLQuaternion fixup_rot;
  1241. dp.packString(joint->mOutName, "joint_name");
  1242. dp.packS32(joint->mPriority, "joint_priority");
  1243. // compute coordinate frame rotation
  1244. LLQuaternion frameRot( joint->mFrameMatrix );
  1245. LLQuaternion frameRotInv = ~frameRot;
  1246. LLQuaternion offsetRot( joint->mOffsetMatrix );
  1247. // find mergechild and mergeparent joints, if specified
  1248. LLQuaternion mergeParentRot;
  1249. LLQuaternion mergeChildRot;
  1250. Joint *mergeParent = NULL;
  1251. Joint *mergeChild = NULL;
  1252. JointVector::iterator mji;
  1253. for (mji=mJoints.begin(); mji!=mJoints.end(); ++mji)
  1254. {
  1255. Joint *mjoint = *mji;
  1256. if ( !joint->mMergeParentName.empty() && (mjoint->mName == joint->mMergeParentName) )
  1257. {
  1258. mergeParent = *mji;
  1259. }
  1260. if ( !joint->mMergeChildName.empty() && (mjoint->mName == joint->mMergeChildName) )
  1261. {
  1262. mergeChild = *mji;
  1263. }
  1264. }
  1265. dp.packS32(joint->mNumRotKeys, "num_rot_keys");
  1266. LLQuaternion::Order order = bvhStringToOrder( joint->mOrder );
  1267. S32 outcount = 0;
  1268. S32 frame = 1;
  1269. for ( ki = joint->mKeys.begin();
  1270. ki != joint->mKeys.end();
  1271. ++ki )
  1272. {
  1273. if ((frame == 1) && joint->mRelativeRotationKey)
  1274. {
  1275. first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
  1276. fixup_rot.shortestArc(LLVector3::z_axis * first_frame_rot * frameRot, LLVector3::z_axis);
  1277. }
  1278. if (ki->mIgnoreRot)
  1279. {
  1280. frame++;
  1281. continue;
  1282. }
  1283. time = (F32)frame * mFrameTime;
  1284. if (mergeParent)
  1285. {
  1286. mergeParentRot = mayaQ( mergeParent->mKeys[frame-1].mRot[0], 
  1287. mergeParent->mKeys[frame-1].mRot[1],
  1288. mergeParent->mKeys[frame-1].mRot[2],
  1289. bvhStringToOrder(mergeParent->mOrder) );
  1290. LLQuaternion parentFrameRot( mergeParent->mFrameMatrix );
  1291. LLQuaternion parentOffsetRot( mergeParent->mOffsetMatrix );
  1292. mergeParentRot = ~parentFrameRot * mergeParentRot * parentFrameRot * parentOffsetRot;
  1293. }
  1294. else
  1295. {
  1296. mergeParentRot.loadIdentity();
  1297. }
  1298. if (mergeChild)
  1299. {
  1300. mergeChildRot = mayaQ( mergeChild->mKeys[frame-1].mRot[0], 
  1301. mergeChild->mKeys[frame-1].mRot[1],
  1302. mergeChild->mKeys[frame-1].mRot[2],
  1303. bvhStringToOrder(mergeChild->mOrder) );
  1304. LLQuaternion childFrameRot( mergeChild->mFrameMatrix );
  1305. LLQuaternion childOffsetRot( mergeChild->mOffsetMatrix );
  1306. mergeChildRot = ~childFrameRot * mergeChildRot * childFrameRot * childOffsetRot;
  1307. }
  1308. else
  1309. {
  1310. mergeChildRot.loadIdentity();
  1311. }
  1312. LLQuaternion inRot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order);
  1313. LLQuaternion outRot =  frameRotInv* mergeChildRot * inRot * mergeParentRot * ~first_frame_rot * frameRot * offsetRot;
  1314. U16 time_short = F32_to_U16(time, 0.f, mDuration);
  1315. dp.packU16(time_short, "time");
  1316. U16 x, y, z;
  1317. LLVector3 rot_vec = outRot.packToVector3();
  1318. rot_vec.quantize16(-1.f, 1.f, -1.f, 1.f);
  1319. x = F32_to_U16(rot_vec.mV[VX], -1.f, 1.f);
  1320. y = F32_to_U16(rot_vec.mV[VY], -1.f, 1.f);
  1321. z = F32_to_U16(rot_vec.mV[VZ], -1.f, 1.f);
  1322. dp.packU16(x, "rot_angle_x");
  1323. dp.packU16(y, "rot_angle_y");
  1324. dp.packU16(z, "rot_angle_z");
  1325. outcount++;
  1326. frame++;
  1327. }
  1328. // output position keys (only for 1st joint)
  1329. if ( ji == mJoints.begin() && !joint->mIgnorePositions )
  1330. {
  1331. dp.packS32(joint->mNumPosKeys, "num_pos_keys");
  1332. LLVector3 relPos = joint->mRelativePosition;
  1333. LLVector3 relKey;
  1334. frame = 1;
  1335. for ( ki = joint->mKeys.begin();
  1336. ki != joint->mKeys.end();
  1337. ++ki )
  1338. {
  1339. if ((frame == 1) && joint->mRelativePositionKey)
  1340. {
  1341. relKey.setVec(ki->mPos);
  1342. }
  1343. if (ki->mIgnorePos)
  1344. {
  1345. frame++;
  1346. continue;
  1347. }
  1348. time = (F32)frame * mFrameTime;
  1349. LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot;
  1350. LLVector3 outPos = inPos * frameRot * offsetRot;
  1351. outPos *= INCHES_TO_METERS;
  1352. outPos -= relPos;
  1353. outPos.clamp(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
  1354. U16 time_short = F32_to_U16(time, 0.f, mDuration);
  1355. dp.packU16(time_short, "time");
  1356. U16 x, y, z;
  1357. outPos.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
  1358. x = F32_to_U16(outPos.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
  1359. y = F32_to_U16(outPos.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
  1360. z = F32_to_U16(outPos.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
  1361. dp.packU16(x, "pos_x");
  1362. dp.packU16(y, "pos_y");
  1363. dp.packU16(z, "pos_z");
  1364. frame++;
  1365. }
  1366. }
  1367. else
  1368. {
  1369. dp.packS32(0, "num_pos_keys");
  1370. }
  1371. }
  1372. S32 num_constraints = (S32)mConstraints.size();
  1373. dp.packS32(num_constraints, "num_constraints");
  1374. for (ConstraintVector::iterator constraint_it = mConstraints.begin();
  1375. constraint_it != mConstraints.end();
  1376. constraint_it++)
  1377. {
  1378. U8 byte = constraint_it->mChainLength;
  1379. dp.packU8(byte, "chain_lenght");
  1380. byte = constraint_it->mConstraintType;
  1381. dp.packU8(byte, "constraint_type");
  1382. dp.packBinaryDataFixed((U8*)constraint_it->mSourceJointName, 16, "source_volume");
  1383. dp.packVector3(constraint_it->mSourceOffset, "source_offset");
  1384. dp.packBinaryDataFixed((U8*)constraint_it->mTargetJointName, 16, "target_volume");
  1385. dp.packVector3(constraint_it->mTargetOffset, "target_offset");
  1386. dp.packVector3(constraint_it->mTargetDir, "target_dir");
  1387. dp.packF32(constraint_it->mEaseInStart, "ease_in_start");
  1388. dp.packF32(constraint_it->mEaseInStop, "ease_in_stop");
  1389. dp.packF32(constraint_it->mEaseOutStart, "ease_out_start");
  1390. dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop");
  1391. }
  1392. return TRUE;
  1393. }