//static void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks) { GLint* viewport = (GLint*) gGLViewport; GLdouble* model = gGLModelView; GLdouble* proj = gGLProjection; GLdouble objX,objY,objZ; LLVector3 frust[8]; if (no_hacks) { gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); } else if (zflip) { gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i+4]-frust[i]; frust[i+4].normVec(); frust[i+4] = frust[i] + frust[i+4]*camera.getFar(); } } else { gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); if (ortho) { LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f; for (U32 i = 0; i < 4; i++) { frust[i+4] = frust[i] + far_shift; } } else { for (U32 i = 0; i < 4; i++) { LLVector3 vec = frust[i] - camera.getOrigin(); vec.normVec(); frust[i+4] = camera.getOrigin() + vec*camera.getFar(); } } } camera.calcAgentFrustumPlanes(frust); }
//----------------------------------------------------------------------------- // LLHeadRotMotion::onUpdate() //----------------------------------------------------------------------------- BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask) { LLQuaternion targetHeadRotWorld; LLQuaternion currentRootRotWorld = mRootJoint->getWorldRotation(); LLQuaternion currentInvRootRotWorld = ~currentRootRotWorld; F32 head_slerp_amt = LLCriticalDamp::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE); F32 torso_slerp_amt = LLCriticalDamp::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE); LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); if (targetPos) { LLVector3 headLookAt = *targetPos; // llinfos << "Look At: " << headLookAt + mHeadJoint->getWorldPosition() << llendl; F32 lookatDistance = headLookAt.normVec(); if (lookatDistance < MIN_HEAD_LOOKAT_DISTANCE) { targetHeadRotWorld = mPelvisJoint->getWorldRotation(); } else { LLVector3 root_up = LLVector3(0.f, 0.f, 1.f) * currentRootRotWorld; LLVector3 left(root_up % headLookAt); // if look_at has zero length, fail // if look_at and skyward are parallel, fail // // Test both of these conditions with a cross product. if (left.magVecSquared() < 0.15f) { LLVector3 root_at = LLVector3(1.f, 0.f, 0.f) * currentRootRotWorld; root_at.mV[VZ] = 0.f; root_at.normVec(); headLookAt = lerp(headLookAt, root_at, 0.4f); headLookAt.normVec(); left = root_up % headLookAt; } // Make sure look_at and skyward and not parallel // and neither are zero length LLVector3 up(headLookAt % left); targetHeadRotWorld = LLQuaternion(headLookAt, left, up); } } else { targetHeadRotWorld = currentRootRotWorld; } LLQuaternion head_rot_local = targetHeadRotWorld * currentInvRootRotWorld; head_rot_local.constrain(HEAD_ROTATION_CONSTRAINT); // set final torso rotation // Set torso target rotation such that it lags behind the head rotation // by a fixed amount. LLQuaternion torso_rot_local = nlerp(TORSO_LAG, LLQuaternion::DEFAULT, head_rot_local ); mTorsoState->setRotation( nlerp(torso_slerp_amt, mTorsoState->getRotation(), torso_rot_local) ); head_rot_local = nlerp(head_slerp_amt, mLastHeadRot, head_rot_local); mLastHeadRot = head_rot_local; if(mNeckState->getJoint() && mNeckState->getJoint()->getParent()) //Guess this has crashed? Taken from snowglobe -Shyotl { // Set the head rotation. LLQuaternion torsoRotLocal = mNeckState->getJoint()->getParent()->getWorldRotation() * currentInvRootRotWorld; head_rot_local = head_rot_local * ~torsoRotLocal; mNeckState->setRotation( nlerp(NECK_LAG, LLQuaternion::DEFAULT, head_rot_local) ); mHeadState->setRotation( nlerp(1.f - NECK_LAG, LLQuaternion::DEFAULT, head_rot_local)); } return TRUE; }