void lggBeamMaps::fireCurrentBeams(LLPointer<LLHUDEffectSpiral> mBeam, const LLColor4U& rgb) { if (mScale == 0.0f) { return; } static LLCachedControl<std::string> colorf(gSavedSettings, "FSBeamColorFile"); bool colorsDisabled = (colorf().empty()); for (std::vector<lggBeamData>::iterator it = mDots.begin(); it != mDots.end(); ++it) { LLColor4U myColor = rgb; if (colorsDisabled) { myColor = (*it).c; } F32 distanceAdjust = dist_vec(mBeam->getPositionGlobal(), gAgent.getPositionGlobal()); F32 pulse = (F32)(.75f + sinf(gFrameTimeSeconds * 1.0f) * 0.25f); LLVector3d offset = (*it).p; offset.mdV[VY] *= -1.f; offset *= pulse * mScale * distanceAdjust * 0.1f; LLVector3 beamLine = LLVector3( mBeam->getPositionGlobal() - gAgent.getPositionGlobal()); LLVector3 beamLineFlat = beamLine; beamLineFlat.mV[VZ]= 0.0f; LLVector3 newDirFlat = LLVector3::x_axis; beamLine.normalize(); beamLineFlat.normalize(); LLQuaternion change; change.shortestArc(newDirFlat, beamLineFlat); offset.rotVec(change); newDirFlat.rotVec(change); change.shortestArc(newDirFlat, beamLine); offset.rotVec(change); LLPointer<LLHUDEffectSpiral> myBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); myBeam->setPositionGlobal(mBeam->getPositionGlobal() + offset + (LLVector3d(beamLine) * sinf(gFrameTimeSeconds * 2.0f) * 0.2f)); myBeam->setColor(myColor); myBeam->setTargetObject(mBeam->getTargetObject()); myBeam->setSourceObject(mBeam->getSourceObject()); myBeam->setNeedsSendToSim(mBeam->getNeedsSendToSim()); myBeam->setDuration(mDuration * 1.2f); } }
void lggBeamMaps::fireCurrentBeams(LLPointer<LLHUDEffectSpiral> mBeam, LLColor4U rgb) { if (scale == 0.0f) { return; } static LLCachedControl<std::string> colorf(gSavedSettings, "FSBeamColorFile"); bool colorsDisabled = std::string(colorf) == "===OFF==="; for(int i = 0; i < (int)dots.size(); i++) { LLColor4U myColor = rgb; if (colorsDisabled) myColor = dots[i].c; F32 distanceAdjust = dist_vec(mBeam->getPositionGlobal(),gAgent.getPositionGlobal()) ; F32 pulse = (F32)(.75f+sinf(gFrameTimeSeconds*1.0f)*0.25f); LLVector3d offset = dots[i].p; offset.mdV[VY] *= -1; offset *= pulse * scale * distanceAdjust * 0.1; //llinfos << "dist is " << distanceAdjust << "scale is " << scale << llendl; LLVector3 beamLine = LLVector3( mBeam->getPositionGlobal() - gAgent.getPositionGlobal()); LLVector3 beamLineFlat = beamLine; beamLineFlat.mV[VZ]= 0.0f; LLVector3 newDirFlat = LLVector3::x_axis; beamLine.normalize(); beamLineFlat.normalize(); LLQuaternion change; change.shortestArc(newDirFlat,beamLineFlat); offset.rotVec(change); newDirFlat.rotVec(change); change.shortestArc(newDirFlat,beamLine); offset.rotVec(change); LLPointer<LLHUDEffectSpiral> myBeam = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); myBeam->setPositionGlobal(mBeam->getPositionGlobal() + offset + (LLVector3d(beamLine) * sinf(gFrameTimeSeconds*2.0f) * 0.2f)); myBeam->setColor(myColor); myBeam->setTargetObject(mBeam->getTargetObject()); myBeam->setSourceObject(mBeam->getSourceObject()); myBeam->setNeedsSendToSim(mBeam->getNeedsSendToSim()); myBeam->setDuration(duration* 1.2f); } }
void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) { // do not update if avatar didn't move if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) { return; } LLVector3 last_position; LLVector3 last_axis; last_position = getOrigin(); last_axis = getAtAxis(); mLastPointOfInterest = point_of_interest; // constrain to max distance from avatar LLVector3 camera_offset = center - gAgent.getPositionAgent(); LLViewerRegion * regp = gAgent.getRegion(); F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f; LLVector3 origin = center; if (origin.mV[2] > water_height) { origin.mV[2] = llmax(origin.mV[2], water_height+0.20f); } else { origin.mV[2] = llmin(origin.mV[2], water_height-0.20f); } setOriginAndLookAt(origin, up_direction, point_of_interest); mVelocityDir = center - last_position ; F32 dpos = mVelocityDir.normVec() ; LLQuaternion rotation; rotation.shortestArc(last_axis, getAtAxis()); F32 x, y, z; F32 drot; rotation.getAngleAxis(&drot, &x, &y, &z); mVelocityStat.addValue(dpos); mAngularVelocityStat.addValue(drot); mAverageSpeed = mVelocityStat.getMeanPerSec() ; mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ; mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect())); // update pixel meter ratio using default fov, not modified one mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5)); // update screen pixel area mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); }
//----------------------------------------------------------------------------- // solve() //----------------------------------------------------------------------------- void LLJointSolverRP3::solve() { // llinfos << llendl; // llinfos << "LLJointSolverRP3::solve()" << llendl; //------------------------------------------------------------------------- // setup joints in their base rotations //------------------------------------------------------------------------- mJointA->setRotation( mJointABaseRotation ); mJointB->setRotation( mJointBBaseRotation ); //------------------------------------------------------------------------- // get joint positions in world space //------------------------------------------------------------------------- LLVector3 aPos = mJointA->getWorldPosition(); LLVector3 bPos = mJointB->getWorldPosition(); LLVector3 cPos = mJointC->getWorldPosition(); LLVector3 gPos = mJointGoal->getWorldPosition(); // llinfos << "bPosLocal = " << mJointB->getPosition() << llendl; // llinfos << "cPosLocal = " << mJointC->getPosition() << llendl; // llinfos << "bRotLocal = " << mJointB->getRotation() << llendl; // llinfos << "cRotLocal = " << mJointC->getRotation() << llendl; // llinfos << "aPos : " << aPos << llendl; // llinfos << "bPos : " << bPos << llendl; // llinfos << "cPos : " << cPos << llendl; // llinfos << "gPos : " << gPos << llendl; //------------------------------------------------------------------------- // get the poleVector in world space //------------------------------------------------------------------------- LLVector3 poleVec = mPoleVector; if ( mJointA->getParent() ) { LLVector4a pole_veca; pole_veca.load3(mPoleVector.mV); mJointA->getParent()->getWorldMatrix().rotate(pole_veca,pole_veca); poleVec.set(pole_veca.getF32ptr()); } //------------------------------------------------------------------------- // compute the following: // vector from A to B // vector from B to C // vector from A to C // vector from A to G (goal) //------------------------------------------------------------------------- LLVector3 abVec = bPos - aPos; LLVector3 bcVec = cPos - bPos; LLVector3 acVec = cPos - aPos; LLVector3 agVec = gPos - aPos; // llinfos << "abVec : " << abVec << llendl; // llinfos << "bcVec : " << bcVec << llendl; // llinfos << "acVec : " << acVec << llendl; // llinfos << "agVec : " << agVec << llendl; //------------------------------------------------------------------------- // compute needed lengths of those vectors //------------------------------------------------------------------------- F32 abLen = abVec.magVec(); F32 bcLen = bcVec.magVec(); F32 agLen = agVec.magVec(); // llinfos << "abLen : " << abLen << llendl; // llinfos << "bcLen : " << bcLen << llendl; // llinfos << "agLen : " << agLen << llendl; //------------------------------------------------------------------------- // compute component vector of (A->B) orthogonal to (A->C) //------------------------------------------------------------------------- LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); // llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl; //------------------------------------------------------------------------- // compute the normal of the original ABC plane (and store for later) //------------------------------------------------------------------------- LLVector3 abcNorm; if (!mbUseBAxis) { if( are_parallel(abVec, bcVec, 0.001f) ) { // the current solution is maxed out, so we use the axis that is // orthogonal to both poleVec and A->B if ( are_parallel(poleVec, abVec, 0.001f) ) { // ACK! the problem is singular if ( are_parallel(poleVec, agVec, 0.001f) ) { // the solutions is also singular return; } else { abcNorm = poleVec % agVec; } } else { abcNorm = poleVec % abVec; } } else { abcNorm = abVec % bcVec; } } else { abcNorm = mBAxis * mJointB->getWorldRotation(); } //------------------------------------------------------------------------- // compute rotation of B //------------------------------------------------------------------------- // angle between A->B and B->C F32 abbcAng = angle_between(abVec, bcVec); // vector orthogonal to A->B and B->C LLVector3 abbcOrthoVec = abVec % bcVec; if (abbcOrthoVec.magVecSquared() < 0.001f) { abbcOrthoVec = poleVec % abVec; abacCompOrthoVec = poleVec; } abbcOrthoVec.normVec(); F32 agLenSq = agLen * agLen; // angle arm for extension F32 cosTheta = (agLenSq - abLen*abLen - bcLen*bcLen) / (2.0f * abLen * bcLen); if (cosTheta > 1.0f) cosTheta = 1.0f; else if (cosTheta < -1.0f) cosTheta = -1.0f; F32 theta = acos(cosTheta); LLQuaternion bRot(theta - abbcAng, abbcOrthoVec); // llinfos << "abbcAng : " << abbcAng << llendl; // llinfos << "abbcOrthoVec : " << abbcOrthoVec << llendl; // llinfos << "agLenSq : " << agLenSq << llendl; // llinfos << "cosTheta : " << cosTheta << llendl; // llinfos << "theta : " << theta << llendl; // llinfos << "bRot : " << bRot << llendl; // llinfos << "theta abbcAng theta-abbcAng: " << theta*180.0/F_PI << " " << abbcAng*180.0f/F_PI << " " << (theta - abbcAng)*180.0f/F_PI << llendl; //------------------------------------------------------------------------- // compute rotation that rotates new A->C to A->G //------------------------------------------------------------------------- // rotate B->C by bRot bcVec = bcVec * bRot; // update A->C acVec = abVec + bcVec; LLQuaternion cgRot; cgRot.shortestArc( acVec, agVec ); // llinfos << "bcVec : " << bcVec << llendl; // llinfos << "acVec : " << acVec << llendl; // llinfos << "cgRot : " << cgRot << llendl; // update A->B and B->C with rotation from C to G abVec = abVec * cgRot; bcVec = bcVec * cgRot; abcNorm = abcNorm * cgRot; acVec = abVec + bcVec; //------------------------------------------------------------------------- // compute the normal of the APG plane //------------------------------------------------------------------------- if (are_parallel(agVec, poleVec, 0.001f)) { // the solution plane is undefined ==> we're done return; } LLVector3 apgNorm = poleVec % agVec; apgNorm.normVec(); if (!mbUseBAxis) { //--------------------------------------------------------------------- // compute the normal of the new ABC plane // (only necessary if we're NOT using mBAxis) //--------------------------------------------------------------------- if( are_parallel(abVec, bcVec, 0.001f) ) { // G is either too close or too far away // we'll use the old ABCnormal } else { abcNorm = abVec % bcVec; } abcNorm.normVec(); } //------------------------------------------------------------------------- // calcuate plane rotation //------------------------------------------------------------------------- LLQuaternion pRot; if ( are_parallel( abcNorm, apgNorm, 0.001f) ) { if (abcNorm * apgNorm < 0.0f) { // we must be PI radians off ==> rotate by PI around agVec pRot.setQuat(F_PI, agVec); } else { // we're done } } else { pRot.shortestArc( abcNorm, apgNorm ); } // llinfos << "abcNorm = " << abcNorm << llendl; // llinfos << "apgNorm = " << apgNorm << llendl; // llinfos << "pRot = " << pRot << llendl; //------------------------------------------------------------------------- // compute twist rotation //------------------------------------------------------------------------- LLQuaternion twistRot( mTwist, agVec ); // llinfos << "twist : " << mTwist*180.0/F_PI << llendl; // llinfos << "agNormVec: " << agNormVec << llendl; // llinfos << "twistRot : " << twistRot << llendl; //------------------------------------------------------------------------- // compute rotation of A //------------------------------------------------------------------------- LLQuaternion aRot = cgRot * pRot * twistRot; //------------------------------------------------------------------------- // apply the rotations //------------------------------------------------------------------------- mJointB->setWorldRotation( mJointB->getWorldRotation() * bRot ); mJointA->setWorldRotation( mJointA->getWorldRotation() * aRot ); }