/indra/llcharacter/llpose.cpp
C++ | 567 lines | 365 code | 71 blank | 131 comment | 60 complexity | e4336015c98eca10c63f1a70e4653200 MD5 | raw file
Possible License(s): LGPL-2.1
1/** 2 * @file llpose.cpp 3 * @brief Implementation of LLPose class. 4 * 5 * $LicenseInfo:firstyear=2001&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 27//----------------------------------------------------------------------------- 28// Header Files 29//----------------------------------------------------------------------------- 30#include "linden_common.h" 31 32#include "llpose.h" 33 34#include "llmotion.h" 35#include "llmath.h" 36#include "llstl.h" 37 38//----------------------------------------------------------------------------- 39// Static 40//----------------------------------------------------------------------------- 41 42//----------------------------------------------------------------------------- 43// LLPose 44//----------------------------------------------------------------------------- 45LLPose::~LLPose() 46{ 47} 48 49//----------------------------------------------------------------------------- 50// getFirstJointState() 51//----------------------------------------------------------------------------- 52LLJointState* LLPose::getFirstJointState() 53{ 54 mListIter = mJointMap.begin(); 55 if (mListIter == mJointMap.end()) 56 { 57 return NULL; 58 } 59 else 60 { 61 return mListIter->second; 62 } 63} 64 65//----------------------------------------------------------------------------- 66// getNextJointState() 67//----------------------------------------------------------------------------- 68LLJointState *LLPose::getNextJointState() 69{ 70 mListIter++; 71 if (mListIter == mJointMap.end()) 72 { 73 return NULL; 74 } 75 else 76 { 77 return mListIter->second; 78 } 79} 80 81//----------------------------------------------------------------------------- 82// addJointState() 83//----------------------------------------------------------------------------- 84BOOL LLPose::addJointState(const LLPointer<LLJointState>& jointState) 85{ 86 if (mJointMap.find(jointState->getJoint()->getName()) == mJointMap.end()) 87 { 88 mJointMap[jointState->getJoint()->getName()] = jointState; 89 } 90 return TRUE; 91} 92 93//----------------------------------------------------------------------------- 94// removeJointState() 95//----------------------------------------------------------------------------- 96BOOL LLPose::removeJointState(const LLPointer<LLJointState>& jointState) 97{ 98 mJointMap.erase(jointState->getJoint()->getName()); 99 return TRUE; 100} 101 102//----------------------------------------------------------------------------- 103// removeAllJointStates() 104//----------------------------------------------------------------------------- 105BOOL LLPose::removeAllJointStates() 106{ 107 mJointMap.clear(); 108 return TRUE; 109} 110 111//----------------------------------------------------------------------------- 112// findJointState() 113//----------------------------------------------------------------------------- 114LLJointState* LLPose::findJointState(LLJoint *joint) 115{ 116 joint_map_iterator iter = mJointMap.find(joint->getName()); 117 118 if (iter == mJointMap.end()) 119 { 120 return NULL; 121 } 122 else 123 { 124 return iter->second; 125 } 126} 127 128//----------------------------------------------------------------------------- 129// findJointState() 130//----------------------------------------------------------------------------- 131LLJointState* LLPose::findJointState(const std::string &name) 132{ 133 joint_map_iterator iter = mJointMap.find(name); 134 135 if (iter == mJointMap.end()) 136 { 137 return NULL; 138 } 139 else 140 { 141 return iter->second; 142 } 143} 144 145//----------------------------------------------------------------------------- 146// setWeight() 147//----------------------------------------------------------------------------- 148void LLPose::setWeight(F32 weight) 149{ 150 joint_map_iterator iter; 151 for(iter = mJointMap.begin(); 152 iter != mJointMap.end(); 153 ++iter) 154 { 155 iter->second->setWeight(weight); 156 } 157 mWeight = weight; 158} 159 160//----------------------------------------------------------------------------- 161// getWeight() 162//----------------------------------------------------------------------------- 163F32 LLPose::getWeight() const 164{ 165 return mWeight; 166} 167 168//----------------------------------------------------------------------------- 169// getNumJointStates() 170//----------------------------------------------------------------------------- 171S32 LLPose::getNumJointStates() const 172{ 173 return (S32)mJointMap.size(); 174} 175 176//----------------------------------------------------------------------------- 177// LLJointStateBlender 178//----------------------------------------------------------------------------- 179 180LLJointStateBlender::LLJointStateBlender() 181{ 182 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) 183 { 184 mJointStates[i] = NULL; 185 mPriorities[i] = S32_MIN; 186 mAdditiveBlends[i] = FALSE; 187 } 188} 189 190LLJointStateBlender::~LLJointStateBlender() 191{ 192 193} 194 195//----------------------------------------------------------------------------- 196// addJointState() 197//----------------------------------------------------------------------------- 198BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend) 199{ 200 llassert(joint_state); 201 202 if (!joint_state->getJoint()) 203 // this joint state doesn't point to an actual joint, so we don't care about applying it 204 return FALSE; 205 206 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) 207 { 208 if (mJointStates[i].isNull()) 209 { 210 mJointStates[i] = joint_state; 211 mPriorities[i] = priority; 212 mAdditiveBlends[i] = additive_blend; 213 return TRUE; 214 } 215 else if (priority > mPriorities[i]) 216 { 217 // we're at a higher priority than the current joint state in this slot 218 // so shift everyone over 219 // previous joint states (newer motions) with same priority should stay in place 220 for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--) 221 { 222 mJointStates[j] = mJointStates[j - 1]; 223 mPriorities[j] = mPriorities[j - 1]; 224 mAdditiveBlends[j] = mAdditiveBlends[j - 1]; 225 } 226 // now store ourselves in this slot 227 mJointStates[i] = joint_state; 228 mPriorities[i] = priority; 229 mAdditiveBlends[i] = additive_blend; 230 return TRUE; 231 } 232 } 233 234 return FALSE; 235} 236 237//----------------------------------------------------------------------------- 238// blendJointStates() 239//----------------------------------------------------------------------------- 240void LLJointStateBlender::blendJointStates(BOOL apply_now) 241{ 242 // we need at least one joint to blend 243 // if there is one, it will be in slot zero according to insertion logic 244 // instead of resetting joint state to default, just leave it unchanged from last frame 245 if (mJointStates[0].isNull()) 246 { 247 return; 248 } 249 250 LLJoint* target_joint = apply_now ? mJointStates[0]->getJoint() : &mJointCache; 251 252 const S32 POS_WEIGHT = 0; 253 const S32 ROT_WEIGHT = 1; 254 const S32 SCALE_WEIGHT = 2; 255 256 F32 sum_weights[3]; 257 U32 sum_usage = 0; 258 259 LLVector3 blended_pos = target_joint->getPosition(); 260 LLQuaternion blended_rot = target_joint->getRotation(); 261 LLVector3 blended_scale = target_joint->getScale(); 262 263 LLVector3 added_pos; 264 LLQuaternion added_rot; 265 LLVector3 added_scale; 266 267 //S32 joint_state_index; 268 269 sum_weights[POS_WEIGHT] = 0.f; 270 sum_weights[ROT_WEIGHT] = 0.f; 271 sum_weights[SCALE_WEIGHT] = 0.f; 272 273 for(S32 joint_state_index = 0; 274 joint_state_index < JSB_NUM_JOINT_STATES && mJointStates[joint_state_index].notNull(); 275 joint_state_index++) 276 { 277 LLJointState* jsp = mJointStates[joint_state_index]; 278 U32 current_usage = jsp->getUsage(); 279 F32 current_weight = jsp->getWeight(); 280 281 if (current_weight == 0.f) 282 { 283 continue; 284 } 285 286 if (mAdditiveBlends[joint_state_index]) 287 { 288 if(current_usage & LLJointState::POS) 289 { 290 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); 291 292 // add in pos for this jointstate modulated by weight 293 added_pos += jsp->getPosition() * (new_weight_sum - sum_weights[POS_WEIGHT]); 294 } 295 296 if(current_usage & LLJointState::SCALE) 297 { 298 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); 299 300 // add in scale for this jointstate modulated by weight 301 added_scale += jsp->getScale() * (new_weight_sum - sum_weights[SCALE_WEIGHT]); 302 } 303 304 if (current_usage & LLJointState::ROT) 305 { 306 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); 307 308 // add in rotation for this jointstate modulated by weight 309 added_rot = nlerp((new_weight_sum - sum_weights[ROT_WEIGHT]), added_rot, jsp->getRotation()) * added_rot; 310 } 311 } 312 else 313 { 314 // blend two jointstates together 315 316 // blend position 317 if(current_usage & LLJointState::POS) 318 { 319 if(sum_usage & LLJointState::POS) 320 { 321 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[POS_WEIGHT]); 322 323 // blend positions from both 324 blended_pos = lerp(jsp->getPosition(), blended_pos, sum_weights[POS_WEIGHT] / new_weight_sum); 325 sum_weights[POS_WEIGHT] = new_weight_sum; 326 } 327 else 328 { 329 // copy position from current 330 blended_pos = jsp->getPosition(); 331 sum_weights[POS_WEIGHT] = current_weight; 332 } 333 } 334 335 // now do scale 336 if(current_usage & LLJointState::SCALE) 337 { 338 if(sum_usage & LLJointState::SCALE) 339 { 340 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[SCALE_WEIGHT]); 341 342 // blend scales from both 343 blended_scale = lerp(jsp->getScale(), blended_scale, sum_weights[SCALE_WEIGHT] / new_weight_sum); 344 sum_weights[SCALE_WEIGHT] = new_weight_sum; 345 } 346 else 347 { 348 // copy scale from current 349 blended_scale = jsp->getScale(); 350 sum_weights[SCALE_WEIGHT] = current_weight; 351 } 352 } 353 354 // rotation 355 if (current_usage & LLJointState::ROT) 356 { 357 if(sum_usage & LLJointState::ROT) 358 { 359 F32 new_weight_sum = llmin(1.f, current_weight + sum_weights[ROT_WEIGHT]); 360 361 // blend rotations from both 362 blended_rot = nlerp(sum_weights[ROT_WEIGHT] / new_weight_sum, jsp->getRotation(), blended_rot); 363 sum_weights[ROT_WEIGHT] = new_weight_sum; 364 } 365 else 366 { 367 // copy rotation from current 368 blended_rot = jsp->getRotation(); 369 sum_weights[ROT_WEIGHT] = current_weight; 370 } 371 } 372 373 // update resulting usage mask 374 sum_usage = sum_usage | current_usage; 375 } 376 } 377 378 if (!added_scale.isFinite()) 379 { 380 added_scale.clearVec(); 381 } 382 383 if (!blended_scale.isFinite()) 384 { 385 blended_scale.setVec(1,1,1); 386 } 387 388 // apply transforms 389 target_joint->setPosition(blended_pos + added_pos); 390 target_joint->setScale(blended_scale + added_scale); 391 target_joint->setRotation(added_rot * blended_rot); 392 393 if (apply_now) 394 { 395 // now clear joint states 396 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) 397 { 398 mJointStates[i] = NULL; 399 } 400 } 401} 402 403//----------------------------------------------------------------------------- 404// interpolate() 405//----------------------------------------------------------------------------- 406void LLJointStateBlender::interpolate(F32 u) 407{ 408 // only interpolate if we have a joint state 409 if (!mJointStates[0]) 410 { 411 return; 412 } 413 LLJoint* target_joint = mJointStates[0]->getJoint(); 414 415 if (!target_joint) 416 { 417 return; 418 } 419 420 target_joint->setPosition(lerp(target_joint->getPosition(), mJointCache.getPosition(), u)); 421 target_joint->setScale(lerp(target_joint->getScale(), mJointCache.getScale(), u)); 422 target_joint->setRotation(nlerp(u, target_joint->getRotation(), mJointCache.getRotation())); 423} 424 425//----------------------------------------------------------------------------- 426// clear() 427//----------------------------------------------------------------------------- 428void LLJointStateBlender::clear() 429{ 430 // now clear joint states 431 for(S32 i = 0; i < JSB_NUM_JOINT_STATES; i++) 432 { 433 mJointStates[i] = NULL; 434 } 435} 436 437//----------------------------------------------------------------------------- 438// resetCachedJoint() 439//----------------------------------------------------------------------------- 440void LLJointStateBlender::resetCachedJoint() 441{ 442 if (!mJointStates[0]) 443 { 444 return; 445 } 446 LLJoint* source_joint = mJointStates[0]->getJoint(); 447 mJointCache.setPosition(source_joint->getPosition()); 448 mJointCache.setScale(source_joint->getScale()); 449 mJointCache.setRotation(source_joint->getRotation()); 450} 451 452//----------------------------------------------------------------------------- 453// LLPoseBlender 454//----------------------------------------------------------------------------- 455 456LLPoseBlender::LLPoseBlender() 457 : mNextPoseSlot(0) 458{ 459} 460 461LLPoseBlender::~LLPoseBlender() 462{ 463 for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer()); 464} 465 466//----------------------------------------------------------------------------- 467// addMotion() 468//----------------------------------------------------------------------------- 469BOOL LLPoseBlender::addMotion(LLMotion* motion) 470{ 471 LLPose* pose = motion->getPose(); 472 473 for(LLJointState* jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState()) 474 { 475 LLJoint *jointp = jsp->getJoint(); 476 LLJointStateBlender* joint_blender; 477 if (mJointStateBlenderPool.find(jointp) == mJointStateBlenderPool.end()) 478 { 479 // this is the first time we are animating this joint 480 // so create new jointblender and add it to our pool 481 joint_blender = new LLJointStateBlender(); 482 mJointStateBlenderPool[jointp] = joint_blender; 483 } 484 else 485 { 486 joint_blender = mJointStateBlenderPool[jointp]; 487 } 488 489 if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY) 490 { 491 joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND); 492 } 493 else 494 { 495 joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND); 496 } 497 498 // add it to our list of active blenders 499 if (std::find(mActiveBlenders.begin(), mActiveBlenders.end(), joint_blender) == mActiveBlenders.end()) 500 { 501 mActiveBlenders.push_front(joint_blender); 502 } 503 } 504 return TRUE; 505} 506 507//----------------------------------------------------------------------------- 508// blendAndApply() 509//----------------------------------------------------------------------------- 510void LLPoseBlender::blendAndApply() 511{ 512 for (blender_list_t::iterator iter = mActiveBlenders.begin(); 513 iter != mActiveBlenders.end(); ) 514 { 515 LLJointStateBlender* jsbp = *iter++; 516 jsbp->blendJointStates(); 517 } 518 519 // we're done now so there are no more active blenders for this frame 520 mActiveBlenders.clear(); 521} 522 523//----------------------------------------------------------------------------- 524// blendAndCache() 525//----------------------------------------------------------------------------- 526void LLPoseBlender::blendAndCache(BOOL reset_cached_joints) 527{ 528 for (blender_list_t::iterator iter = mActiveBlenders.begin(); 529 iter != mActiveBlenders.end(); ++iter) 530 { 531 LLJointStateBlender* jsbp = *iter; 532 if (reset_cached_joints) 533 { 534 jsbp->resetCachedJoint(); 535 } 536 jsbp->blendJointStates(FALSE); 537 } 538} 539 540//----------------------------------------------------------------------------- 541// interpolate() 542//----------------------------------------------------------------------------- 543void LLPoseBlender::interpolate(F32 u) 544{ 545 for (blender_list_t::iterator iter = mActiveBlenders.begin(); 546 iter != mActiveBlenders.end(); ++iter) 547 { 548 LLJointStateBlender* jsbp = *iter; 549 jsbp->interpolate(u); 550 } 551} 552 553//----------------------------------------------------------------------------- 554// clearBlenders() 555//----------------------------------------------------------------------------- 556void LLPoseBlender::clearBlenders() 557{ 558 for (blender_list_t::iterator iter = mActiveBlenders.begin(); 559 iter != mActiveBlenders.end(); ++iter) 560 { 561 LLJointStateBlender* jsbp = *iter; 562 jsbp->clear(); 563 } 564 565 mActiveBlenders.clear(); 566} 567