//-------------------------------------------------------------------- // setRotation() //-------------------------------------------------------------------- void LLJoint::setRotation( const LLQuaternion& rot ) { if (rot.isFinite()) { // if (mXform.getRotation() != rot) { mXform.setRotation(rot); touch(MATRIX_DIRTY | ROTATION_DIRTY); } } }
//----------------------------------------------------------------------------- // LLEditingMotion::onUpdate() //----------------------------------------------------------------------------- BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask) { LLVector3 focus_pt; LLVector3* pointAtPt = (LLVector3*)mCharacter->getAnimationData("PointAtPoint"); BOOL result = TRUE; if (!pointAtPt) { focus_pt = mLastSelectPt; result = FALSE; } else { focus_pt = *pointAtPt; mLastSelectPt = focus_pt; } focus_pt += mCharacter->getCharacterPosition(); // propagate joint positions to kinematic chain mParentJoint.setPosition( mParentState->getJoint()->getWorldPosition() ); mShoulderJoint.setPosition( mShoulderState->getJoint()->getPosition() ); mElbowJoint.setPosition( mElbowState->getJoint()->getPosition() ); mWristJoint.setPosition( mWristState->getJoint()->getPosition() + mWristOffset ); // propagate current joint rotations to kinematic chain mParentJoint.setRotation( mParentState->getJoint()->getWorldRotation() ); mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() ); mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() ); // update target position from character LLVector3 target = focus_pt - mParentJoint.getPosition(); F32 target_dist = target.normVec(); LLVector3 edit_plane_normal(1.f / F_SQRT2, 1.f / F_SQRT2, 0.f); edit_plane_normal.normVec(); edit_plane_normal.rotVec(mTorsoState->getJoint()->getWorldRotation()); F32 dot = edit_plane_normal * target; if (dot < 0.f) { target = target + (edit_plane_normal * (dot * 2.f)); target.mV[VZ] += clamp_rescale(dot, 0.f, -1.f, 0.f, 5.f); target.normVec(); } target = target * target_dist; if (!target.isFinite()) { LL_WARNS() << "Non finite target in editing motion with target distance of " << target_dist << " and focus point " << focus_pt << " and pointAtPt: "; if (pointAtPt) { LL_CONT << *pointAtPt; } else { LL_CONT << "NULL"; } LL_CONT << LL_ENDL; target.setVec(1.f, 1.f, 1.f); } mTarget.setPosition( target + mParentJoint.getPosition()); // LL_INFOS() << "Point At: " << mTarget.getPosition() << LL_ENDL; // update the ikSolver if (!mTarget.getPosition().isExactlyZero()) { LLQuaternion shoulderRot = mShoulderJoint.getRotation(); LLQuaternion elbowRot = mElbowJoint.getRotation(); mIKSolver.solve(); // use blending... F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE); shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot); elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); // now put blended values back into joints llassert(shoulderRot.isFinite()); llassert(elbowRot.isFinite()); mShoulderState->setRotation(shoulderRot); mElbowState->setRotation(elbowRot); mWristState->setRotation(LLQuaternion::DEFAULT); } mCharacter->setAnimationData("Hand Pose", &sHandPose); mCharacter->setAnimationData("Hand Pose Priority", &sHandPosePriority); return result; }