00001
00032
00033
00034
00035 #include "linden_common.h"
00036
00037 #include "llheadrotmotion.h"
00038 #include "llcharacter.h"
00039 #include "llrand.h"
00040 #include "m3math.h"
00041 #include "v3dmath.h"
00042 #include "llcriticaldamp.h"
00043
00044
00045
00046
00047 const F32 TORSO_LAG = 0.35f;
00048 const F32 NECK_LAG = 0.5f;
00049 const F32 HEAD_LOOKAT_LAG_HALF_LIFE = 0.15f;
00050 const F32 TORSO_LOOKAT_LAG_HALF_LIFE = 0.27f;
00051 const F32 EYE_LOOKAT_LAG_HALF_LIFE = 0.06f;
00052 const F32 HEAD_ROTATION_CONSTRAINT = F_PI_BY_TWO * 0.8f;
00053
00054 const F32 MIN_HEAD_LOOKAT_DISTANCE = 0.3f;
00055 const F32 MAX_TIME_DELTA = 2.f;
00056 const F32 EYE_JITTER_MIN_TIME = 0.3f;
00057 const F32 EYE_JITTER_MAX_TIME = 2.5f;
00058 const F32 EYE_JITTER_MAX_YAW = 0.08f;
00059 const F32 EYE_JITTER_MAX_PITCH = 0.015f;
00060 const F32 EYE_LOOK_AWAY_MIN_TIME = 5.f;
00061 const F32 EYE_LOOK_AWAY_MAX_TIME = 15.f;
00062 const F32 EYE_LOOK_BACK_MIN_TIME = 1.f;
00063 const F32 EYE_LOOK_BACK_MAX_TIME = 5.f;
00064 const F32 EYE_LOOK_AWAY_MAX_YAW = 0.15f;
00065 const F32 EYE_LOOK_AWAY_MAX_PITCH = 0.12f;
00066 const F32 EYE_ROT_LIMIT_ANGLE = F_PI_BY_TWO * 0.3f;
00067
00068 const F32 EYE_BLINK_MIN_TIME = 0.5f;
00069 const F32 EYE_BLINK_MAX_TIME = 8.f;
00070 const F32 EYE_BLINK_CLOSE_TIME = 0.03f;
00071 const F32 EYE_BLINK_SPEED = 0.015f;
00072 const F32 EYE_BLINK_TIME_DELTA = 0.005f;
00073
00074
00075
00076
00077
00078 LLHeadRotMotion::LLHeadRotMotion(const LLUUID &id) :
00079 LLMotion(id),
00080 mCharacter(NULL),
00081 mTorsoJoint(NULL),
00082 mHeadJoint(NULL)
00083 {
00084 mName = "head_rot";
00085 }
00086
00087
00088
00089
00090
00091
00092 LLHeadRotMotion::~LLHeadRotMotion()
00093 {
00094 }
00095
00096
00097
00098
00099 LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *character)
00100 {
00101 if (!character)
00102 return STATUS_FAILURE;
00103 mCharacter = character;
00104
00105 mPelvisJoint = character->getJoint("mPelvis");
00106 if ( ! mPelvisJoint )
00107 {
00108 llinfos << getName() << ": Can't get pelvis joint." << llendl;
00109 return STATUS_FAILURE;
00110 }
00111
00112 mRootJoint = character->getJoint("mRoot");
00113 if ( ! mRootJoint )
00114 {
00115 llinfos << getName() << ": Can't get root joint." << llendl;
00116 return STATUS_FAILURE;
00117 }
00118
00119 mTorsoJoint = character->getJoint("mTorso");
00120 if ( ! mTorsoJoint )
00121 {
00122 llinfos << getName() << ": Can't get torso joint." << llendl;
00123 return STATUS_FAILURE;
00124 }
00125
00126 mHeadJoint = character->getJoint("mHead");
00127 if ( ! mHeadJoint )
00128 {
00129 llinfos << getName() << ": Can't get head joint." << llendl;
00130 return STATUS_FAILURE;
00131 }
00132
00133 mTorsoState.setJoint( character->getJoint("mTorso") );
00134 if ( ! mTorsoState.getJoint() )
00135 {
00136 llinfos << getName() << ": Can't get torso joint." << llendl;
00137 return STATUS_FAILURE;
00138 }
00139
00140 mNeckState.setJoint( character->getJoint("mNeck") );
00141 if ( ! mNeckState.getJoint() )
00142 {
00143 llinfos << getName() << ": Can't get neck joint." << llendl;
00144 return STATUS_FAILURE;
00145 }
00146
00147 mHeadState.setJoint( character->getJoint("mHead") );
00148 if ( ! mHeadState.getJoint() )
00149 {
00150 llinfos << getName() << ": Can't get head joint." << llendl;
00151 return STATUS_FAILURE;
00152 }
00153
00154 mTorsoState.setUsage(LLJointState::ROT);
00155 mNeckState.setUsage(LLJointState::ROT);
00156 mHeadState.setUsage(LLJointState::ROT);
00157
00158 addJointState( &mTorsoState );
00159 addJointState( &mNeckState );
00160 addJointState( &mHeadState );
00161
00162 mLastHeadRot.loadIdentity();
00163
00164 return STATUS_SUCCESS;
00165 }
00166
00167
00168
00169
00170
00171 BOOL LLHeadRotMotion::onActivate()
00172 {
00173 return TRUE;
00174 }
00175
00176
00177
00178
00179
00180 BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)
00181 {
00182 LLQuaternion targetHeadRotWorld;
00183 LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation();
00184 LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld;
00185
00186 F32 head_slerp_amt = LLCriticalDamp::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE);
00187 F32 torso_slerp_amt = LLCriticalDamp::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE);
00188
00189 LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint");
00190
00191 if (targetPos)
00192 {
00193 LLVector3 headLookAt = *targetPos;
00194
00195
00196
00197 F32 lookatDistance = headLookAt.normVec();
00198
00199 if (lookatDistance < MIN_HEAD_LOOKAT_DISTANCE)
00200 {
00201 targetHeadRotWorld = mPelvisJoint->getWorldRotation();
00202 }
00203 else
00204 {
00205 LLVector3 root_up = LLVector3(0.f, 0.f, 1.f) * currentRootRotWorld;
00206 LLVector3 left(root_up % headLookAt);
00207
00208
00209
00210
00211
00212 if (left.magVecSquared() < 0.15f)
00213 {
00214 LLVector3 root_at = LLVector3(1.f, 0.f, 0.f) * currentRootRotWorld;
00215 root_at.mV[VZ] = 0.f;
00216 root_at.normVec();
00217
00218 headLookAt = lerp(headLookAt, root_at, 0.4f);
00219 headLookAt.normVec();
00220
00221 left = root_up % headLookAt;
00222 }
00223
00224
00225
00226 LLVector3 up(headLookAt % left);
00227
00228 targetHeadRotWorld = LLQuaternion(headLookAt, left, up);
00229 }
00230 }
00231 else
00232 {
00233 targetHeadRotWorld = currentRootRotWorld;
00234 }
00235
00236 LLQuaternion head_rot_local = targetHeadRotWorld * currentInvRootRotWorld;
00237 head_rot_local.constrain(HEAD_ROTATION_CONSTRAINT);
00238
00239
00240
00241
00242 LLQuaternion torso_rot_local = nlerp(TORSO_LAG, LLQuaternion::DEFAULT, head_rot_local );
00243 mTorsoState.setRotation( nlerp(torso_slerp_amt, mTorsoState.getRotation(), torso_rot_local) );
00244
00245 head_rot_local = nlerp(head_slerp_amt, mLastHeadRot, head_rot_local);
00246 mLastHeadRot = head_rot_local;
00247
00248
00249 LLQuaternion torsoRotLocal = mNeckState.getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld;
00250 head_rot_local = head_rot_local * ~torsoRotLocal;
00251 mNeckState.setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) );
00252 mHeadState.setRotation( nlerp(1.f - NECK_LAG, LLQuaternion::DEFAULT, head_rot_local));
00253
00254 return TRUE;
00255 }
00256
00257
00258
00259
00260
00261 void LLHeadRotMotion::onDeactivate()
00262 {
00263 }
00264
00265
00266
00267
00268
00269
00270 LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id)
00271 {
00272 mCharacter = NULL;
00273 mEyeJitterTime = 0.f;
00274 mEyeJitterYaw = 0.f;
00275 mEyeJitterPitch = 0.f;
00276
00277 mEyeLookAwayTime = 0.f;
00278 mEyeLookAwayYaw = 0.f;
00279 mEyeLookAwayPitch = 0.f;
00280
00281 mEyeBlinkTime = 0.f;
00282 mEyesClosed = FALSE;
00283
00284 mHeadJoint = NULL;
00285
00286 mName = "eye_rot";
00287 }
00288
00289
00290
00291
00292
00293
00294 LLEyeMotion::~LLEyeMotion()
00295 {
00296 }
00297
00298
00299
00300
00301 LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character)
00302 {
00303 mCharacter = character;
00304
00305 mHeadJoint = character->getJoint("mHead");
00306 if ( ! mHeadJoint )
00307 {
00308 llinfos << getName() << ": Can't get head joint." << llendl;
00309 return STATUS_FAILURE;
00310 }
00311
00312 mLeftEyeState.setJoint( character->getJoint("mEyeLeft") );
00313 if ( ! mLeftEyeState.getJoint() )
00314 {
00315 llinfos << getName() << ": Can't get left eyeball joint." << llendl;
00316 return STATUS_FAILURE;
00317 }
00318
00319 mRightEyeState.setJoint( character->getJoint("mEyeRight") );
00320 if ( ! mRightEyeState.getJoint() )
00321 {
00322 llinfos << getName() << ": Can't get Right eyeball joint." << llendl;
00323 return STATUS_FAILURE;
00324 }
00325
00326 mLeftEyeState.setUsage(LLJointState::ROT);
00327 mRightEyeState.setUsage(LLJointState::ROT);
00328
00329 addJointState( &mLeftEyeState );
00330 addJointState( &mRightEyeState );
00331
00332 return STATUS_SUCCESS;
00333 }
00334
00335
00336
00337
00338
00339 BOOL LLEyeMotion::onActivate()
00340 {
00341 return TRUE;
00342 }
00343
00344
00345
00346
00347
00348 BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask)
00349 {
00350
00351 LLQuaternion target_eye_rot;
00352 LLVector3 eye_look_at;
00353 F32 vergence;
00354
00355
00356 if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime)
00357 {
00358 mEyeJitterTime = EYE_JITTER_MIN_TIME + ll_frand(EYE_JITTER_MAX_TIME - EYE_JITTER_MIN_TIME);
00359 mEyeJitterYaw = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_YAW;
00360 mEyeJitterPitch = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_PITCH;
00361
00362 mEyeLookAwayTime -= llmax(0.f, mEyeJitterTimer.getElapsedTimeF32());
00363 mEyeJitterTimer.reset();
00364 }
00365 else if (mEyeJitterTimer.getElapsedTimeF32() > mEyeLookAwayTime)
00366 {
00367 if (ll_frand() > 0.1f)
00368 {
00369
00370 mEyeBlinkTime = mEyeBlinkTimer.getElapsedTimeF32();
00371 }
00372 if (mEyeLookAwayYaw == 0.f && mEyeLookAwayPitch == 0.f)
00373 {
00374 mEyeLookAwayYaw = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_YAW;
00375 mEyeLookAwayPitch = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_PITCH;
00376 mEyeLookAwayTime = EYE_LOOK_BACK_MIN_TIME + ll_frand(EYE_LOOK_BACK_MAX_TIME - EYE_LOOK_BACK_MIN_TIME);
00377 }
00378 else
00379 {
00380 mEyeLookAwayYaw = 0.f;
00381 mEyeLookAwayPitch = 0.f;
00382 mEyeLookAwayTime = EYE_LOOK_AWAY_MIN_TIME + ll_frand(EYE_LOOK_AWAY_MAX_TIME - EYE_LOOK_AWAY_MIN_TIME);
00383 }
00384 }
00385
00386
00387 if (!mEyesClosed && mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime)
00388 {
00389 F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime;
00390 F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA;
00391
00392 leftEyeBlinkMorph = llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f);
00393 rightEyeBlinkMorph = llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f);
00394 mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph);
00395 mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph);
00396 mCharacter->updateVisualParams();
00397
00398 if (rightEyeBlinkMorph == 1.f)
00399 {
00400 mEyesClosed = TRUE;
00401 mEyeBlinkTime = EYE_BLINK_CLOSE_TIME;
00402 mEyeBlinkTimer.reset();
00403 }
00404 }
00405 else if (mEyesClosed)
00406 {
00407 if (mEyeBlinkTimer.getElapsedTimeF32() >= mEyeBlinkTime)
00408 {
00409 F32 leftEyeBlinkMorph = mEyeBlinkTimer.getElapsedTimeF32() - mEyeBlinkTime;
00410 F32 rightEyeBlinkMorph = leftEyeBlinkMorph - EYE_BLINK_TIME_DELTA;
00411
00412 leftEyeBlinkMorph = 1.f - llclamp(leftEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f);
00413 rightEyeBlinkMorph = 1.f - llclamp(rightEyeBlinkMorph / EYE_BLINK_SPEED, 0.f, 1.f);
00414 mCharacter->setVisualParamWeight("Blink_Left", leftEyeBlinkMorph);
00415 mCharacter->setVisualParamWeight("Blink_Right", rightEyeBlinkMorph);
00416 mCharacter->updateVisualParams();
00417
00418 if (rightEyeBlinkMorph == 0.f)
00419 {
00420 mEyesClosed = FALSE;
00421 mEyeBlinkTime = EYE_BLINK_MIN_TIME + ll_frand(EYE_BLINK_MAX_TIME - EYE_BLINK_MIN_TIME);
00422 mEyeBlinkTimer.reset();
00423 }
00424 }
00425 }
00426
00427 BOOL has_eye_target = FALSE;
00428 LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint");
00429
00430 if (targetPos)
00431 {
00432 LLVector3 skyward(0.f, 0.f, 1.f);
00433 LLVector3 left;
00434 LLVector3 up;
00435
00436 eye_look_at = *targetPos;
00437 has_eye_target = TRUE;
00438 F32 lookAtDistance = eye_look_at.normVec();
00439
00440 left.setVec(skyward % eye_look_at);
00441 up.setVec(eye_look_at % left);
00442
00443 target_eye_rot = LLQuaternion(eye_look_at, left, up);
00444
00445 target_eye_rot *= ~mHeadJoint->getWorldRotation();
00446
00447 target_eye_rot.constrain(EYE_ROT_LIMIT_ANGLE);
00448
00449
00450 F32 interocular_dist = (mLeftEyeState.getJoint()->getWorldPosition() - mRightEyeState.getJoint()->getWorldPosition()).magVec();
00451 vergence = -atan2((interocular_dist / 2.f), lookAtDistance);
00452 llclamp(vergence, -F_PI_BY_TWO, 0.f);
00453 }
00454 else
00455 {
00456 target_eye_rot = LLQuaternion::DEFAULT;
00457 vergence = 0.f;
00458 }
00459
00460
00461 vergence += 4.f * DEG_TO_RAD;
00462
00463
00464 LLQuaternion eye_jitter_rot;
00465
00466
00467 if (vergence > -0.05f)
00468 {
00469
00470 eye_jitter_rot.setQuat(0.f, mEyeJitterPitch + mEyeLookAwayPitch, mEyeJitterYaw + mEyeLookAwayYaw);
00471 }
00472 else
00473 {
00474
00475 eye_jitter_rot.loadIdentity();
00476 }
00477
00478
00479 LLQuaternion vergence_quat;
00480
00481 if (has_eye_target)
00482 {
00483 vergence_quat.setQuat(vergence, LLVector3(0.f, 0.f, 1.f));
00484 }
00485 else
00486 {
00487 vergence_quat.loadIdentity();
00488 }
00489
00490
00491 LLQuaternion left_eye_rot = target_eye_rot;
00492 left_eye_rot = vergence_quat * eye_jitter_rot * left_eye_rot;
00493
00494 LLQuaternion right_eye_rot = target_eye_rot;
00495 vergence_quat.transQuat();
00496 right_eye_rot = vergence_quat * eye_jitter_rot * right_eye_rot;
00497
00498 mLeftEyeState.setRotation( left_eye_rot );
00499 mRightEyeState.setRotation( right_eye_rot );
00500
00501 return TRUE;
00502 }
00503
00504
00505
00506
00507
00508 void LLEyeMotion::onDeactivate()
00509 {
00510 LLJoint* joint = mLeftEyeState.getJoint();
00511 if (joint)
00512 {
00513 joint->setRotation(LLQuaternion::DEFAULT);
00514 }
00515
00516 joint = mRightEyeState.getJoint();
00517 if (joint)
00518 {
00519 joint->setRotation(LLQuaternion::DEFAULT);
00520 }
00521 }
00522
00523