00001
00032
00033
00034
00035
00036 #include "linden_common.h"
00037
00038 #include "llcharacter.h"
00039 #include "llstring.h"
00040
00041 #define SKEL_HEADER "Linden Skeleton 1.0"
00042
00043 LLStringTable LLCharacter::sVisualParamNames(1024);
00044
00045 std::vector< LLCharacter* > LLCharacter::sInstances;
00046
00047
00048
00049
00050
00051
00052 LLCharacter::LLCharacter()
00053 :
00054 mPreferredPelvisHeight( 0.f ),
00055 mSex( SEX_FEMALE ),
00056 mAppearanceSerialNum( 0 ),
00057 mSkeletonSerialNum( 0 )
00058 {
00059 mMotionController.setCharacter( this );
00060 sInstances.push_back(this);
00061 mPauseRequest = new LLPauseRequestHandle();
00062 }
00063
00064
00065
00066
00067
00068
00069 LLCharacter::~LLCharacter()
00070 {
00071 for (LLVisualParam *param = getFirstVisualParam();
00072 param;
00073 param = getNextVisualParam())
00074 {
00075 delete param;
00076 }
00077 std::vector<LLCharacter*>::iterator iter = std::find(sInstances.begin(), sInstances.end(), this);
00078 if (iter != sInstances.end())
00079 {
00080 sInstances.erase(iter);
00081 }
00082 }
00083
00084
00085
00086
00087
00088 LLJoint *LLCharacter::getJoint( const std::string &name )
00089 {
00090 LLJoint* joint = NULL;
00091
00092 LLJoint *root = getRootJoint();
00093 if (root)
00094 {
00095 joint = root->findJoint(name);
00096 }
00097
00098 if (!joint)
00099 {
00100 llwarns << "Failed to find joint." << llendl;
00101 }
00102 return joint;
00103 }
00104
00105
00106
00107
00108 BOOL LLCharacter::addMotion( const LLUUID& id, LLMotionConstructor create )
00109 {
00110 return mMotionController.addMotion(id, create);
00111 }
00112
00113
00114
00115
00116 void LLCharacter::removeMotion( const LLUUID& id )
00117 {
00118 mMotionController.removeMotion(id);
00119 }
00120
00121
00122
00123
00124 LLMotion* LLCharacter::createMotion( const LLUUID &id )
00125 {
00126 return mMotionController.createMotion( id );
00127 }
00128
00129
00130
00131
00132 BOOL LLCharacter::startMotion(const LLUUID &id, F32 start_offset)
00133 {
00134 return mMotionController.startMotion(id, start_offset);
00135 }
00136
00137
00138
00139
00140
00141 BOOL LLCharacter::stopMotion(const LLUUID& id, BOOL stop_immediate)
00142 {
00143 return mMotionController.stopMotionLocally(id, stop_immediate);
00144 }
00145
00146
00147
00148
00149 BOOL LLCharacter::isMotionActive(const LLUUID& id)
00150 {
00151 LLMotion *motionp = mMotionController.findMotion(id);
00152 if (motionp)
00153 {
00154 return mMotionController.isMotionActive(motionp);
00155 }
00156
00157 return FALSE;
00158 }
00159
00160
00161
00162
00163
00164 void LLCharacter::requestStopMotion( LLMotion* motion)
00165 {
00166
00167 }
00168
00169
00170
00171
00172
00173 void LLCharacter::updateMotion(BOOL force_update)
00174 {
00175
00176
00177
00178 if (mMotionController.isPaused() &&
00179 (force_update || mPauseRequest->getNumRefs() == 1))
00180 {
00181 mMotionController.unpause();
00182 }
00183
00184 mMotionController.updateMotion();
00185
00186
00187
00188 if (force_update && mPauseRequest->getNumRefs() > 1)
00189 {
00190 mMotionController.pause();
00191 }
00192 }
00193
00194
00195
00196
00197
00198 void LLCharacter::deactivateAllMotions()
00199 {
00200 mMotionController.deactivateAllMotions();
00201 }
00202
00203
00204
00205
00206
00207 void LLCharacter::flushAllMotions()
00208 {
00209 mMotionController.flushAllMotions();
00210 }
00211
00212
00213
00214
00215
00216 void LLCharacter::dumpCharacter( LLJoint* joint )
00217 {
00218
00219 if (joint == NULL)
00220 {
00221 llinfos << "DEBUG: Dumping Character @" << this << llendl;
00222 dumpCharacter( getRootJoint() );
00223 llinfos << "DEBUG: Done." << llendl;
00224 return;
00225 }
00226
00227
00228 llinfos << "DEBUG: " << joint->getName() << " (" << (joint->getParent()?joint->getParent()->getName():std::string("ROOT")) << ")" << llendl;
00229
00230
00231 for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
00232 iter != joint->mChildren.end(); ++iter)
00233 {
00234 LLJoint* child_joint = *iter;
00235 dumpCharacter(child_joint);
00236 }
00237 }
00238
00239
00240
00241
00242 void LLCharacter::setAnimationData(std::string name, void *data)
00243 {
00244 mAnimationData[name] = data;
00245 }
00246
00247
00248
00249
00250 void* LLCharacter::getAnimationData(std::string name)
00251 {
00252 return get_if_there(mAnimationData, name, (void*)NULL);
00253 }
00254
00255
00256
00257
00258 void LLCharacter::removeAnimationData(std::string name)
00259 {
00260 mAnimationData.erase(name);
00261 }
00262
00263
00264
00265
00266 BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL set_by_user)
00267 {
00268 S32 index = which_param->getID();
00269 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
00270 if (index_iter != mVisualParamIndexMap.end())
00271 {
00272 index_iter->second->setWeight(weight, set_by_user);
00273 return TRUE;
00274 }
00275 return FALSE;
00276 }
00277
00278
00279
00280
00281 BOOL LLCharacter::setVisualParamWeight(const char* param_name, F32 weight, BOOL set_by_user)
00282 {
00283 LLString tname(param_name);
00284 LLString::toLower(tname);
00285 char *tableptr = sVisualParamNames.checkString(tname);
00286 VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
00287 if (name_iter != mVisualParamNameMap.end())
00288 {
00289 name_iter->second->setWeight(weight, set_by_user);
00290 return TRUE;
00291 }
00292 llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter: " << param_name << llendl;
00293 return FALSE;
00294 }
00295
00296
00297
00298
00299 BOOL LLCharacter::setVisualParamWeight(S32 index, F32 weight, BOOL set_by_user)
00300 {
00301 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
00302 if (index_iter != mVisualParamIndexMap.end())
00303 {
00304 index_iter->second->setWeight(weight, set_by_user);
00305 return TRUE;
00306 }
00307 llwarns << "LLCharacter::setVisualParamWeight() Invalid visual parameter index: " << index << llendl;
00308 return FALSE;
00309 }
00310
00311
00312
00313
00314 F32 LLCharacter::getVisualParamWeight(LLVisualParam *which_param)
00315 {
00316 S32 index = which_param->getID();
00317 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
00318 if (index_iter != mVisualParamIndexMap.end())
00319 {
00320 return index_iter->second->getWeight();
00321 }
00322 else
00323 {
00324 llwarns << "LLCharacter::getVisualParamWeight() Invalid visual parameter*, index= " << index << llendl;
00325 return 0.f;
00326 }
00327 }
00328
00329
00330
00331
00332 F32 LLCharacter::getVisualParamWeight(const char* param_name)
00333 {
00334 LLString tname(param_name);
00335 LLString::toLower(tname);
00336 char *tableptr = sVisualParamNames.checkString(tname);
00337 VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
00338 if (name_iter != mVisualParamNameMap.end())
00339 {
00340 return name_iter->second->getWeight();
00341 }
00342 llwarns << "LLCharacter::getVisualParamWeight() Invalid visual parameter: " << param_name << llendl;
00343 return 0.f;
00344 }
00345
00346
00347
00348
00349 F32 LLCharacter::getVisualParamWeight(S32 index)
00350 {
00351 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
00352 if (index_iter != mVisualParamIndexMap.end())
00353 {
00354 return index_iter->second->getWeight();
00355 }
00356 else
00357 {
00358 llwarns << "LLCharacter::getVisualParamWeight() Invalid visual parameter index: " << index << llendl;
00359 return 0.f;
00360 }
00361 }
00362
00363
00364
00365
00366 void LLCharacter::clearVisualParamWeights()
00367 {
00368 for (LLVisualParam *param = getFirstVisualParam();
00369 param;
00370 param = getNextVisualParam())
00371 {
00372 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
00373 {
00374 param->setWeight( param->getDefaultWeight(), FALSE );
00375 }
00376 }
00377 }
00378
00379
00380
00381
00382 BOOL LLCharacter::visualParamWeightsAreDefault()
00383 {
00384 for (LLVisualParam *param = getFirstVisualParam();
00385 param;
00386 param = getNextVisualParam())
00387 {
00388 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
00389 {
00390 if (param->getWeight() != param->getDefaultWeight())
00391 return false;
00392 }
00393 }
00394
00395 return true;
00396 }
00397
00398
00399
00400
00401
00402
00403 LLVisualParam* LLCharacter::getVisualParam(const char *param_name)
00404 {
00405 LLString tname(param_name);
00406 LLString::toLower(tname);
00407 char *tableptr = sVisualParamNames.checkString(tname);
00408 VisualParamNameMap_t::iterator name_iter = mVisualParamNameMap.find(tableptr);
00409 if (name_iter != mVisualParamNameMap.end())
00410 {
00411 return name_iter->second;
00412 }
00413 llwarns << "LLCharacter::getVisualParam() Invalid visual parameter: " << param_name << llendl;
00414 return NULL;
00415 }
00416
00417
00418
00419
00420 void LLCharacter::addSharedVisualParam(LLVisualParam *param)
00421 {
00422 S32 index = param->getID();
00423 VisualParamIndexMap_t::iterator index_iter = mVisualParamIndexMap.find(index);
00424 LLVisualParam* current_param = 0;
00425 if (index_iter != mVisualParamIndexMap.end())
00426 current_param = index_iter->second;
00427 if( current_param )
00428 {
00429 LLVisualParam* next_param = current_param;
00430 while(next_param->getNextParam())
00431 {
00432 next_param = next_param->getNextParam();
00433 }
00434 next_param->setNextParam(param);
00435 }
00436 else
00437 {
00438 llwarns << "Shared visual parameter " << param->getName() << " does not already exist with ID " <<
00439 param->getID() << llendl;
00440 }
00441 }
00442
00443
00444
00445
00446 void LLCharacter::addVisualParam(LLVisualParam *param)
00447 {
00448 S32 index = param->getID();
00449
00450 std::pair<VisualParamIndexMap_t::iterator, bool> idxres;
00451 idxres = mVisualParamIndexMap.insert(VisualParamIndexMap_t::value_type(index, param));
00452 if (!idxres.second)
00453 {
00454 llwarns << "Visual parameter " << param->getName() << " already exists with same ID as " <<
00455 param->getName() << llendl;
00456 VisualParamIndexMap_t::iterator index_iter = idxres.first;
00457 index_iter->second = param;
00458 }
00459
00460 if (param->getInfo())
00461 {
00462
00463 LLString tname(param->getName());
00464 LLString::toLower(tname);
00465 char *tableptr = sVisualParamNames.addString(tname);
00466 std::pair<VisualParamNameMap_t::iterator, bool> nameres;
00467 nameres = mVisualParamNameMap.insert(VisualParamNameMap_t::value_type(tableptr, param));
00468 if (!nameres.second)
00469 {
00470
00471 VisualParamNameMap_t::iterator name_iter = nameres.first;
00472 name_iter->second = param;
00473 }
00474 }
00475
00476 }
00477
00478
00479
00480
00481 void LLCharacter::updateVisualParams()
00482 {
00483 for (LLVisualParam *param = getFirstVisualParam();
00484 param;
00485 param = getNextVisualParam())
00486 {
00487 if (param->isAnimating())
00488 {
00489 continue;
00490 }
00491
00492 F32 effective_weight = ( param->getSex() & mSex ) ? param->getWeight() : param->getDefaultWeight();
00493 if (effective_weight != param->getLastWeight())
00494 {
00495 param->apply( mSex );
00496 }
00497 }
00498 }
00499
00500 LLAnimPauseRequest LLCharacter::requestPause()
00501 {
00502 mMotionController.pause();
00503 return mPauseRequest;
00504 }
00505