00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include "llkeyframemotionparam.h"
00038 #include "llcharacter.h"
00039 #include "llmath.h"
00040 #include "m3math.h"
00041 #include "lldir.h"
00042 #include "llanimationstates.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
00055 {
00056 mDefaultKeyframeMotion = NULL;
00057 mCharacter = NULL;
00058
00059 mEaseInDuration = 0.f;
00060 mEaseOutDuration = 0.f;
00061 mDuration = 0.f;
00062 mPriority = LLJoint::LOW_PRIORITY;
00063 }
00064
00065
00066
00067
00068
00069
00070 LLKeyframeMotionParam::~LLKeyframeMotionParam()
00071 {
00072 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00073 iter != mParameterizedMotions.end(); ++iter)
00074 {
00075 motion_list_t& motionList = iter->second;
00076 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00077 {
00078 const ParameterizedMotion& paramMotion = *iter2;
00079 delete paramMotion.first;
00080 }
00081 motionList.clear();
00082 }
00083 mParameterizedMotions.clear();
00084 }
00085
00086
00087
00088
00089 LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
00090 {
00091 mCharacter = character;
00092
00093 if (!loadMotions())
00094 {
00095 return STATUS_FAILURE;
00096 }
00097
00098 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00099 iter != mParameterizedMotions.end(); ++iter)
00100 {
00101 motion_list_t& motionList = iter->second;
00102 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00103 {
00104 const ParameterizedMotion& paramMotion = *iter2;
00105
00106 paramMotion.first->onInitialize(character);
00107
00108 if (paramMotion.first->getDuration() > mEaseInDuration)
00109 {
00110 mEaseInDuration = paramMotion.first->getEaseInDuration();
00111 }
00112
00113 if (paramMotion.first->getEaseOutDuration() > mEaseOutDuration)
00114 {
00115 mEaseOutDuration = paramMotion.first->getEaseOutDuration();
00116 }
00117
00118 if (paramMotion.first->getDuration() > mDuration)
00119 {
00120 mDuration = paramMotion.first->getDuration();
00121 }
00122
00123 if (paramMotion.first->getPriority() > mPriority)
00124 {
00125 mPriority = paramMotion.first->getPriority();
00126 }
00127
00128 LLPose *pose = paramMotion.first->getPose();
00129
00130 mPoseBlender.addMotion(paramMotion.first);
00131 for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
00132 {
00133 LLPose *blendedPose = mPoseBlender.getBlendedPose();
00134 blendedPose->addJointState(jsp);
00135 }
00136 }
00137 }
00138
00139 return STATUS_SUCCESS;
00140 }
00141
00142
00143
00144
00145 BOOL LLKeyframeMotionParam::onActivate()
00146 {
00147 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00148 iter != mParameterizedMotions.end(); ++iter)
00149 {
00150 motion_list_t& motionList = iter->second;
00151 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00152 {
00153 const ParameterizedMotion& paramMotion = *iter2;
00154 paramMotion.first->activate();
00155 }
00156 }
00157 return TRUE;
00158 }
00159
00160
00161
00162
00163
00164 BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
00165 {
00166 F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
00167
00168
00169 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00170 iter != mParameterizedMotions.end(); ++iter)
00171 {
00172 motion_list_t& motionList = iter->second;
00173 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00174 {
00175 const ParameterizedMotion& paramMotion = *iter2;
00176
00177 paramMotion.first->getPose()->setWeight(0.f);
00178 }
00179 }
00180
00181
00182 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00183 iter != mParameterizedMotions.end(); ++iter)
00184 {
00185 const std::string& paramName = iter->first;
00186 F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
00187 if (NULL == paramValue)
00188 {
00189 llwarns << "paramValue == NULL" << llendl;
00190 continue;
00191 }
00192
00193 const ParameterizedMotion* firstMotion = NULL;
00194 const ParameterizedMotion* secondMotion = NULL;
00195
00196 motion_list_t& motionList = iter->second;
00197 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00198 {
00199 const ParameterizedMotion& paramMotion = *iter2;
00200 paramMotion.first->onUpdate(time, joint_mask);
00201
00202 F32 distToParam = paramMotion.second - *paramValue;
00203
00204 if ( distToParam <= 0.f)
00205 {
00206
00207 firstMotion = ¶mMotion;
00208 }
00209 else
00210 {
00211
00212
00213 if (firstMotion && !secondMotion )
00214 {
00215 secondMotion = ¶mMotion;
00216 }
00217
00218 else if (!firstMotion)
00219 {
00220 firstMotion = ¶mMotion;
00221 secondMotion = ¶mMotion;
00222 }
00223 }
00224 }
00225
00226 LLPose *firstPose;
00227 LLPose *secondPose;
00228
00229 if (firstMotion)
00230 firstPose = firstMotion->first->getPose();
00231 else
00232 firstPose = NULL;
00233
00234 if (secondMotion)
00235 secondPose = secondMotion->first->getPose();
00236 else
00237 secondPose = NULL;
00238
00239
00240 if (firstMotion && secondMotion)
00241 {
00242 if (firstMotion == secondMotion)
00243 {
00244 firstPose->setWeight(weightFactor);
00245 }
00246 else if (firstMotion->second == secondMotion->second)
00247 {
00248 firstPose->setWeight(0.5f * weightFactor);
00249 secondPose->setWeight(0.5f * weightFactor);
00250 }
00251 else
00252 {
00253 F32 first_weight = 1.f -
00254 ((llclamp(*paramValue - firstMotion->second, 0.f, (secondMotion->second - firstMotion->second))) /
00255 (secondMotion->second - firstMotion->second));
00256 first_weight = llclamp(first_weight, 0.f, 1.f);
00257
00258 F32 second_weight = 1.f - first_weight;
00259
00260 firstPose->setWeight(first_weight * weightFactor);
00261 secondPose->setWeight(second_weight * weightFactor);
00262
00263
00264
00265 }
00266 }
00267 else if (firstMotion && !secondMotion)
00268 {
00269 firstPose->setWeight(weightFactor);
00270 }
00271 }
00272
00273
00274 mPoseBlender.blendAndApply();
00275
00276 llinfos << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << llendl;
00277
00278 return TRUE;
00279 }
00280
00281
00282
00283
00284 void LLKeyframeMotionParam::onDeactivate()
00285 {
00286 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00287 iter != mParameterizedMotions.end(); ++iter)
00288 {
00289 motion_list_t& motionList = iter->second;
00290 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00291 {
00292 const ParameterizedMotion& paramMotion = *iter2;
00293 paramMotion.first->onDeactivate();
00294 }
00295 }
00296 }
00297
00298
00299
00300
00301 BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
00302 {
00303 LLMotion *newMotion = mCharacter->createMotion( id );
00304
00305 if (!newMotion)
00306 {
00307 return FALSE;
00308 }
00309
00310 newMotion->setName(name);
00311
00312
00313 mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
00314
00315 return TRUE;
00316 }
00317
00318
00319
00320
00321
00322 void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
00323 {
00324 for (motion_map_t::iterator iter = mParameterizedMotions.begin();
00325 iter != mParameterizedMotions.end(); ++iter)
00326 {
00327 motion_list_t& motionList = iter->second;
00328 for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
00329 {
00330 const ParameterizedMotion& paramMotion = *iter2;
00331 if (paramMotion.first->getName() == name)
00332 {
00333 mDefaultKeyframeMotion = paramMotion.first;
00334 }
00335 }
00336 }
00337 }
00338
00339
00340
00341
00342 BOOL LLKeyframeMotionParam::loadMotions()
00343 {
00344
00345
00346
00347
00348 char path[LL_MAX_PATH];
00349 snprintf( path,sizeof(path), "%s_%s.llp",
00350 gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix()).c_str(),
00351 getName().c_str() );
00352
00353
00354
00355
00356 S32 fileSize = 0;
00357 apr_file_t* fp = ll_apr_file_open(path, LL_APR_R, &fileSize);
00358 if (!fp || fileSize == 0)
00359 {
00360 llinfos << "ERROR: can't open: " << path << llendl;
00361 return FALSE;
00362 }
00363
00364
00365 char *text = new char[ fileSize+1 ];
00366 if ( !text )
00367 {
00368 llinfos << "ERROR: can't allocated keyframe text buffer." << llendl;
00369 apr_file_close(fp);
00370 return FALSE;
00371 }
00372
00373
00374
00375
00376 bool error = false;
00377 char *p = text;
00378 while ( 1 )
00379 {
00380 if (apr_file_eof(fp) == APR_EOF)
00381 {
00382 break;
00383 }
00384 if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
00385 {
00386 error = true;
00387 break;
00388 }
00389 while ( *(++p) )
00390 ;
00391 }
00392
00393
00394
00395
00396 apr_file_close( fp );
00397
00398
00399
00400
00401 llassert( p <= (text+fileSize) );
00402
00403 if ( error )
00404 {
00405 llinfos << "ERROR: error while reading from " << path << llendl;
00406 delete [] text;
00407 return FALSE;
00408 }
00409
00410 llinfos << "Loading parametric keyframe data for: " << getName() << llendl;
00411
00412
00413
00414
00415 p = text;
00416 S32 num;
00417 char strA[80];
00418 char strB[80];
00419 F32 floatA = 0.0f;
00420
00421
00422
00423
00424
00425 BOOL isFirstMotion = TRUE;
00426 num = sscanf(p, "%79s %79s %f", strA, strB, &floatA);
00427
00428 while(1)
00429 {
00430 if (num == 0 || num == EOF) break;
00431 if ((num != 3))
00432 {
00433 llinfos << "WARNING: can't read parametric motion" << llendl;
00434 delete [] text;
00435 return FALSE;
00436 }
00437
00438 addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(strA), strB, floatA);
00439 if (isFirstMotion)
00440 {
00441 isFirstMotion = FALSE;
00442 setDefaultKeyframeMotion(strA);
00443 }
00444
00445 p = strstr(p, "\n");
00446 if (!p)
00447 {
00448 break;
00449 }
00450
00451 p++;
00452 num = sscanf(p, "%79s %79s %f", strA, strB, &floatA);
00453 }
00454
00455 delete [] text;
00456 return TRUE;
00457 }
00458
00459