summaryrefslogtreecommitdiff
path: root/indra/llcharacter/llkeyframemotionparam.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
committerAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 19:04:52 +0200
commit1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch)
treeab243607f74f78200787bba5b9b88f07ef1b966f /indra/llcharacter/llkeyframemotionparam.cpp
parent6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff)
parente1623bb276f83a43ce7a197e388720c05bdefe61 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts: # autobuild.xml # indra/cmake/CMakeLists.txt # indra/cmake/GoogleMock.cmake # indra/llaudio/llaudioengine_fmodstudio.cpp # indra/llaudio/llaudioengine_fmodstudio.h # indra/llaudio/lllistener_fmodstudio.cpp # indra/llaudio/lllistener_fmodstudio.h # indra/llaudio/llstreamingaudio_fmodstudio.cpp # indra/llaudio/llstreamingaudio_fmodstudio.h # indra/llcharacter/llmultigesture.cpp # indra/llcharacter/llmultigesture.h # indra/llimage/llimage.cpp # indra/llimage/llimagepng.cpp # indra/llimage/llimageworker.cpp # indra/llimage/tests/llimageworker_test.cpp # indra/llmessage/tests/llmockhttpclient.h # indra/llprimitive/llgltfmaterial.h # indra/llrender/llfontfreetype.cpp # indra/llui/llcombobox.cpp # indra/llui/llfolderview.cpp # indra/llui/llfolderviewmodel.h # indra/llui/lllineeditor.cpp # indra/llui/lllineeditor.h # indra/llui/lltextbase.cpp # indra/llui/lltextbase.h # indra/llui/lltexteditor.cpp # indra/llui/lltextvalidate.cpp # indra/llui/lltextvalidate.h # indra/llui/lluictrl.h # indra/llui/llview.cpp # indra/llwindow/llwindowmacosx.cpp # indra/newview/app_settings/settings.xml # indra/newview/llappearancemgr.cpp # indra/newview/llappearancemgr.h # indra/newview/llavatarpropertiesprocessor.cpp # indra/newview/llavatarpropertiesprocessor.h # indra/newview/llbreadcrumbview.cpp # indra/newview/llbreadcrumbview.h # indra/newview/llbreastmotion.cpp # indra/newview/llbreastmotion.h # indra/newview/llconversationmodel.h # indra/newview/lldensityctrl.cpp # indra/newview/lldensityctrl.h # indra/newview/llface.inl # indra/newview/llfloatereditsky.cpp # indra/newview/llfloatereditwater.cpp # indra/newview/llfloateremojipicker.h # indra/newview/llfloaterimsessiontab.cpp # indra/newview/llfloaterprofiletexture.cpp # indra/newview/llfloaterprofiletexture.h # indra/newview/llgesturemgr.cpp # indra/newview/llgesturemgr.h # indra/newview/llimpanel.cpp # indra/newview/llimpanel.h # indra/newview/llinventorybridge.cpp # indra/newview/llinventorybridge.h # indra/newview/llinventoryclipboard.cpp # indra/newview/llinventoryclipboard.h # indra/newview/llinventoryfunctions.cpp # indra/newview/llinventoryfunctions.h # indra/newview/llinventorygallery.cpp # indra/newview/lllistbrowser.cpp # indra/newview/lllistbrowser.h # indra/newview/llpanelobjectinventory.cpp # indra/newview/llpanelprofile.cpp # indra/newview/llpanelprofile.h # indra/newview/llpreviewgesture.cpp # indra/newview/llsavedsettingsglue.cpp # indra/newview/llsavedsettingsglue.h # indra/newview/lltooldraganddrop.cpp # indra/newview/llurllineeditorctrl.cpp # indra/newview/llvectorperfoptions.cpp # indra/newview/llvectorperfoptions.h # indra/newview/llviewerparceloverlay.cpp # indra/newview/llviewertexlayer.cpp # indra/newview/llviewertexturelist.cpp # indra/newview/macmain.h # indra/test/test.cpp
Diffstat (limited to 'indra/llcharacter/llkeyframemotionparam.cpp')
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp872
1 files changed, 436 insertions, 436 deletions
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
index dfb6c1ec9f..e2f1602353 100644
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ b/indra/llcharacter/llkeyframemotionparam.cpp
@@ -1,436 +1,436 @@
-/**
- * @file llkeyframemotionparam.cpp
- * @brief Implementation of LLKeyframeMotion class.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * 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.
- *
- * 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.
- *
- * 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$
- */
-
-//-----------------------------------------------------------------------------
-// Header Files
-//-----------------------------------------------------------------------------
-#include "linden_common.h"
-
-#include "llkeyframemotionparam.h"
-#include "llcharacter.h"
-#include "llmath.h"
-#include "m3math.h"
-#include "lldir.h"
-#include "llanimationstates.h"
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam class
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
-{
- mDefaultKeyframeMotion = NULL;
- mCharacter = NULL;
-
- mEaseInDuration = 0.f;
- mEaseOutDuration = 0.f;
- mDuration = 0.f;
- mPriority = LLJoint::LOW_PRIORITY;
-}
-
-
-//-----------------------------------------------------------------------------
-// ~LLKeyframeMotionParam()
-// Class Destructor
-//-----------------------------------------------------------------------------
-LLKeyframeMotionParam::~LLKeyframeMotionParam()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- delete paramMotion.mMotion;
- }
- motionList.clear();
- }
- mParameterizedMotions.clear();
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onInitialize(LLCharacter *character)
-//-----------------------------------------------------------------------------
-LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
-{
- mCharacter = character;
-
- if (!loadMotions())
- {
- return STATUS_FAILURE;
- }
-
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- LLMotion* motion = paramMotion.mMotion;
- motion->onInitialize(character);
-
- if (motion->getDuration() > mEaseInDuration)
- {
- mEaseInDuration = motion->getEaseInDuration();
- }
-
- if (motion->getEaseOutDuration() > mEaseOutDuration)
- {
- mEaseOutDuration = motion->getEaseOutDuration();
- }
-
- if (motion->getDuration() > mDuration)
- {
- mDuration = motion->getDuration();
- }
-
- if (motion->getPriority() > mPriority)
- {
- mPriority = motion->getPriority();
- }
-
- LLPose *pose = motion->getPose();
-
- mPoseBlender.addMotion(motion);
- for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
- {
- LLPose *blendedPose = mPoseBlender.getBlendedPose();
- blendedPose->addJointState(jsp);
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onActivate()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::onActivate()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->activate(mActivationTimestamp);
- }
- }
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onUpdate()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
-{
- LL_PROFILE_ZONE_SCOPED;
- F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
-
- // zero out all pose weights
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
-// LL_INFOS() << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << LL_ENDL;
- paramMotion.mMotion->getPose()->setWeight(0.f);
- }
- }
-
-
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- const std::string& paramName = motion_pair.first;
- F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
- if (NULL == paramValue) // unexpected, but...
- {
- LL_WARNS() << "paramValue == NULL" << LL_ENDL;
- continue;
- }
-
- // DANGER! Do not modify mParameterizedMotions while using these pointers!
- const ParameterizedMotion* firstMotion = NULL;
- const ParameterizedMotion* secondMotion = NULL;
-
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->onUpdate(time, joint_mask);
-
- F32 distToParam = paramMotion.mParam - *paramValue;
-
- if ( distToParam <= 0.f)
- {
- // keep track of the motion closest to the parameter value
- firstMotion = &paramMotion;
- }
- else
- {
- // we've passed the parameter value
- // so store the first motion we find as the second one we want to blend...
- if (firstMotion && !secondMotion )
- {
- secondMotion = &paramMotion;
- }
- //...or, if we've seen no other motion so far, make sure we blend to this only
- else if (!firstMotion)
- {
- firstMotion = &paramMotion;
- secondMotion = &paramMotion;
- }
- }
- }
-
- LLPose *firstPose;
- LLPose *secondPose;
-
- if (firstMotion)
- firstPose = firstMotion->mMotion->getPose();
- else
- firstPose = NULL;
-
- if (secondMotion)
- secondPose = secondMotion->mMotion->getPose();
- else
- secondPose = NULL;
-
- // now modify weight of the subanim (only if we are blending between two motions)
- if (firstMotion && secondMotion)
- {
- if (firstMotion == secondMotion)
- {
- firstPose->setWeight(weightFactor);
- }
- else if (firstMotion->mParam == secondMotion->mParam)
- {
- firstPose->setWeight(0.5f * weightFactor);
- secondPose->setWeight(0.5f * weightFactor);
- }
- else
- {
- F32 first_weight = 1.f -
- ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) /
- (secondMotion->mParam - firstMotion->mParam));
- first_weight = llclamp(first_weight, 0.f, 1.f);
-
- F32 second_weight = 1.f - first_weight;
-
- firstPose->setWeight(first_weight * weightFactor);
- secondPose->setWeight(second_weight * weightFactor);
-
-// LL_INFOS() << "Parameter " << *paramName << ": " << *paramValue << LL_ENDL;
-// LL_INFOS() << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << LL_ENDL;
- }
- }
- else if (firstMotion && !secondMotion)
- {
- firstPose->setWeight(weightFactor);
- }
- }
-
- // blend poses
- mPoseBlender.blendAndApply();
-
- LL_INFOS() << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << LL_ENDL;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onDeactivate()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotionParam::onDeactivate()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->onDeactivate();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::addKeyframeMotion()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
-{
- LLMotion *newMotion = mCharacter->createMotion( id );
-
- if (!newMotion)
- {
- return false;
- }
-
- newMotion->setName(name);
-
- // now add motion to this list
- mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::setDefaultKeyframeMotion()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- if (paramMotion.mMotion->getName() == name)
- {
- mDefaultKeyframeMotion = paramMotion.mMotion;
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// loadMotions()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::loadMotions()
-{
- //-------------------------------------------------------------------------
- // Load named file by concatenating the character prefix with the motion name.
- // Load data into a buffer to be parsed.
- //-------------------------------------------------------------------------
- //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
- // + "_" + getName() + ".llp";
- //RN: deprecated unused reference to "motion" directory
- std::string path;
-
-
- //-------------------------------------------------------------------------
- // open the file
- //-------------------------------------------------------------------------
- S32 fileSize = 0;
- LLAPRFile infile ;
- infile.open(path, LL_APR_R, NULL, &fileSize);
- apr_file_t* fp = infile.getFileHandle() ;
- if (!fp || fileSize == 0)
- {
- LL_INFOS() << "ERROR: can't open: " << path << LL_ENDL;
- return false;
- }
-
- // allocate a text buffer
- std::vector<char> text(fileSize+1);
-
- //-------------------------------------------------------------------------
- // load data from file into buffer
- //-------------------------------------------------------------------------
- bool error = false;
- char *p = &text[0];
- while ( 1 )
- {
- if (apr_file_eof(fp) == APR_EOF)
- {
- break;
- }
- if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
- {
- error = true;
- break;
- }
- while ( *(++p) )
- ;
- }
-
- //-------------------------------------------------------------------------
- // close the file
- //-------------------------------------------------------------------------
- infile.close();
-
- //-------------------------------------------------------------------------
- // check for error
- //-------------------------------------------------------------------------
- llassert( p <= (&text[0] + fileSize) );
-
- if ( error )
- {
- LL_INFOS() << "ERROR: error while reading from " << path << LL_ENDL;
- return false;
- }
-
- LL_INFOS() << "Loading parametric keyframe data for: " << getName() << LL_ENDL;
-
- //-------------------------------------------------------------------------
- // parse the text and build keyframe data structures
- //-------------------------------------------------------------------------
- p = &text[0];
- S32 num;
- char strA[80]; /* Flawfinder: ignore */
- char strB[80]; /* Flawfinder: ignore */
- F32 floatA = 0.0f;
-
-
- //-------------------------------------------------------------------------
- // get priority
- //-------------------------------------------------------------------------
- bool isFirstMotion = true;
- num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
-
- while(1)
- {
- if (num == 0 || num == EOF) break;
- if ((num != 3))
- {
- LL_INFOS() << "WARNING: can't read parametric motion" << LL_ENDL;
- return false;
- }
-
- addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA);
- if (isFirstMotion)
- {
- isFirstMotion = false;
- setDefaultKeyframeMotion(strA);
- }
-
- p = strstr(p, "\n");
- if (!p)
- {
- break;
- }
-
- p++;
- num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
- }
-
- return true;
-}
-
-// End
+/**
+ * @file llkeyframemotionparam.cpp
+ * @brief Implementation of LLKeyframeMotion class.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+
+#include "llkeyframemotionparam.h"
+#include "llcharacter.h"
+#include "llmath.h"
+#include "m3math.h"
+#include "lldir.h"
+#include "llanimationstates.h"
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam class
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam()
+// Class Constructor
+//-----------------------------------------------------------------------------
+LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
+{
+ mDefaultKeyframeMotion = NULL;
+ mCharacter = NULL;
+
+ mEaseInDuration = 0.f;
+ mEaseOutDuration = 0.f;
+ mDuration = 0.f;
+ mPriority = LLJoint::LOW_PRIORITY;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLKeyframeMotionParam()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLKeyframeMotionParam::~LLKeyframeMotionParam()
+{
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+ delete paramMotion.mMotion;
+ }
+ motionList.clear();
+ }
+ mParameterizedMotions.clear();
+}
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam::onInitialize(LLCharacter *character)
+//-----------------------------------------------------------------------------
+LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
+{
+ mCharacter = character;
+
+ if (!loadMotions())
+ {
+ return STATUS_FAILURE;
+ }
+
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+ LLMotion* motion = paramMotion.mMotion;
+ motion->onInitialize(character);
+
+ if (motion->getDuration() > mEaseInDuration)
+ {
+ mEaseInDuration = motion->getEaseInDuration();
+ }
+
+ if (motion->getEaseOutDuration() > mEaseOutDuration)
+ {
+ mEaseOutDuration = motion->getEaseOutDuration();
+ }
+
+ if (motion->getDuration() > mDuration)
+ {
+ mDuration = motion->getDuration();
+ }
+
+ if (motion->getPriority() > mPriority)
+ {
+ mPriority = motion->getPriority();
+ }
+
+ LLPose *pose = motion->getPose();
+
+ mPoseBlender.addMotion(motion);
+ for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
+ {
+ LLPose *blendedPose = mPoseBlender.getBlendedPose();
+ blendedPose->addJointState(jsp);
+ }
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam::onActivate()
+//-----------------------------------------------------------------------------
+bool LLKeyframeMotionParam::onActivate()
+{
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+ paramMotion.mMotion->activate(mActivationTimestamp);
+ }
+ }
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam::onUpdate()
+//-----------------------------------------------------------------------------
+bool LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
+
+ // zero out all pose weights
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+// LL_INFOS() << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << LL_ENDL;
+ paramMotion.mMotion->getPose()->setWeight(0.f);
+ }
+ }
+
+
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ const std::string& paramName = motion_pair.first;
+ F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
+ if (NULL == paramValue) // unexpected, but...
+ {
+ LL_WARNS() << "paramValue == NULL" << LL_ENDL;
+ continue;
+ }
+
+ // DANGER! Do not modify mParameterizedMotions while using these pointers!
+ const ParameterizedMotion* firstMotion = NULL;
+ const ParameterizedMotion* secondMotion = NULL;
+
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+ paramMotion.mMotion->onUpdate(time, joint_mask);
+
+ F32 distToParam = paramMotion.mParam - *paramValue;
+
+ if ( distToParam <= 0.f)
+ {
+ // keep track of the motion closest to the parameter value
+ firstMotion = &paramMotion;
+ }
+ else
+ {
+ // we've passed the parameter value
+ // so store the first motion we find as the second one we want to blend...
+ if (firstMotion && !secondMotion )
+ {
+ secondMotion = &paramMotion;
+ }
+ //...or, if we've seen no other motion so far, make sure we blend to this only
+ else if (!firstMotion)
+ {
+ firstMotion = &paramMotion;
+ secondMotion = &paramMotion;
+ }
+ }
+ }
+
+ LLPose *firstPose;
+ LLPose *secondPose;
+
+ if (firstMotion)
+ firstPose = firstMotion->mMotion->getPose();
+ else
+ firstPose = NULL;
+
+ if (secondMotion)
+ secondPose = secondMotion->mMotion->getPose();
+ else
+ secondPose = NULL;
+
+ // now modify weight of the subanim (only if we are blending between two motions)
+ if (firstMotion && secondMotion)
+ {
+ if (firstMotion == secondMotion)
+ {
+ firstPose->setWeight(weightFactor);
+ }
+ else if (firstMotion->mParam == secondMotion->mParam)
+ {
+ firstPose->setWeight(0.5f * weightFactor);
+ secondPose->setWeight(0.5f * weightFactor);
+ }
+ else
+ {
+ F32 first_weight = 1.f -
+ ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) /
+ (secondMotion->mParam - firstMotion->mParam));
+ first_weight = llclamp(first_weight, 0.f, 1.f);
+
+ F32 second_weight = 1.f - first_weight;
+
+ firstPose->setWeight(first_weight * weightFactor);
+ secondPose->setWeight(second_weight * weightFactor);
+
+// LL_INFOS() << "Parameter " << *paramName << ": " << *paramValue << LL_ENDL;
+// LL_INFOS() << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << LL_ENDL;
+ }
+ }
+ else if (firstMotion && !secondMotion)
+ {
+ firstPose->setWeight(weightFactor);
+ }
+ }
+
+ // blend poses
+ mPoseBlender.blendAndApply();
+
+ LL_INFOS() << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << LL_ENDL;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam::onDeactivate()
+//-----------------------------------------------------------------------------
+void LLKeyframeMotionParam::onDeactivate()
+{
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+ paramMotion.mMotion->onDeactivate();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam::addKeyframeMotion()
+//-----------------------------------------------------------------------------
+bool LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
+{
+ LLMotion *newMotion = mCharacter->createMotion( id );
+
+ if (!newMotion)
+ {
+ return false;
+ }
+
+ newMotion->setName(name);
+
+ // now add motion to this list
+ mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
+
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLKeyframeMotionParam::setDefaultKeyframeMotion()
+//-----------------------------------------------------------------------------
+void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
+{
+ for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
+ {
+ motion_list_t& motionList = motion_pair.second;
+ for (const ParameterizedMotion& paramMotion : motionList)
+ {
+ if (paramMotion.mMotion->getName() == name)
+ {
+ mDefaultKeyframeMotion = paramMotion.mMotion;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// loadMotions()
+//-----------------------------------------------------------------------------
+bool LLKeyframeMotionParam::loadMotions()
+{
+ //-------------------------------------------------------------------------
+ // Load named file by concatenating the character prefix with the motion name.
+ // Load data into a buffer to be parsed.
+ //-------------------------------------------------------------------------
+ //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
+ // + "_" + getName() + ".llp";
+ //RN: deprecated unused reference to "motion" directory
+ std::string path;
+
+
+ //-------------------------------------------------------------------------
+ // open the file
+ //-------------------------------------------------------------------------
+ S32 fileSize = 0;
+ LLAPRFile infile ;
+ infile.open(path, LL_APR_R, NULL, &fileSize);
+ apr_file_t* fp = infile.getFileHandle() ;
+ if (!fp || fileSize == 0)
+ {
+ LL_INFOS() << "ERROR: can't open: " << path << LL_ENDL;
+ return false;
+ }
+
+ // allocate a text buffer
+ std::vector<char> text(fileSize+1);
+
+ //-------------------------------------------------------------------------
+ // load data from file into buffer
+ //-------------------------------------------------------------------------
+ bool error = false;
+ char *p = &text[0];
+ while ( 1 )
+ {
+ if (apr_file_eof(fp) == APR_EOF)
+ {
+ break;
+ }
+ if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
+ {
+ error = true;
+ break;
+ }
+ while ( *(++p) )
+ ;
+ }
+
+ //-------------------------------------------------------------------------
+ // close the file
+ //-------------------------------------------------------------------------
+ infile.close();
+
+ //-------------------------------------------------------------------------
+ // check for error
+ //-------------------------------------------------------------------------
+ llassert( p <= (&text[0] + fileSize) );
+
+ if ( error )
+ {
+ LL_INFOS() << "ERROR: error while reading from " << path << LL_ENDL;
+ return false;
+ }
+
+ LL_INFOS() << "Loading parametric keyframe data for: " << getName() << LL_ENDL;
+
+ //-------------------------------------------------------------------------
+ // parse the text and build keyframe data structures
+ //-------------------------------------------------------------------------
+ p = &text[0];
+ S32 num;
+ char strA[80]; /* Flawfinder: ignore */
+ char strB[80]; /* Flawfinder: ignore */
+ F32 floatA = 0.0f;
+
+
+ //-------------------------------------------------------------------------
+ // get priority
+ //-------------------------------------------------------------------------
+ bool isFirstMotion = true;
+ num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
+
+ while(1)
+ {
+ if (num == 0 || num == EOF) break;
+ if ((num != 3))
+ {
+ LL_INFOS() << "WARNING: can't read parametric motion" << LL_ENDL;
+ return false;
+ }
+
+ addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA);
+ if (isFirstMotion)
+ {
+ isFirstMotion = false;
+ setDefaultKeyframeMotion(strA);
+ }
+
+ p = strstr(p, "\n");
+ if (!p)
+ {
+ break;
+ }
+
+ p++;
+ num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
+ }
+
+ return true;
+}
+
+// End