PageRenderTime 34ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/llcharacter/llbvhloader.cpp

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