diff options
Diffstat (limited to 'indra/llcharacter/llbvhloader.cpp')
-rw-r--r-- | indra/llcharacter/llbvhloader.cpp | 375 |
1 files changed, 227 insertions, 148 deletions
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 1d157fd5f5..532a2c1b0d 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -2,30 +2,25 @@ * @file llbvhloader.cpp * @brief Translates a BVH files to LindenLabAnimation format. * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - * - * Copyright (c) 2004-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -55,41 +50,43 @@ const F32 ROTATION_MOTION_THRESHOLD = 0.001f; char gInFile[1024]; /* Flawfinder: ignore */ char gOutFile[1024]; /* Flawfinder: ignore */ - +/* //------------------------------------------------------------------------ // Status Codes //------------------------------------------------------------------------ -char *LLBVHLoader::ST_OK = "Ok"; -char *LLBVHLoader::ST_EOF = "Premature end of file."; -char *LLBVHLoader::ST_NO_CONSTRAINT = "Can't read constraint definition."; -char *LLBVHLoader::ST_NO_FILE = "Can't open BVH file."; -char *LLBVHLoader::ST_NO_HIER = "Invalid HIERARCHY header."; -char *LLBVHLoader::ST_NO_JOINT = "Can't find ROOT or JOINT."; -char *LLBVHLoader::ST_NO_NAME = "Can't get JOINT name."; -char *LLBVHLoader::ST_NO_OFFSET = "Can't find OFFSET."; -char *LLBVHLoader::ST_NO_CHANNELS = "Can't find CHANNELS."; -char *LLBVHLoader::ST_NO_ROTATION = "Can't get rotation order."; -char *LLBVHLoader::ST_NO_AXIS = "Can't get rotation axis."; -char *LLBVHLoader::ST_NO_MOTION = "Can't find MOTION."; -char *LLBVHLoader::ST_NO_FRAMES = "Can't get number of frames."; -char *LLBVHLoader::ST_NO_FRAME_TIME = "Can't get frame time."; -char *LLBVHLoader::ST_NO_POS = "Can't get position values."; -char *LLBVHLoader::ST_NO_ROT = "Can't get rotation values."; -char *LLBVHLoader::ST_NO_XLT_FILE = "Can't open translation file."; -char *LLBVHLoader::ST_NO_XLT_HEADER = "Can't read translation header."; -char *LLBVHLoader::ST_NO_XLT_NAME = "Can't read translation names."; -char *LLBVHLoader::ST_NO_XLT_IGNORE = "Can't read translation ignore value."; -char *LLBVHLoader::ST_NO_XLT_RELATIVE = "Can't read translation relative value."; -char *LLBVHLoader::ST_NO_XLT_OUTNAME = "Can't read translation outname value."; -char *LLBVHLoader::ST_NO_XLT_MATRIX = "Can't read translation matrix."; -char *LLBVHLoader::ST_NO_XLT_MERGECHILD = "Can't get mergechild name."; -char *LLBVHLoader::ST_NO_XLT_MERGEPARENT = "Can't get mergeparent name."; -char *LLBVHLoader::ST_NO_XLT_PRIORITY = "Can't get priority value."; -char *LLBVHLoader::ST_NO_XLT_LOOP = "Can't get loop value."; -char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values."; -char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values."; -char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value."; -char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name."; +const char *LLBVHLoader::ST_OK = "Ok"; +const char *LLBVHLoader::ST_EOF = "Premature end of file."; +const char *LLBVHLoader::ST_NO_CONSTRAINT = "Can't read constraint definition."; +const char *LLBVHLoader::ST_NO_FILE = "Can't open BVH file."; +const char *LLBVHLoader::ST_NO_HIER = "Invalid HIERARCHY header."; +const char *LLBVHLoader::ST_NO_JOINT = "Can't find ROOT or JOINT."; +const char *LLBVHLoader::ST_NO_NAME = "Can't get JOINT name."; +const char *LLBVHLoader::ST_NO_OFFSET = "Can't find OFFSET."; +const char *LLBVHLoader::ST_NO_CHANNELS = "Can't find CHANNELS."; +const char *LLBVHLoader::ST_NO_ROTATION = "Can't get rotation order."; +const char *LLBVHLoader::ST_NO_AXIS = "Can't get rotation axis."; +const char *LLBVHLoader::ST_NO_MOTION = "Can't find MOTION."; +const char *LLBVHLoader::ST_NO_FRAMES = "Can't get number of frames."; +const char *LLBVHLoader::ST_NO_FRAME_TIME = "Can't get frame time."; +const char *LLBVHLoader::ST_NO_POS = "Can't get position values."; +const char *LLBVHLoader::ST_NO_ROT = "Can't get rotation values."; +const char *LLBVHLoader::ST_NO_XLT_FILE = "Can't open translation file."; +const char *LLBVHLoader::ST_NO_XLT_HEADER = "Can't read translation header."; +const char *LLBVHLoader::ST_NO_XLT_NAME = "Can't read translation names."; +const char *LLBVHLoader::ST_NO_XLT_IGNORE = "Can't read translation ignore value."; +const char *LLBVHLoader::ST_NO_XLT_RELATIVE = "Can't read translation relative value."; +const char *LLBVHLoader::ST_NO_XLT_OUTNAME = "Can't read translation outname value."; +const char *LLBVHLoader::ST_NO_XLT_MATRIX = "Can't read translation matrix."; +const char *LLBVHLoader::ST_NO_XLT_MERGECHILD = "Can't get mergechild name."; +const char *LLBVHLoader::ST_NO_XLT_MERGEPARENT = "Can't get mergeparent name."; +const char *LLBVHLoader::ST_NO_XLT_PRIORITY = "Can't get priority value."; +const char *LLBVHLoader::ST_NO_XLT_LOOP = "Can't get loop value."; +const char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values."; +const char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values."; +const char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value."; +const char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name."; +const char *LLBVHLoader::ST_BAD_ROOT = "Illegal ROOT joint."; +*/ //------------------------------------------------------------------------ // find_next_whitespace() @@ -123,7 +120,9 @@ LLQuaternion::Order bvhStringToOrder( char *str ) //----------------------------------------------------------------------------- // LLBVHLoader() //----------------------------------------------------------------------------- -LLBVHLoader::LLBVHLoader(const char* buffer) + +/* + LLBVHLoader::LLBVHLoader(const char* buffer) { reset(); @@ -143,7 +142,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer) } } - char error_text[128]; /* Flawfinder: ignore */ + char error_text[128]; // Flawfinder: ignore S32 error_line; mStatus = loadBVHFile(buffer, error_text, error_line); if (mStatus != LLBVHLoader::ST_OK) @@ -157,6 +156,49 @@ LLBVHLoader::LLBVHLoader(const char* buffer) mInitialized = TRUE; } +*/ +LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine) +{ + reset(); + errorLine = 0; + mStatus = loadTranslationTable("anim.ini"); + loadStatus = mStatus; + llinfos<<"Load Status 00 : "<< loadStatus << llendl; + if (mStatus == E_ST_NO_XLT_FILE) + { + //llwarns << "NOTE: No translation table found." << llendl; + loadStatus = mStatus; + return; + } + else + { + if (mStatus != E_ST_OK) + { + //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl; + errorLine = getLineNumber(); + loadStatus = mStatus; + return; + } + } + + char error_text[128]; /* Flawfinder: ignore */ + S32 error_line; + mStatus = loadBVHFile(buffer, error_text, error_line); + + if (mStatus != E_ST_OK) + { + //llwarns << "ERROR: [line: " << getLineNumber() << "] " << mStatus << llendl; + loadStatus = mStatus; + errorLine = getLineNumber(); + return; + } + + applyTranslations(); + optimize(); + + mInitialized = TRUE; +} + LLBVHLoader::~LLBVHLoader() { @@ -166,7 +208,7 @@ LLBVHLoader::~LLBVHLoader() //------------------------------------------------------------------------ // LLBVHLoader::loadTranslationTable() //------------------------------------------------------------------------ -LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) +ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) { mLineNumber = 0; mTranslations.clear(); @@ -175,30 +217,27 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //-------------------------------------------------------------------- // open file //-------------------------------------------------------------------- - char path[LL_MAX_PATH]; /* Flawfinder: ignore */ + std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); - snprintf( path, sizeof(path), "%s", /* Flawfinder: ignore */ - gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName).c_str()); - - - apr_file_t *fp = ll_apr_file_open(path, LL_APR_R); + LLAPRFile infile ; + infile.open(path, LL_APR_R); + apr_file_t *fp = infile.getFileHandle(); if (!fp) - return ST_NO_XLT_FILE; + return E_ST_NO_XLT_FILE; llinfos << "NOTE: Loading translation table: " << fileName << llendl; //-------------------------------------------------------------------- // register file to be closed on function exit //-------------------------------------------------------------------- - FileCloser fileCloser(fp); - + //-------------------------------------------------------------------- // load header //-------------------------------------------------------------------- if ( ! getLine(fp) ) - return ST_EOF; + return E_ST_EOF; if ( strncmp(mLine, "Translations 1.0", 16) ) - return ST_NO_XLT_HEADER; + return E_ST_NO_XLT_HEADER; //-------------------------------------------------------------------- // load data one line at a time @@ -224,7 +263,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) { char name[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " [%127[^]]", name) != 1 ) - return ST_NO_XLT_NAME; + return E_ST_NO_XLT_NAME; if (strcmp(name, "GLOBALS")==0) { @@ -243,11 +282,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for optional emote //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "emote")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "emote")==0) { char emote_str[1024]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_EMOTE; + return E_ST_NO_XLT_EMOTE; mEmoteName.assign( emote_str ); // llinfos << "NOTE: Emote: " << mEmoteName.c_str() << llendl; @@ -258,11 +297,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global priority setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "priority")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "priority")==0) { S32 priority; if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return ST_NO_XLT_PRIORITY; + return E_ST_NO_XLT_PRIORITY; mPriority = priority; // llinfos << "NOTE: Priority: " << mPriority << llendl; @@ -272,7 +311,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global loop setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "loop")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "loop")==0) { char trueFalse[128]; /* Flawfinder: ignore */ trueFalse[0] = '\0'; @@ -286,11 +325,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) } else if ( sscanf(mLine, " %*s = %127s", trueFalse) == 1 ) /* Flawfinder: ignore */ { - mLoop = (LLString::compareInsensitive(trueFalse, "true")==0); + mLoop = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); } else { - return ST_NO_XLT_LOOP; + return E_ST_NO_XLT_LOOP; } mLoopInPoint = loop_in * mDuration; @@ -302,12 +341,12 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global easeIn setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "easein")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easein")==0) { F32 duration; char type[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ - return ST_NO_XLT_EASEIN; + return E_ST_NO_XLT_EASEIN; mEaseIn = duration; continue; @@ -316,12 +355,12 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global easeOut setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "easeout")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easeout")==0) { F32 duration; char type[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ - return ST_NO_XLT_EASEOUT; + return E_ST_NO_XLT_EASEOUT; mEaseOut = duration; continue; @@ -330,17 +369,17 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for global handMorph setting //---------------------------------------------------------------- - if (loadingGlobals && LLString::compareInsensitive(token, "hand")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "hand")==0) { S32 handMorph; if (sscanf(mLine, " %*s = %d", &handMorph) != 1) - return ST_NO_XLT_HAND; + return E_ST_NO_XLT_HAND; mHand = handMorph; continue; } - if (loadingGlobals && LLString::compareInsensitive(token, "constraint")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "constraint")==0) { Constraint constraint; @@ -382,7 +421,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) &constraint.mTargetOffset.mV[VY], &constraint.mTargetOffset.mV[VZ]) != 13) { - return ST_NO_CONSTRAINT; + return E_ST_NO_CONSTRAINT; } } else @@ -400,7 +439,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) continue; } - if (loadingGlobals && LLString::compareInsensitive(token, "planar_constraint")==0) + if (loadingGlobals && LLStringUtil::compareInsensitive(token, "planar_constraint")==0) { Constraint constraint; @@ -442,7 +481,7 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) &constraint.mTargetOffset.mV[VY], &constraint.mTargetOffset.mV[VZ]) != 13) { - return ST_NO_CONSTRAINT; + return E_ST_NO_CONSTRAINT; } } else @@ -465,25 +504,25 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) // at this point there must be a valid trans pointer //---------------------------------------------------------------- if ( ! trans ) - return ST_NO_XLT_NAME; + return E_ST_NO_XLT_NAME; //---------------------------------------------------------------- // check for ignore flag //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "ignore")==0 ) + if ( LLStringUtil::compareInsensitive(token, "ignore")==0 ) { char trueFalse[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_IGNORE; + return E_ST_NO_XLT_IGNORE; - trans->mIgnore = (LLString::compareInsensitive(trueFalse, "true")==0); + trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); continue; } //---------------------------------------------------------------- // check for relativepos flag //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "relativepos")==0 ) + if ( LLStringUtil::compareInsensitive(token, "relativepos")==0 ) { F32 x, y, z; char relpos[128]; /* Flawfinder: ignore */ @@ -493,18 +532,18 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) } else if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ { - if ( LLString::compareInsensitive(relpos, "firstkey")==0 ) + if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) { trans->mRelativePositionKey = TRUE; } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } continue; @@ -513,24 +552,24 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for relativerot flag //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "relativerot")==0 ) + if ( LLStringUtil::compareInsensitive(token, "relativerot")==0 ) { //F32 x, y, z; char relpos[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ { - if ( LLString::compareInsensitive(relpos, "firstkey")==0 ) + if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) { trans->mRelativeRotationKey = TRUE; } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } } else { - return ST_NO_XLT_RELATIVE; + return E_ST_NO_XLT_RELATIVE; } continue; @@ -539,11 +578,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for outname value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "outname")==0 ) + if ( LLStringUtil::compareInsensitive(token, "outname")==0 ) { char outName[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_OUTNAME; + return E_ST_NO_XLT_OUTNAME; trans->mOutName = outName; continue; @@ -552,14 +591,14 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for frame matrix value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "frame")==0 ) + if ( LLStringUtil::compareInsensitive(token, "frame")==0 ) { LLMatrix3 fm; if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", &fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2], &fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2], &fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 ) - return ST_NO_XLT_MATRIX; + return E_ST_NO_XLT_MATRIX; trans->mFrameMatrix = fm; continue; @@ -568,14 +607,14 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for offset matrix value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "offset")==0 ) + if ( LLStringUtil::compareInsensitive(token, "offset")==0 ) { LLMatrix3 om; if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", &om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2], &om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2], &om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 ) - return ST_NO_XLT_MATRIX; + return E_ST_NO_XLT_MATRIX; trans->mOffsetMatrix = om; continue; @@ -584,11 +623,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for mergeparent value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "mergeparent")==0 ) + if ( LLStringUtil::compareInsensitive(token, "mergeparent")==0 ) { char mergeParentName[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_MERGEPARENT; + return E_ST_NO_XLT_MERGEPARENT; trans->mMergeParentName = mergeParentName; continue; @@ -597,11 +636,11 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for mergechild value //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "mergechild")==0 ) + if ( LLStringUtil::compareInsensitive(token, "mergechild")==0 ) { char mergeChildName[128]; /* Flawfinder: ignore */ if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */ - return ST_NO_XLT_MERGECHILD; + return E_ST_NO_XLT_MERGECHILD; trans->mMergeChildName = mergeChildName; continue; @@ -610,25 +649,27 @@ LLBVHLoader::Status LLBVHLoader::loadTranslationTable(const char *fileName) //---------------------------------------------------------------- // check for per-joint priority //---------------------------------------------------------------- - if ( LLString::compareInsensitive(token, "priority")==0 ) + if ( LLStringUtil::compareInsensitive(token, "priority")==0 ) { S32 priority; if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return ST_NO_XLT_PRIORITY; + return E_ST_NO_XLT_PRIORITY; trans->mPriorityModifier = priority; continue; } } - return ST_OK; + + infile.close() ; + return E_ST_OK; } //------------------------------------------------------------------------ // LLBVHLoader::loadBVHFile() //------------------------------------------------------------------------ -LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line) +ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 &err_line) { std::string line; @@ -650,14 +691,14 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex // consume hierarchy //-------------------------------------------------------------------- if (iter == tokens.end()) - return ST_EOF; + return E_ST_EOF; line = (*(iter++)); err_line++; if ( !strstr(line.c_str(), "HIERARCHY") ) { // llinfos << line << llendl; - return ST_NO_HIER; + return E_ST_NO_HIER; } //-------------------------------------------------------------------- @@ -669,7 +710,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex // get next line //---------------------------------------------------------------- if (iter == tokens.end()) - return ST_EOF; + return E_ST_EOF; line = (*(iter++)); err_line++; @@ -719,7 +760,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex else { strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return ST_NO_JOINT; + return E_ST_NO_JOINT; } //---------------------------------------------------------------- @@ -729,9 +770,20 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( sscanf(line.c_str(), "%*s %79s", jointName) != 1 ) /* Flawfinder: ignore */ { strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ - return ST_NO_NAME; + return E_ST_NO_NAME; } + //--------------------------------------------------------------- + // we require the root joint be "hip" - DEV-26188 + //--------------------------------------------------------------- + const char* FORCED_ROOT_NAME = "hip"; + if ( (mJoints.size() == 0 ) && ( !strstr(jointName, FORCED_ROOT_NAME) ) ) + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_BAD_ROOT; + } + + //---------------------------------------------------------------- // add a set of keyframes for this joint //---------------------------------------------------------------- @@ -754,7 +806,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //---------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -765,7 +817,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "{") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_OFFSET; + return E_ST_NO_OFFSET; } else { @@ -777,7 +829,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //---------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -788,7 +840,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "OFFSET") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_OFFSET; + return E_ST_NO_OFFSET; } //---------------------------------------------------------------- @@ -796,7 +848,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //---------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -807,7 +859,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "CHANNELS") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_CHANNELS; + return E_ST_NO_CHANNELS; } //---------------------------------------------------------------- @@ -820,14 +872,14 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROTATION; + return E_ST_NO_ROTATION; } const char axis = *(p - 1); if ((axis != 'X') && (axis != 'Y') && (axis != 'Z')) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_AXIS; + return E_ST_NO_AXIS; } joint->mOrder[i] = axis; @@ -842,7 +894,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "MOTION") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_MOTION; + return E_ST_NO_MOTION; } //-------------------------------------------------------------------- @@ -850,7 +902,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //-------------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -858,13 +910,13 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "Frames:") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAMES; + return E_ST_NO_FRAMES; } if ( sscanf(line.c_str(), "Frames: %d", &mNumFrames) != 1 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAMES; + return E_ST_NO_FRAMES; } //-------------------------------------------------------------------- @@ -872,7 +924,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex //-------------------------------------------------------------------- if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -880,13 +932,13 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( !strstr(line.c_str(), "Frame Time:") ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAME_TIME; + return E_ST_NO_FRAME_TIME; } if ( sscanf(line.c_str(), "Frame Time: %f", &mFrameTime) != 1 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_FRAME_TIME; + return E_ST_NO_FRAME_TIME; } mDuration = (F32)mNumFrames * mFrameTime; @@ -903,7 +955,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex // get next line if (iter == tokens.end()) { - return ST_EOF; + return E_ST_EOF; } line = (*(iter++)); err_line++; @@ -922,7 +974,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( sscanf(p, "%f %f %f", key.mPos, key.mPos+1, key.mPos+2) != 3 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_POS; + return E_ST_NO_POS; } } @@ -931,19 +983,19 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } p = find_next_whitespace(++p); if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } p = find_next_whitespace(++p); if (!p) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } // get 3 rot values for joint @@ -951,7 +1003,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex if ( sscanf(p, " %f %f %f", rot, rot+1, rot+2) != 3 ) { strncpy(error_text, line.c_str(), 127); /*Flawfinder: ignore*/ - return ST_NO_ROT; + return E_ST_NO_ROT; } p++; @@ -962,7 +1014,7 @@ LLBVHLoader::Status LLBVHLoader::loadBVHFile(const char *buffer, char* error_tex } } - return ST_OK; + return E_ST_OK; } @@ -1137,6 +1189,8 @@ void LLBVHLoader::optimize() F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); + double diff_max = 0; + KeyVector::iterator ki_max = ki; for (; ki != joint->mKeys.end(); ++ki) { if (ki_prev == ki_last_good_pos) @@ -1197,30 +1251,55 @@ void LLBVHLoader::optimize() F32 x_delta; F32 y_delta; F32 rot_test; - + + // Test if the rotation has changed significantly since the very first frame. If false + // for all frames, then we'll just throw out this joint's rotation entirely. x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); rot_test = x_delta + y_delta; - if (rot_test > ROTATION_MOTION_THRESHOLD) { rot_changed = TRUE; } - x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); rot_test = x_delta + y_delta; - if (rot_test < rot_threshold) - { - ki_prev->mIgnoreRot = TRUE; - numRotFramesConsidered++; - } - else + // Draw a line between the last good keyframe and current. Test the distance between the last frame (current-1, i.e. ki_prev) + // and the line. If it's greater than some threshold, then it represents a significant frame and we want to include it. + if (rot_test >= rot_threshold || + (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2)) { + // Add the current test keyframe (which is technically the previous key, i.e. ki_prev). numRotFramesConsidered = 2; ki_last_good_rot = ki_prev; joint->mNumRotKeys++; + + // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e. + // had the largest deviation from the earlier tests). Note that a more robust approach would be test all intermediate + // keyframes against the line between the last good keyframe and current, but we're settling for this other method + // because it's significantly faster. + if (diff_max > 0) + { + if (ki_max->mIgnoreRot == TRUE) + { + ki_max->mIgnoreRot = FALSE; + joint->mNumRotKeys++; + } + diff_max = 0; + } + } + else + { + // This keyframe isn't significant enough, throw it away. + ki_prev->mIgnoreRot = TRUE; + numRotFramesConsidered++; + // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later. + if (rot_test > diff_max) + { + diff_max = rot_test; + ki_max = ki; + } } } @@ -1304,7 +1383,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) dp.packU16(KEYFRAME_MOTION_SUBVERSION, "sub_version"); dp.packS32(mPriority, "base_priority"); dp.packF32(mDuration, "duration"); - dp.packString(mEmoteName.c_str(), "emote_name"); + dp.packString(mEmoteName, "emote_name"); dp.packF32(mLoopInPoint, "loop_in_point"); dp.packF32(mLoopOutPoint, "loop_out_point"); dp.packS32(mLoop, "loop"); @@ -1325,7 +1404,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) LLQuaternion first_frame_rot; LLQuaternion fixup_rot; - dp.packString(joint->mOutName.c_str(), "joint_name"); + dp.packString(joint->mOutName, "joint_name"); dp.packS32(joint->mPriority, "joint_priority"); // compute coordinate frame rotation |