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