llagent.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:183k
- {
- const F32 SMOOTHING_HALF_LIFE = 0.02f;
-
- F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
-
- if (!mFocusObject) // we differentiate on avatar mode
- {
- // for avatar-relative focus, we smooth in avatar space -
- // the avatar moves too jerkily w/r/t global space to smooth there.
- LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent;
- if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
- {
- camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing);
- camera_pos_global = camera_pos_agent + agent_pos;
- }
- }
- else
- {
- LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal;
- if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
- {
- camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing);
- }
- }
- }
-
- mCameraSmoothingLastPositionGlobal = camera_pos_global;
- mCameraSmoothingLastPositionAgent = camera_pos_agent;
- mCameraSmoothingStop = FALSE;
- }
-
- mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE));
- // llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl;
- F32 ui_offset = 0.f;
- if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode )
- {
- ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global );
- }
- LLVector3 focus_agent = getPosAgentFromGlobal(mFocusGlobal);
-
- mCameraPositionAgent = getPosAgentFromGlobal(camera_pos_global);
- // Move the camera
- //Ventrella
- LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
- //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
- //end Ventrella
- //RN: translate UI offset after camera is oriented properly
- LLViewerCamera::getInstance()->translate(LLViewerCamera::getInstance()->getLeftAxis() * ui_offset);
-
- // Change FOV
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
- // follow camera when in customize mode
- if (cameraCustomizeAvatar())
- {
- setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
- }
- // update the travel distance stat
- // this isn't directly related to the camera
- // but this seemed like the best place to do this
- LLVector3d global_pos = getPositionGlobal();
- if (! mLastPositionGlobal.isExactlyZero())
- {
- LLVector3d delta = global_pos - mLastPositionGlobal;
- mDistanceTraveled += delta.magVec();
- }
- mLastPositionGlobal = global_pos;
-
- if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->isSitting() && cameraMouselook())
- {
- LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() +
- LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() +
- LLVector3(0.1f, 0.f, 0.f) * mAvatarObject->mPelvisp->getWorldRotation();
- LLVector3 diff = mCameraPositionAgent - head_pos;
- diff = diff * ~mAvatarObject->mRoot.getWorldRotation();
- LLJoint* torso_joint = mAvatarObject->mTorsop;
- LLJoint* chest_joint = mAvatarObject->mChestp;
- LLVector3 torso_scale = torso_joint->getScale();
- LLVector3 chest_scale = chest_joint->getScale();
- // shorten avatar skeleton to avoid foot interpenetration
- if (!mAvatarObject->mInAir)
- {
- LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
- F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f);
- F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f);
- torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
- LLJoint* neck_joint = mAvatarObject->mNeckp;
- LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation();
- scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f);
- chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
- diff.mV[VZ] = 0.f;
- }
- mAvatarObject->mPelvisp->setPosition(mAvatarObject->mPelvisp->getPosition() + diff);
- mAvatarObject->mRoot.updateWorldMatrixChildren();
- for (LLVOAvatar::attachment_map_t::iterator iter = mAvatarObject->mAttachmentPoints.begin();
- iter != mAvatarObject->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- LLViewerObject *attached_object = (*attachment_iter);
- if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
- {
- // clear any existing "early" movements of attachment
- attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE);
- gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
- attached_object->updateText();
- }
- }
- }
- torso_joint->setScale(torso_scale);
- chest_joint->setScale(chest_scale);
- }
- }
- void LLAgent::updateFocusOffset()
- {
- validateFocusObject();
- if (mFocusObject.notNull())
- {
- LLVector3d obj_pos = getPosGlobalFromAgent(mFocusObject->getRenderPosition());
- mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos);
- }
- }
- void LLAgent::validateFocusObject()
- {
- if (mFocusObject.notNull() &&
- (mFocusObject->isDead()))
- {
- mFocusObjectOffset.clearVec();
- clearFocusObject();
- mCameraFOVZoomFactor = 0.f;
- }
- }
- //-----------------------------------------------------------------------------
- // calcCustomizeAvatarUIOffset()
- //-----------------------------------------------------------------------------
- F32 LLAgent::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global )
- {
- F32 ui_offset = 0.f;
- if( gFloaterCustomize )
- {
- const LLRect& rect = gFloaterCustomize->getRect();
- // Move the camera so that the avatar isn't covered up by this floater.
- F32 fraction_of_fov = 0.5f - (0.5f * (1.f - llmin(1.f, ((F32)rect.getWidth() / (F32)gViewerWindow->getWindowWidthScaled()))));
- F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); // radians
- F32 offset = tan(apparent_angle);
- if( rect.mLeft < (gViewerWindow->getWindowWidthScaled() - rect.mRight) )
- {
- // Move the avatar to the right (camera to the left)
- ui_offset = offset;
- }
- else
- {
- // Move the avatar to the left (camera to the right)
- ui_offset = -offset;
- }
- }
- F32 range = (F32)dist_vec(camera_pos_global, gAgent.getFocusGlobal());
- mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
- return mUIOffset * range;
- }
- //-----------------------------------------------------------------------------
- // calcFocusPositionTargetGlobal()
- //-----------------------------------------------------------------------------
- LLVector3d LLAgent::calcFocusPositionTargetGlobal()
- {
- if (mFocusObject.notNull() && mFocusObject->isDead())
- {
- clearFocusObject();
- }
- // Ventrella
- if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
- {
- mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
- return mFocusTargetGlobal;
- }// End Ventrella
- else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- LLVector3d at_axis(1.0, 0.0, 0.0);
- LLQuaternion agent_rot = mFrameAgent.getQuaternion();
- if (mAvatarObject.notNull() && mAvatarObject->getParent())
- {
- LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
- if (!root_object->flagCameraDecoupled())
- {
- agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
- }
- }
- at_axis = at_axis * agent_rot;
- mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis;
- return mFocusTargetGlobal;
- }
- else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
- {
- return mFocusTargetGlobal;
- }
- else if (!mFocusOnAvatar)
- {
- if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull())
- {
- LLDrawable* drawablep = mFocusObject->mDrawable;
-
- if (mTrackFocusObject &&
- drawablep &&
- drawablep->isActive())
- {
- if (!mFocusObject->isAvatar())
- {
- if (mFocusObject->isSelected())
- {
- gPipeline.updateMoveNormalAsync(drawablep);
- }
- else
- {
- if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
- {
- gPipeline.updateMoveNormalAsync(drawablep);
- }
- else
- {
- gPipeline.updateMoveDampedAsync(drawablep);
- }
- }
- }
- }
- // if not tracking object, update offset based on new object position
- else
- {
- updateFocusOffset();
- }
- LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset;
- mFocusTargetGlobal.setVec(getPosGlobalFromAgent(focus_agent));
- }
- return mFocusTargetGlobal;
- }
- else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull())
- {
- // sit camera
- LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
- LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
- LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot);
- return getPosGlobalFromAgent(target_pos);
- }
- else
- {
- return getPositionGlobal() + calcThirdPersonFocusOffset();
- }
- }
- LLVector3d LLAgent::calcThirdPersonFocusOffset()
- {
- // ...offset from avatar
- LLVector3d focus_offset;
- LLQuaternion agent_rot = mFrameAgent.getQuaternion();
- if (!mAvatarObject.isNull() && mAvatarObject->getParent())
- {
- agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
- }
- focus_offset = mFocusOffsetInitial[mCameraPreset] * agent_rot;
- return focus_offset;
- }
- void LLAgent::setupSitCamera()
- {
- // agent frame entering this function is in world coordinates
- if (mAvatarObject.notNull() && mAvatarObject->getParent())
- {
- LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
- // slam agent coordinate frame to proper parent local version
- LLVector3 at_axis = mFrameAgent.getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- resetAxes(at_axis * ~parent_rot);
- }
- }
- //-----------------------------------------------------------------------------
- // getCameraPositionAgent()
- //-----------------------------------------------------------------------------
- const LLVector3 &LLAgent::getCameraPositionAgent() const
- {
- return LLViewerCamera::getInstance()->getOrigin();
- }
- //-----------------------------------------------------------------------------
- // getCameraPositionGlobal()
- //-----------------------------------------------------------------------------
- LLVector3d LLAgent::getCameraPositionGlobal() const
- {
- return getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
- }
- //-----------------------------------------------------------------------------
- // calcCameraFOVZoomFactor()
- //-----------------------------------------------------------------------------
- F32 LLAgent::calcCameraFOVZoomFactor()
- {
- LLVector3 camera_offset_dir;
- camera_offset_dir.setVec(mCameraFocusOffset);
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- return 0.f;
- }
- else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
- {
- // don't FOV zoom on mostly transparent objects
- LLVector3 focus_offset = mFocusObjectOffset;
- F32 obj_min_dist = 0.f;
- calcCameraMinDistance(obj_min_dist);
- F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
- mFocusObjectDist = obj_min_dist - current_distance;
- F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f);
- return new_fov_zoom;
- }
- else // focusing on land or avatar
- {
- // keep old field of view until user changes focus explicitly
- return mCameraFOVZoomFactor;
- //return 0.f;
- }
- }
- //-----------------------------------------------------------------------------
- // calcCameraPositionTargetGlobal()
- //-----------------------------------------------------------------------------
- LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
- {
- // Compute base camera position and look-at points.
- F32 camera_land_height;
- LLVector3d frame_center_global = mAvatarObject.isNull() ? getPositionGlobal()
- : getPosGlobalFromAgent(mAvatarObject->mRoot.getWorldPosition());
-
- BOOL isConstrained = FALSE;
- LLVector3d head_offset;
- head_offset.setVec(mThirdPersonHeadOffset);
- LLVector3d camera_position_global;
- // Ventrella
- if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
- {
- camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
- }// End Ventrella
- else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- if (mAvatarObject.isNull() || mAvatarObject->mDrawable.isNull())
- {
- llwarns << "Null avatar drawable!" << llendl;
- return LLVector3d::zero;
- }
- head_offset.clearVec();
- if (mAvatarObject->isSitting() && mAvatarObject->getParent())
- {
- mAvatarObject->updateHeadOffset();
- head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX];
- head_offset.mdV[VY] = mAvatarObject->mHeadOffset.mV[VY];
- head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ] + 0.1f;
- const LLMatrix4& mat = ((LLViewerObject*) mAvatarObject->getParent())->getRenderMatrix();
- camera_position_global = getPosGlobalFromAgent
- ((mAvatarObject->getPosition()+
- LLVector3(head_offset)*mAvatarObject->getRotation()) * mat);
- }
- else
- {
- head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ];
- if (mAvatarObject->isSitting())
- {
- head_offset.mdV[VZ] += 0.1;
- }
- camera_position_global = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());//frame_center_global;
- head_offset = head_offset * mAvatarObject->getRenderRotation();
- camera_position_global = camera_position_global + head_offset;
- }
- }
- else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar)
- {
- LLVector3 local_camera_offset;
- F32 camera_distance = 0.f;
- if (mSitCameraEnabled
- && mAvatarObject.notNull()
- && mAvatarObject->isSitting()
- && mSitCameraReferenceObject.notNull())
- {
- // sit camera
- LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
- LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
- LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot);
- camera_position_global = getPosGlobalFromAgent(target_pos);
- }
- else
- {
- local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
-
- // are we sitting down?
- if (mAvatarObject.notNull() && mAvatarObject->getParent())
- {
- LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
- // slam agent coordinate frame to proper parent local version
- LLVector3 at_axis = mFrameAgent.getAtAxis() * parent_rot;
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- resetAxes(at_axis * ~parent_rot);
- local_camera_offset = local_camera_offset * mFrameAgent.getQuaternion() * parent_rot;
- }
- else
- {
- local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset );
- }
- if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->isSitting()))
- {
- LLVector3 plane_normal;
- plane_normal.setVec(mCameraCollidePlane.mV);
- F32 offset_dot_norm = local_camera_offset * plane_normal;
- if (llabs(offset_dot_norm) < 0.001f)
- {
- offset_dot_norm = 0.001f;
- }
-
- camera_distance = local_camera_offset.normalize();
- F32 pos_dot_norm = getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal;
-
- // if agent is outside the colliding half-plane
- if (pos_dot_norm > mCameraCollidePlane.mV[VW])
- {
- // check to see if camera is on the opposite side (inside) the half-plane
- if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW])
- {
- // diminish offset by factor to push it back outside the half-plane
- camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm;
- }
- }
- else
- {
- if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW])
- {
- camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm;
- }
- }
- }
- else
- {
- camera_distance = local_camera_offset.normalize();
- }
- mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE);
- if (mTargetCameraDistance != mCurrentCameraDistance)
- {
- F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
- mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
- }
- // Make the camera distance current
- local_camera_offset *= mCurrentCameraDistance;
- // set the global camera position
- LLVector3d camera_offset;
-
- LLVector3 av_pos = mAvatarObject.isNull() ? LLVector3::zero : mAvatarObject->getRenderPosition();
- camera_offset.setVec( local_camera_offset );
- camera_position_global = frame_center_global + head_offset + camera_offset;
- if (mAvatarObject.notNull())
- {
- LLVector3d camera_lag_d;
- F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
- LLVector3 target_lag;
- LLVector3 vel = getVelocity();
- // lag by appropriate amount for flying
- F32 time_in_air = mAvatarObject->mTimeInAir.getElapsedTimeF32();
- if(!mCameraAnimating && mAvatarObject->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
- {
- LLVector3 frame_at_axis = mFrameAgent.getAtAxis();
- frame_at_axis -= projected_vec(frame_at_axis, getReferenceUpVector());
- frame_at_axis.normalize();
- //transition smoothly in air mode, to avoid camera pop
- F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME;
- u = llclamp(u, 0.f, 1.f);
- lag_interp *= u;
- if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == mAvatarObject->getID())
- {
- // disable camera lag when using mouse-directed steering
- target_lag.clearVec();
- }
- else
- {
- target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
- }
- mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
- F32 lag_dist = mCameraLag.magVec();
- if (lag_dist > MAX_CAMERA_LAG)
- {
- mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist;
- }
- // clamp camera lag so that avatar is always in front
- F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis;
- if (dot < -(MIN_CAMERA_LAG * u))
- {
- mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis;
- }
- }
- else
- {
- mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f));
- }
- camera_lag_d.setVec(mCameraLag);
- camera_position_global = camera_position_global - camera_lag_d;
- }
- }
- }
- else
- {
- LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal();
- // camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value
- camera_position_global = focusPosGlobal + mCameraFocusOffset;
- }
- if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
- {
- LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(
- camera_position_global);
- bool constrain = true;
- if(regionp && regionp->canManageEstate())
- {
- constrain = false;
- }
- if(constrain)
- {
- F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ?
- APPEARANCE_MAX_ZOOM : mDrawDistance;
- LLVector3d camera_offset = camera_position_global
- - gAgent.getPositionGlobal();
- F32 camera_distance = (F32)camera_offset.magVec();
- if(camera_distance > max_dist)
- {
- camera_position_global = gAgent.getPositionGlobal() +
- (max_dist / camera_distance) * camera_offset;
- isConstrained = TRUE;
- }
- }
- // JC - Could constrain camera based on parcel stuff here.
- // LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
- //
- // if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global)))
- // {
- // camera_position_global = last_position_global;
- //
- // isConstrained = TRUE;
- // }
- }
- // Don't let camera go underground
- F32 camera_min_off_ground = getCameraMinOffGround();
- camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
- if (camera_position_global.mdV[VZ] < camera_land_height + camera_min_off_ground)
- {
- camera_position_global.mdV[VZ] = camera_land_height + camera_min_off_ground;
- isConstrained = TRUE;
- }
- if (hit_limit)
- {
- *hit_limit = isConstrained;
- }
- return camera_position_global;
- }
- LLVector3 LLAgent::getCameraOffsetInitial()
- {
- return mCameraOffsetInitial[mCameraPreset];
- }
- //-----------------------------------------------------------------------------
- // handleScrollWheel()
- //-----------------------------------------------------------------------------
- void LLAgent::handleScrollWheel(S32 clicks)
- {
- if ( mCameraMode == CAMERA_MODE_FOLLOW && gAgent.getFocusOnAvatar())
- {
- if ( ! mFollowCam.getPositionLocked() ) // not if the followCam position is locked in place
- {
- mFollowCam.zoom( clicks );
- if ( mFollowCam.isZoomedToMinimumDistance() )
- {
- changeCameraToMouselook(FALSE);
- }
- }
- }
- else
- {
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
- const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2);
- // Block if camera is animating
- if (mCameraAnimating)
- {
- return;
- }
- if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
- {
- F32 zoom_factor = (F32)pow(0.8, -clicks);
- cameraZoomIn(zoom_factor);
- }
- else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
- {
- F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
-
- F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
- current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
-
- cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
- }
- else
- {
- F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec();
- cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks)));
- }
- }
- }
- //-----------------------------------------------------------------------------
- // getCameraMinOffGround()
- //-----------------------------------------------------------------------------
- F32 LLAgent::getCameraMinOffGround()
- {
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- return 0.f;
- }
- else
- {
- if (gSavedSettings.getBOOL("DisableCameraConstraints"))
- {
- return -1000.f;
- }
- else
- {
- return 0.5f;
- }
- }
- }
- //-----------------------------------------------------------------------------
- // resetCamera()
- //-----------------------------------------------------------------------------
- void LLAgent::resetCamera()
- {
- // Remove any pitch from the avatar
- LLVector3 at = mFrameAgent.getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
- // have to explicitly clear field of view zoom now
- mCameraFOVZoomFactor = 0.f;
- updateCamera();
- }
- //-----------------------------------------------------------------------------
- // changeCameraToMouselook()
- //-----------------------------------------------------------------------------
- void LLAgent::changeCameraToMouselook(BOOL animate)
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
- // visibility changes at end of animation
- gViewerWindow->getWindow()->resetBusyCount();
- // unpause avatar animation
- mPauseRequest = NULL;
- LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
- if (mAvatarObject.notNull())
- {
- mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
- mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
- }
- //gViewerWindow->stopGrab();
- LLSelectMgr::getInstance()->deselectAll();
- gViewerWindow->hideCursor();
- gViewerWindow->moveCursorToCenter();
- if( mCameraMode != CAMERA_MODE_MOUSELOOK )
- {
- gFocusMgr.setKeyboardFocus( NULL );
-
- mLastCameraMode = mCameraMode;
- mCameraMode = CAMERA_MODE_MOUSELOOK;
- U32 old_flags = mControlFlags;
- setControlFlags(AGENT_CONTROL_MOUSELOOK);
- if (old_flags != mControlFlags)
- {
- mbFlagsDirty = TRUE;
- }
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- mCameraAnimating = FALSE;
- endAnimationUpdateUI();
- }
- }
- }
- //-----------------------------------------------------------------------------
- // changeCameraToDefault()
- //-----------------------------------------------------------------------------
- void LLAgent::changeCameraToDefault()
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
- if (LLFollowCamMgr::getActiveFollowCamParams())
- {
- changeCameraToFollow();
- }
- else
- {
- changeCameraToThirdPerson();
- }
- }
- // Ventrella
- //-----------------------------------------------------------------------------
- // changeCameraToFollow()
- //-----------------------------------------------------------------------------
- void LLAgent::changeCameraToFollow(BOOL animate)
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
- if( mCameraMode != CAMERA_MODE_FOLLOW )
- {
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- animate = FALSE;
- }
- startCameraAnimation();
- mLastCameraMode = mCameraMode;
- mCameraMode = CAMERA_MODE_FOLLOW;
- // bang-in the current focus, position, and up vector of the follow cam
- mFollowCam.reset( mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis );
-
- if (gBasicToolset)
- {
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- }
- if (mAvatarObject.notNull())
- {
- mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
- mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
- mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
- }
- // unpause avatar animation
- mPauseRequest = NULL;
- U32 old_flags = mControlFlags;
- clearControlFlags(AGENT_CONTROL_MOUSELOOK);
- if (old_flags != mControlFlags)
- {
- mbFlagsDirty = TRUE;
- }
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- mCameraAnimating = FALSE;
- endAnimationUpdateUI();
- }
- }
- }
- //-----------------------------------------------------------------------------
- // changeCameraToThirdPerson()
- //-----------------------------------------------------------------------------
- void LLAgent::changeCameraToThirdPerson(BOOL animate)
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
- gViewerWindow->getWindow()->resetBusyCount();
- mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
- if (mAvatarObject.notNull())
- {
- if (!mAvatarObject->isSitting())
- {
- mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
- }
- mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
- mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
- }
- LLVector3 at_axis;
- // unpause avatar animation
- mPauseRequest = NULL;
- if( mCameraMode != CAMERA_MODE_THIRD_PERSON )
- {
- if (gBasicToolset)
- {
- LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
- }
- mCameraLag.clearVec();
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
- {
- mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
- mTargetCameraDistance = MIN_CAMERA_DISTANCE;
- animate = FALSE;
- }
- mLastCameraMode = mCameraMode;
- mCameraMode = CAMERA_MODE_THIRD_PERSON;
- U32 old_flags = mControlFlags;
- clearControlFlags(AGENT_CONTROL_MOUSELOOK);
- if (old_flags != mControlFlags)
- {
- mbFlagsDirty = TRUE;
- }
- }
- // Remove any pitch from the avatar
- if (mAvatarObject.notNull() && mAvatarObject->getParent())
- {
- LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
- at_axis = LLViewerCamera::getInstance()->getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- resetAxes(at_axis * ~obj_rot);
- }
- else
- {
- at_axis = mFrameAgent.getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- resetAxes(at_axis);
- }
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- mCameraAnimating = FALSE;
- endAnimationUpdateUI();
- }
- }
- //-----------------------------------------------------------------------------
- // changeCameraToCustomizeAvatar()
- //-----------------------------------------------------------------------------
- void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_animate)
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- {
- return;
- }
- standUp(); // force stand up
- gViewerWindow->getWindow()->resetBusyCount();
- if (gFaceEditToolset)
- {
- LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
- }
- if (camera_animate)
- {
- startCameraAnimation();
- }
- // Remove any pitch from the avatar
- //LLVector3 at = mFrameAgent.getAtAxis();
- //at.mV[VZ] = 0.f;
- //at.normalize();
- //gAgent.resetAxes(at);
- if( mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR )
- {
- mLastCameraMode = mCameraMode;
- mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
- U32 old_flags = mControlFlags;
- clearControlFlags(AGENT_CONTROL_MOUSELOOK);
- if (old_flags != mControlFlags)
- {
- mbFlagsDirty = TRUE;
- }
- gFocusMgr.setKeyboardFocus( NULL );
- gFocusMgr.setMouseCapture( NULL );
- LLVOAvatarSelf::onCustomizeStart();
- }
- if (mAvatarObject.notNull())
- {
- if(avatar_animate)
- {
- // Remove any pitch from the avatar
- LLVector3 at = mFrameAgent.getAtAxis();
- at.mV[VZ] = 0.f;
- at.normalize();
- gAgent.resetAxes(at);
- sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
- mCustomAnim = TRUE ;
- mAvatarObject->startMotion(ANIM_AGENT_CUSTOMIZE);
- LLMotion* turn_motion = mAvatarObject->findMotion(ANIM_AGENT_CUSTOMIZE);
- if (turn_motion)
- {
- mAnimationDuration = turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP;
- }
- else
- {
- mAnimationDuration = gSavedSettings.getF32("ZoomTime");
- }
- }
- gAgent.setFocusGlobal(LLVector3d::zero);
- }
- else
- {
- mCameraAnimating = FALSE;
- endAnimationUpdateUI();
- }
- }
- void LLAgent::switchCameraPreset(ECameraPreset preset)
- {
- //zoom is supposed to be reset for the front and group views
- mCameraZoomFraction = 1.f;
- //focusing on avatar in that case means following him on movements
- mFocusOnAvatar = TRUE;
- mCameraPreset = preset;
- gSavedSettings.setU32("CameraPreset", mCameraPreset);
- }
- //
- // Focus point management
- //
- //-----------------------------------------------------------------------------
- // startCameraAnimation()
- //-----------------------------------------------------------------------------
- void LLAgent::startCameraAnimation()
- {
- mAnimationCameraStartGlobal = getCameraPositionGlobal();
- mAnimationFocusStartGlobal = mFocusGlobal;
- mAnimationTimer.reset();
- mCameraAnimating = TRUE;
- mAnimationDuration = gSavedSettings.getF32("ZoomTime");
- }
- //-----------------------------------------------------------------------------
- // stopCameraAnimation()
- //-----------------------------------------------------------------------------
- void LLAgent::stopCameraAnimation()
- {
- mCameraAnimating = FALSE;
- }
- void LLAgent::clearFocusObject()
- {
- if (mFocusObject.notNull())
- {
- startCameraAnimation();
- setFocusObject(NULL);
- mFocusObjectOffset.clearVec();
- }
- }
- void LLAgent::setFocusObject(LLViewerObject* object)
- {
- mFocusObject = object;
- }
- // Focus on a point, but try to keep camera position stable.
- //-----------------------------------------------------------------------------
- // setFocusGlobal()
- //-----------------------------------------------------------------------------
- void LLAgent::setFocusGlobal(const LLPickInfo& pick)
- {
- LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID);
- if (objectp)
- {
- // focus on object plus designated offset
- // which may or may not be same as pick.mPosGlobal
- setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID);
- }
- else
- {
- // focus directly on point where user clicked
- setFocusGlobal(pick.mPosGlobal, pick.mObjectID);
- }
- }
- void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
- {
- setFocusObject(gObjectList.findObject(object_id));
- LLVector3d old_focus = mFocusTargetGlobal;
- LLViewerObject *focus_obj = mFocusObject;
- // if focus has changed
- if (old_focus != focus)
- {
- if (focus.isExactlyZero())
- {
- if (mAvatarObject.notNull())
- {
- mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
- }
- else
- {
- mFocusTargetGlobal = getPositionGlobal();
- }
- mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal;
- mCameraFocusOffset = mCameraFocusOffsetTarget;
- setLookAt(LOOKAT_TARGET_CLEAR);
- }
- else
- {
- mFocusTargetGlobal = focus;
- if (!focus_obj)
- {
- mCameraFOVZoomFactor = 0.f;
- }
- mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal;
- startCameraAnimation();
- if (focus_obj)
- {
- if (focus_obj->isAvatar())
- {
- setLookAt(LOOKAT_TARGET_FOCUS, focus_obj);
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation());
- }
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal));
- }
- }
- }
- else // focus == mFocusTargetGlobal
- {
- if (focus.isExactlyZero())
- {
- if (mAvatarObject.notNull())
- {
- mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
- }
- else
- {
- mFocusTargetGlobal = getPositionGlobal();
- }
- }
- mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);;
- mCameraFocusOffset = mCameraFocusOffsetTarget;
- }
- if (mFocusObject.notNull())
- {
- // for attachments, make offset relative to avatar, not the attachment
- if (mFocusObject->isAttachment())
- {
- while (mFocusObject.notNull() // DEV-29123 - can crash with a messed-up attachment
- && !mFocusObject->isAvatar())
- {
- mFocusObject = (LLViewerObject*) mFocusObject->getParent();
- }
- setFocusObject((LLViewerObject*)mFocusObject);
- }
- updateFocusOffset();
- }
- }
- // Used for avatar customization
- //-----------------------------------------------------------------------------
- // setCameraPosAndFocusGlobal()
- //-----------------------------------------------------------------------------
- void LLAgent::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLVector3d& focus, const LLUUID &object_id)
- {
- LLVector3d old_focus = mFocusTargetGlobal;
- F64 focus_delta_squared = (old_focus - focus).magVecSquared();
- const F64 ANIM_EPSILON_SQUARED = 0.0001;
- if( focus_delta_squared > ANIM_EPSILON_SQUARED )
- {
- startCameraAnimation();
- if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode )
- {
- // Compensate for the fact that the camera has already been offset to make room for LLFloaterCustomize.
- mAnimationCameraStartGlobal -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal ));
- }
- }
-
- //LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) );
- setFocusObject(gObjectList.findObject(object_id));
- mFocusTargetGlobal = focus;
- mCameraFocusOffsetTarget = camera_pos - focus;
- mCameraFocusOffset = mCameraFocusOffsetTarget;
- if (mFocusObject)
- {
- if (mFocusObject->isAvatar())
- {
- setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject);
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation());
- }
- }
- else
- {
- setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal));
- }
- if( mCameraAnimating )
- {
- const F64 ANIM_METERS_PER_SECOND = 10.0;
- const F64 MIN_ANIM_SECONDS = 0.5;
- const F64 MAX_ANIM_SECONDS = 10.0;
- F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
- anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
- setAnimationDuration( (F32)anim_duration );
- }
- updateFocusOffset();
- }
- //-----------------------------------------------------------------------------
- // setSitCamera()
- //-----------------------------------------------------------------------------
- void LLAgent::setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos, const LLVector3 &camera_focus)
- {
- BOOL camera_enabled = !object_id.isNull();
- if (camera_enabled)
- {
- LLViewerObject *reference_object = gObjectList.findObject(object_id);
- if (reference_object)
- {
- //convert to root object relative?
- mSitCameraPos = camera_pos;
- mSitCameraFocus = camera_focus;
- mSitCameraReferenceObject = reference_object;
- mSitCameraEnabled = TRUE;
- }
- }
- else
- {
- mSitCameraPos.clearVec();
- mSitCameraFocus.clearVec();
- mSitCameraReferenceObject = NULL;
- mSitCameraEnabled = FALSE;
- }
- }
- //-----------------------------------------------------------------------------
- // setFocusOnAvatar()
- //-----------------------------------------------------------------------------
- void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
- {
- if (focus_on_avatar != mFocusOnAvatar)
- {
- if (animate)
- {
- startCameraAnimation();
- }
- else
- {
- stopCameraAnimation();
- }
- }
-
- //RN: when focused on the avatar, we're not "looking" at it
- // looking implies intent while focusing on avatar means
- // you're just walking around with a camera on you...eesh.
- if (!mFocusOnAvatar && focus_on_avatar)
- {
- setFocusGlobal(LLVector3d::zero);
- mCameraFOVZoomFactor = 0.f;
- if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
- {
- LLVector3 at_axis;
- if (mAvatarObject.notNull() && mAvatarObject->getParent())
- {
- LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
- at_axis = LLViewerCamera::getInstance()->getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- resetAxes(at_axis * ~obj_rot);
- }
- else
- {
- at_axis = LLViewerCamera::getInstance()->getAtAxis();
- at_axis.mV[VZ] = 0.f;
- at_axis.normalize();
- resetAxes(at_axis);
- }
- }
- }
- // unlocking camera from avatar
- else if (mFocusOnAvatar && !focus_on_avatar)
- {
- // keep camera focus point consistent, even though it is now unlocked
- setFocusGlobal(getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID());
- }
-
- mFocusOnAvatar = focus_on_avatar;
- }
- //-----------------------------------------------------------------------------
- // heardChat()
- //-----------------------------------------------------------------------------
- void LLAgent::heardChat(const LLUUID& id)
- {
- // log text and voice chat to speaker mgr
- // for keeping track of active speakers, etc.
- LLLocalSpeakerMgr::getInstance()->speakerChatted(id);
- // don't respond to your own voice
- if (id == getID()) return;
-
- if (ll_rand(2) == 0)
- {
- LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
- setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
- }
- mLastChatterID = id;
- mChatTimer.reset();
- }
- //-----------------------------------------------------------------------------
- // lookAtLastChat()
- //-----------------------------------------------------------------------------
- void LLAgent::lookAtLastChat()
- {
- // Block if camera is animating or not in normal third person camera mode
- if (mCameraAnimating || !cameraThirdPerson())
- {
- return;
- }
- LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
- if (chatter)
- {
- LLVector3 delta_pos;
- if (chatter->isAvatar())
- {
- LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
- if (mAvatarObject.notNull() && chatter_av->mHeadp)
- {
- delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
- }
- else
- {
- delta_pos = chatter->getPositionAgent() - getPositionAgent();
- }
- delta_pos.normalize();
- setControlFlags(AGENT_CONTROL_STOP);
- changeCameraToThirdPerson();
- LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
- LLVector3 left = delta_pos % LLVector3::z_axis;
- left.normalize();
- LLVector3 up = left % delta_pos;
- up.normalize();
- new_camera_pos -= delta_pos * 0.4f;
- new_camera_pos += left * 0.3f;
- new_camera_pos += up * 0.2f;
- if (chatter_av->mHeadp)
- {
- setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID);
- mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
- }
- else
- {
- setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
- mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
- }
- setFocusOnAvatar(FALSE, TRUE);
- }
- else
- {
- delta_pos = chatter->getRenderPosition() - getPositionAgent();
- delta_pos.normalize();
- setControlFlags(AGENT_CONTROL_STOP);
- changeCameraToThirdPerson();
- LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
- LLVector3 left = delta_pos % LLVector3::z_axis;
- left.normalize();
- LLVector3 up = left % delta_pos;
- up.normalize();
- new_camera_pos -= delta_pos * 0.4f;
- new_camera_pos += left * 0.3f;
- new_camera_pos += up * 0.2f;
- setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
- mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
- setFocusOnAvatar(FALSE, TRUE);
- }
- }
- }
- const F32 SIT_POINT_EXTENTS = 0.2f;
- LLSD ll_sdmap_from_vector3(const LLVector3& vec)
- {
- LLSD ret;
- ret["X"] = vec.mV[VX];
- ret["Y"] = vec.mV[VY];
- ret["Z"] = vec.mV[VZ];
- return ret;
- }
- LLVector3 ll_vector3_from_sdmap(const LLSD& sd)
- {
- LLVector3 ret;
- ret.mV[VX] = F32(sd["X"].asReal());
- ret.mV[VY] = F32(sd["Y"].asReal());
- ret.mV[VZ] = F32(sd["Z"].asReal());
- return ret;
- }
- void LLAgent::setStartPosition( U32 location_id )
- {
- LLViewerObject *object;
- if (gAgentID == LLUUID::null)
- {
- return;
- }
- // we've got an ID for an agent viewerobject
- object = gObjectList.findObject(gAgentID);
- if (! object)
- {
- llinfos << "setStartPosition - Can't find agent viewerobject id " << gAgentID << llendl;
- return;
- }
- // we've got the viewer object
- // Sometimes the agent can be velocity interpolated off of
- // this simulator. Clamp it to the region the agent is
- // in, a little bit in on each side.
- const F32 INSET = 0.5f; //meters
- const F32 REGION_WIDTH = LLWorld::getInstance()->getRegionWidthInMeters();
- LLVector3 agent_pos = getPositionAgent();
- if (mAvatarObject.notNull())
- {
- // the z height is at the agent's feet
- agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ];
- }
- agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET );
- agent_pos.mV[VY] = llclamp( agent_pos.mV[VY], INSET, REGION_WIDTH - INSET );
- // Don't let them go below ground, or too high.
- agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ],
- mRegionp->getLandHeightRegion( agent_pos ),
- LLWorld::getInstance()->getRegionMaxHeight() );
- // Send the CapReq
- LLSD request;
- LLSD body;
- LLSD homeLocation;
- homeLocation["LocationId"] = LLSD::Integer(location_id);
- homeLocation["LocationPos"] = ll_sdmap_from_vector3(agent_pos);
- homeLocation["LocationLookAt"] = ll_sdmap_from_vector3(mFrameAgent.getAtAxis());
- body["HomeLocation"] = homeLocation;
- // This awkward idiom warrants explanation.
- // For starters, LLSDMessage::ResponderAdapter is ONLY for testing the new
- // LLSDMessage functionality with a pre-existing LLHTTPClient::Responder.
- // In new code, define your reply/error methods on the same class as the
- // sending method, bind them to local LLEventPump objects and pass those
- // LLEventPump names in the request LLSD object.
- // When testing old code, the new LLHomeLocationResponder object
- // is referenced by an LLHTTPClient::ResponderPtr, so when the
- // ResponderAdapter is deleted, the LLHomeLocationResponder will be too.
- // We must trust that the underlying LLHTTPClient code will eventually
- // fire either the reply callback or the error callback; either will cause
- // the ResponderAdapter to delete itself.
- LLSDMessage::ResponderAdapter*
- adapter(new LLSDMessage::ResponderAdapter(new LLHomeLocationResponder()));
- request["message"] = "HomeLocation";
- request["payload"] = body;
- request["reply"] = adapter->getReplyName();
- request["error"] = adapter->getErrorName();
- gAgent.getRegion()->getCapAPI().post(request);
- const U32 HOME_INDEX = 1;
- if( HOME_INDEX == location_id )
- {
- setHomePosRegion( mRegionp->getHandle(), getPositionAgent() );
- }
- }
- struct HomeLocationMapper: public LLCapabilityListener::CapabilityMapper
- {
- // No reply message expected
- HomeLocationMapper(): LLCapabilityListener::CapabilityMapper("HomeLocation") {}
- virtual void buildMessage(LLMessageSystem* msg,
- const LLUUID& agentID,
- const LLUUID& sessionID,
- const std::string& capabilityName,
- const LLSD& payload) const
- {
- msg->newMessageFast(_PREHASH_SetStartLocationRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, agentID);
- msg->addUUIDFast(_PREHASH_SessionID, sessionID);
- msg->nextBlockFast( _PREHASH_StartLocationData);
- // corrected by sim
- msg->addStringFast(_PREHASH_SimName, "");
- msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
- msg->addVector3Fast(_PREHASH_LocationPos,
- ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
- msg->addVector3Fast(_PREHASH_LocationLookAt,
- ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
- }
- };
- // Need an instance of this class so it will self-register
- static HomeLocationMapper homeLocationMapper;
- void LLAgent::requestStopMotion( LLMotion* motion )
- {
- // Notify all avatars that a motion has stopped.
- // This is needed to clear the animation state bits
- LLUUID anim_state = motion->getID();
- onAnimStop(motion->getID());
- // if motion is not looping, it could have stopped by running out of time
- // so we need to tell the server this
- // llinfos << "Sending stop for motion " << motion->getName() << llendl;
- sendAnimationRequest( anim_state, ANIM_REQUEST_STOP );
- }
- void LLAgent::onAnimStop(const LLUUID& id)
- {
- // handle automatic state transitions (based on completion of animation playback)
- if (id == ANIM_AGENT_STAND)
- {
- stopFidget();
- }
- else if (id == ANIM_AGENT_AWAY)
- {
- clearAFK();
- }
- else if (id == ANIM_AGENT_STANDUP)
- {
- // send stand up command
- setControlFlags(AGENT_CONTROL_FINISH_ANIM);
- // now trigger dusting self off animation
- if (mAvatarObject.notNull() && !mAvatarObject->mBelowWater && rand() % 3 == 0)
- sendAnimationRequest( ANIM_AGENT_BRUSH, ANIM_REQUEST_START );
- }
- else if (id == ANIM_AGENT_PRE_JUMP || id == ANIM_AGENT_LAND || id == ANIM_AGENT_MEDIUM_LAND)
- {
- setControlFlags(AGENT_CONTROL_FINISH_ANIM);
- }
- }
- BOOL LLAgent::isGodlike() const
- {
- return mAgentAccess.isGodlike();
- }
- U8 LLAgent::getGodLevel() const
- {
- return mAgentAccess.getGodLevel();
- }
- bool LLAgent::wantsPGOnly() const
- {
- return mAgentAccess.wantsPGOnly();
- }
- bool LLAgent::canAccessMature() const
- {
- return mAgentAccess.canAccessMature();
- }
- bool LLAgent::canAccessAdult() const
- {
- return mAgentAccess.canAccessAdult();
- }
- bool LLAgent::canAccessMaturityInRegion( U64 region_handle ) const
- {
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle( region_handle );
- if( regionp )
- {
- switch( regionp->getSimAccess() )
- {
- case SIM_ACCESS_MATURE:
- if( !canAccessMature() )
- return false;
- break;
- case SIM_ACCESS_ADULT:
- if( !canAccessAdult() )
- return false;
- break;
- default:
- // Oh, go on and hear the silly noises.
- break;
- }
- }
-
- return true;
- }
- bool LLAgent::canAccessMaturityAtGlobal( LLVector3d pos_global ) const
- {
- U64 region_handle = to_region_handle_global( pos_global.mdV[0], pos_global.mdV[1] );
- return canAccessMaturityInRegion( region_handle );
- }
- bool LLAgent::prefersPG() const
- {
- return mAgentAccess.prefersPG();
- }
- bool LLAgent::prefersMature() const
- {
- return mAgentAccess.prefersMature();
- }
-
- bool LLAgent::prefersAdult() const
- {
- return mAgentAccess.prefersAdult();
- }
- bool LLAgent::isTeen() const
- {
- return mAgentAccess.isTeen();
- }
- bool LLAgent::isMature() const
- {
- return mAgentAccess.isMature();
- }
- bool LLAgent::isAdult() const
- {
- return mAgentAccess.isAdult();
- }
- void LLAgent::setTeen(bool teen)
- {
- mAgentAccess.setTeen(teen);
- }
- //static
- int LLAgent::convertTextToMaturity(char text)
- {
- return LLAgentAccess::convertTextToMaturity(text);
- }
- bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
- {
- if (!getRegion())
- return false;
-
- // Update agent access preference on the server
- std::string url = getRegion()->getCapability("UpdateAgentInformation");
- if (!url.empty())
- {
- // Set new access preference
- LLSD access_prefs = LLSD::emptyMap();
- if (preferredMaturity == SIM_ACCESS_PG)
- {
- access_prefs["max"] = "PG";
- }
- else if (preferredMaturity == SIM_ACCESS_MATURE)
- {
- access_prefs["max"] = "M";
- }
- if (preferredMaturity == SIM_ACCESS_ADULT)
- {
- access_prefs["max"] = "A";
- }
-
- LLSD body = LLSD::emptyMap();
- body["access_prefs"] = access_prefs;
- llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
- << url << llendl;
- LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); // Ignore response
- return true;
- }
- return false;
- }
- BOOL LLAgent::getAdminOverride() const
- {
- return mAgentAccess.getAdminOverride();
- }
- void LLAgent::setMaturity(char text)
- {
- mAgentAccess.setMaturity(text);
- }
- void LLAgent::setAdminOverride(BOOL b)
- {
- mAgentAccess.setAdminOverride(b);
- }
- void LLAgent::setGodLevel(U8 god_level)
- {
- mAgentAccess.setGodLevel(god_level);
- }
- void LLAgent::setAOTransition()
- {
- mAgentAccess.setTransition();
- }
- const LLAgentAccess& LLAgent::getAgentAccess()
- {
- return mAgentAccess;
- }
- bool LLAgent::validateMaturity(const LLSD& newvalue)
- {
- return mAgentAccess.canSetMaturity(newvalue.asInteger());
- }
- void LLAgent::handleMaturity(const LLSD& newvalue)
- {
- sendMaturityPreferenceToServer(newvalue.asInteger());
- }
- //----------------------------------------------------------------------------
- //*TODO remove, is not used anywhere as of August 20, 2009
- void LLAgent::buildFullnameAndTitle(std::string& name) const
- {
- if (isGroupMember())
- {
- name = mGroupTitle;
- name += ' ';
- }
- else
- {
- name.erase(0, name.length());
- }
- if (mAvatarObject.notNull())
- {
- name += mAvatarObject->getFullname();
- }
- }
- BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */) const
- {
- if (!ignore_god_mode && isGodlike())
- return true;
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- // This implementation should mirror LLAgentInfo::hasPowerInGroup
- BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const
- {
- if (isGodlike())
- return true;
- // GP_NO_POWERS can also mean no power is enough to grant an ability.
- if (GP_NO_POWERS == power) return FALSE;
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- return (BOOL)((mGroups.get(i).mPowers & power) > 0);
- }
- }
- return FALSE;
- }
- BOOL LLAgent::hasPowerInActiveGroup(U64 power) const
- {
- return (mGroupID.notNull() && (hasPowerInGroup(mGroupID, power)));
- }
- U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const
- {
- if (isGodlike())
- return GP_ALL_POWERS;
-
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- return (mGroups.get(i).mPowers);
- }
- }
- return GP_NO_POWERS;
- }
- BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const
- {
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- data = mGroups.get(i);
- return TRUE;
- }
- }
- return FALSE;
- }
- S32 LLAgent::getGroupContribution(const LLUUID& group_id) const
- {
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- S32 contribution = mGroups.get(i).mContribution;
- return contribution;
- }
- }
- return 0;
- }
- BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)
- {
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- mGroups.get(i).mContribution = contribution;
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("SetGroupContribution");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgentID);
- msg->addUUID("SessionID", gAgentSessionID);
- msg->nextBlock("Data");
- msg->addUUID("GroupID", group_id);
- msg->addS32("Contribution", contribution);
- sendReliableMessage();
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile)
- {
- S32 count = mGroups.count();
- for(S32 i = 0; i < count; ++i)
- {
- if(mGroups.get(i).mID == group_id)
- {
- mGroups.get(i).mAcceptNotices = accept_notices;
- mGroups.get(i).mListInProfile = list_in_profile;
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("SetGroupAcceptNotices");
- msg->nextBlock("AgentData");
- msg->addUUID("AgentID", gAgentID);
- msg->addUUID("SessionID", gAgentSessionID);
- msg->nextBlock("Data");
- msg->addUUID("GroupID", group_id);
- msg->addBOOL("AcceptNotices", accept_notices);
- msg->nextBlock("NewData");
- msg->addBOOL("ListInProfile", list_in_profile);
- sendReliableMessage();
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL LLAgent::canJoinGroups() const
- {
- return mGroups.count() < MAX_AGENT_GROUPS;
- }
- LLQuaternion LLAgent::getHeadRotation()
- {
- if (mAvatarObject.isNull() || !mAvatarObject->mPelvisp || !mAvatarObject->mHeadp)
- {
- return LLQuaternion::DEFAULT;
- }
- if (!gAgent.cameraMouselook())
- {
- return mAvatarObject->getRotation();
- }
- // We must be in mouselook
- LLVector3 look_dir( LLViewerCamera::getInstance()->getAtAxis() );
- LLVector3 up = look_dir % mFrameAgent.getLeftAxis();
- LLVector3 left = up % look_dir;
- LLQuaternion rot(look_dir, left, up);
- if (mAvatarObject->getParent())
- {
- rot = rot * ~mAvatarObject->getParent()->getRotation();
- }
- return rot;
- }
- void LLAgent::sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request)
- {
- if (gAgentID.isNull())
- {
- return;
- }
- S32 num_valid_anims = 0;
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_AgentAnimation);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- for (S32 i = 0; i < anim_ids.count(); i++)
- {
- if (anim_ids[i].isNull())
- {
- continue;
- }
- msg->nextBlockFast(_PREHASH_AnimationList);
- msg->addUUIDFast(_PREHASH_AnimID, (anim_ids[i]) );
- msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
- num_valid_anims++;
- }
- msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
- msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
- if (num_valid_anims)
- {
- sendReliableMessage();
- }
- }
- void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
- {
- if (gAgentID.isNull() || anim_id.isNull() || !mRegionp)
- {
- return;
- }
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_AgentAnimation);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- msg->nextBlockFast(_PREHASH_AnimationList);
- msg->addUUIDFast(_PREHASH_AnimID, (anim_id) );
- msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
- msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
- msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
- sendReliableMessage();
- }
- void LLAgent::sendWalkRun(bool running)
- {
- LLMessageSystem* msgsys = gMessageSystem;
- if (msgsys)
- {
- msgsys->newMessageFast(_PREHASH_SetAlwaysRun);
- msgsys->nextBlockFast(_PREHASH_AgentData);
- msgsys->addUUIDFast(_PREHASH_AgentID, getID());
- msgsys->addUUIDFast(_PREHASH_SessionID, getSessionID());
- msgsys->addBOOLFast(_PREHASH_AlwaysRun, BOOL(running) );
- sendReliableMessage();
- }
- }
- void LLAgent::friendsChanged()
- {
- LLCollectProxyBuddies collector;
- LLAvatarTracker::instance().applyFunctor(collector);
- mProxyForAgents = collector.mProxy;
- }
- BOOL LLAgent::isGrantedProxy(const LLPermissions& perm)
- {
- return (mProxyForAgents.count(perm.getOwner()) > 0);
- }
- BOOL LLAgent::allowOperation(PermissionBit op,
- const LLPermissions& perm,
- U64 group_proxy_power,
- U8 god_minimum)
- {
- // Check god level.
- if (getGodLevel() >= god_minimum) return TRUE;
- if (!perm.isOwned()) return FALSE;
- // A group member with group_proxy_power can act as owner.
- BOOL is_group_owned;
- LLUUID owner_id;
- perm.getOwnership(owner_id, is_group_owned);
- LLUUID group_id(perm.getGroup());
- LLUUID agent_proxy(getID());
- if (is_group_owned)
- {
- if (hasPowerInGroup(group_id, group_proxy_power))
- {
- // Let the member assume the group's id for permission requests.
- agent_proxy = owner_id;
- }
- }
- else
- {
- // Check for granted mod permissions.
- if ((PERM_OWNER != op) && isGrantedProxy(perm))
- {
- agent_proxy = owner_id;
- }
- }
- // This is the group id to use for permission requests.
- // Only group members may use this field.
- LLUUID group_proxy = LLUUID::null;
- if (group_id.notNull() && isInGroup(group_id))
- {
- group_proxy = group_id;
- }
- // We now have max ownership information.
- if (PERM_OWNER == op)
- {
- // This this was just a check for ownership, we can now return the answer.
- return (agent_proxy == owner_id);
- }
- return perm.allowOperationBy(op, agent_proxy, group_proxy);
- }
- const LLColor4 &LLAgent::getEffectColor()
- {
- return mEffectColor;
- }
- void LLAgent::setEffectColor(const LLColor4 &color)
- {
- mEffectColor = color;
- }
- void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
- {
- mAgentOriginGlobal = origin_global;
- }
- BOOL LLAgent::leftButtonGrabbed() const
- {
- return (!cameraMouselook() && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
- || (cameraMouselook() && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
- || (!cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
- || (cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
- }
- BOOL LLAgent::rotateGrabbed() const
- {
- return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0)
- || (mControlsTakenCount[CONTROL_YAW_NEG_INDEX] > 0);
- }
- BOOL LLAgent::forwardGrabbed() const
- {
- return (mControlsTakenCount[CONTROL_AT_POS_INDEX] > 0);
- }
- BOOL LLAgent::backwardGrabbed() const
- {
- return (mControlsTakenCount[CONTROL_AT_NEG_INDEX] > 0);
- }
- BOOL LLAgent::upGrabbed() const
- {
- return (mControlsTakenCount[CONTROL_UP_POS_INDEX] > 0);
- }
- BOOL LLAgent::downGrabbed() const
- {
- return (mControlsTakenCount[CONTROL_UP_NEG_INDEX] > 0);
- }
- void update_group_floaters(const LLUUID& group_id)
- {
-
- LLGroupActions::refresh(group_id);
- //*TODO Implement group update for Profile View
- // still actual as of July 31, 2009 (DZ)
- gAgent.fireEvent(new LLOldEvents::LLEvent(&gAgent, "new group"), "");
- }
- // static
- void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **)
- {
- LLUUID agent_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
- if (agent_id != gAgentID)
- {
- llwarns << "processAgentDropGroup for agent other than me" << llendl;
- return;
- }
- LLUUID group_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
- // Remove the group if it already exists remove it and add the new data to pick up changes.
- LLGroupData gd;
- gd.mID = group_id;
- S32 index = gAgent.mGroups.find(gd);
- if (index != -1)
- {
- gAgent.mGroups.remove(index);
- if (gAgent.getGroupID() == group_id)
- {
- gAgent.mGroupID.setNull();
- gAgent.mGroupPowers = 0;
- gAgent.mGroupName.clear();
- gAgent.mGroupTitle.clear();
- }
-
- // refresh all group information
- gAgent.sendAgentDataUpdateRequest();
- LLGroupMgr::getInstance()->clearGroupData(group_id);
- // close the floater for this group, if any.
- LLGroupActions::closeGroup(group_id);
- }
- else
- {
- llwarns << "processAgentDropGroup, agent is not part of group " << group_id << llendl;
- }
- }
- class LLAgentDropGroupViewerNode : public LLHTTPNode
- {
- virtual void post(
- LLHTTPNode::ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- if (
- !input.isMap() ||
- !input.has("body") )
- {
- //what to do with badly formed message?
- response->statusUnknownError(400);
- response->result(LLSD("Invalid message parameters"));
- }
- LLSD body = input["body"];
- if ( body.has("body") )
- {
- //stupid message system doubles up the "body"s
- body = body["body"];
- }
- if (
- body.has("AgentData") &&
- body["AgentData"].isArray() &&
- body["AgentData"][0].isMap() )
- {
- llinfos << "VALID DROP GROUP" << llendl;
- //there is only one set of data in the AgentData block
- LLSD agent_data = body["AgentData"][0];
- LLUUID agent_id;
- LLUUID group_id;
- agent_id = agent_data["AgentID"].asUUID();
- group_id = agent_data["GroupID"].asUUID();
- if (agent_id != gAgentID)
- {
- llwarns
- << "AgentDropGroup for agent other than me" << llendl;
- response->notFound();
- return;
- }
- // Remove the group if it already exists remove it
- // and add the new data to pick up changes.
- LLGroupData gd;
- gd.mID = group_id;
- S32 index = gAgent.mGroups.find(gd);
- if (index != -1)
- {
- gAgent.mGroups.remove(index);
- if (gAgent.getGroupID() == group_id)
- {
- gAgent.mGroupID.setNull();
- gAgent.mGroupPowers = 0;
- gAgent.mGroupName.clear();
- gAgent.mGroupTitle.clear();
- }
-
- // refresh all group information
- gAgent.sendAgentDataUpdateRequest();
- LLGroupMgr::getInstance()->clearGroupData(group_id);
- // close the floater for this group, if any.
- LLGroupActions::closeGroup(group_id);
- }
- else
- {
- llwarns
- << "AgentDropGroup, agent is not part of group "
- << group_id << llendl;
- }
- response->result(LLSD());
- }
- else
- {
- //what to do with badly formed message?
- response->statusUnknownError(400);
- response->result(LLSD("Invalid message parameters"));
- }
- }
- };
- LLHTTPRegistration<LLAgentDropGroupViewerNode>
- gHTTPRegistrationAgentDropGroupViewerNode(
- "/message/AgentDropGroup");
- // static
- void LLAgent::processAgentGroupDataUpdate(LLMessageSystem *msg, void **)
- {
- LLUUID agent_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
- if (agent_id != gAgentID)
- {
- llwarns << "processAgentGroupDataUpdate for agent other than me" << llendl;
- return;
- }
-
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
- LLGroupData group;
- S32 index = -1;
- bool need_floater_update = false;
- for(S32 i = 0; i < count; ++i)
- {
- msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group.mID, i);
- msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupInsigniaID, group.mInsigniaID, i);
- msg->getU64(_PREHASH_GroupData, "GroupPowers", group.mPowers, i);
- msg->getBOOL(_PREHASH_GroupData, "AcceptNotices", group.mAcceptNotices, i);
- msg->getS32(_PREHASH_GroupData, "Contribution", group.mContribution, i);
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group.mName, i);
-
- if(group.mID.notNull())
- {
- need_floater_update = true;
- // Remove the group if it already exists remove it and add the new data to pick up changes.
- index = gAgent.mGroups.find(group);
- if (index != -1)
- {
- gAgent.mGroups.remove(index);
- }
- gAgent.mGroups.put(group);
- }
- if (need_floater_update)
- {
- update_group_floaters(group.mID);
- }
- }
- }
- class LLAgentGroupDataUpdateViewerNode : public LLHTTPNode
- {
- virtual void post(
- LLHTTPNode::ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLSD body = input["body"];
- if(body.has("body"))
- body = body["body"];
- LLUUID agent_id = body["AgentData"][0]["AgentID"].asUUID();
- if (agent_id != gAgentID)
- {
- llwarns << "processAgentGroupDataUpdate for agent other than me" << llendl;
- return;
- }
- LLSD group_data = body["GroupData"];
- LLSD::array_iterator iter_group =
- group_data.beginArray();
- LLSD::array_iterator end_group =
- group_data.endArray();
- int group_index = 0;
- for(; iter_group != end_group; ++iter_group)
- {
- LLGroupData group;
- S32 index = -1;
- bool need_floater_update = false;
- group.mID = (*iter_group)["GroupID"].asUUID();
- group.mPowers = ll_U64_from_sd((*iter_group)["GroupPowers"]);
- group.mAcceptNotices = (*iter_group)["AcceptNotices"].asBoolean();
- group.mListInProfile = body["NewGroupData"][group_index]["ListInProfile"].asBoolean();
- group.mInsigniaID = (*iter_group)["GroupInsigniaID"].asUUID();
- group.mName = (*iter_group)["GroupName"].asString();
- group.mContribution = (*iter_group)["Contribution"].asInteger();
- group_index++;
- if(group.mID.notNull())
- {
- need_floater_update = true;
- // Remove the group if it already exists remove it and add the new data to pick up changes.
- index = gAgent.mGroups.find(group);
- if (index != -1)
- {
- gAgent.mGroups.remove(index);
- }
- gAgent.mGroups.put(group);
- }
- if (need_floater_update)
- {
- update_group_floaters(group.mID);
- }
- }
- }
- };
- LLHTTPRegistration<LLAgentGroupDataUpdateViewerNode >
- gHTTPRegistrationAgentGroupDataUpdateViewerNode ("/message/AgentGroupDataUpdate");
- // static
- void LLAgent::processAgentDataUpdate(LLMessageSystem *msg, void **)
- {
- LLUUID agent_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
- if (agent_id != gAgentID)
- {
- llwarns << "processAgentDataUpdate for agent other than me" << llendl;
- return;
- }
- msg->getStringFast(_PREHASH_AgentData, _PREHASH_GroupTitle, gAgent.mGroupTitle);
- LLUUID active_id;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_ActiveGroupID, active_id);
- if(active_id.notNull())
- {
- gAgent.mGroupID = active_id;
- msg->getU64(_PREHASH_AgentData, "GroupPowers", gAgent.mGroupPowers);
- msg->getString(_PREHASH_AgentData, _PREHASH_GroupName, gAgent.mGroupName);
- }
- else
- {
- gAgent.mGroupID.setNull();
- gAgent.mGroupPowers = 0;
- gAgent.mGroupName.clear();
- }
- update_group_floaters(active_id);
- }
- // static
- void LLAgent::processScriptControlChange(LLMessageSystem *msg, void **)
- {
- S32 block_count = msg->getNumberOfBlocks("Data");
- for (S32 block_index = 0; block_index < block_count; block_index++)
- {
- BOOL take_controls;
- U32 controls;
- BOOL passon;
- U32 i;
- msg->getBOOL("Data", "TakeControls", take_controls, block_index);
- if (take_controls)
- {
- // take controls
- msg->getU32("Data", "Controls", controls, block_index );
- msg->getBOOL("Data", "PassToAgent", passon, block_index );
- U32 total_count = 0;
- for (i = 0; i < TOTAL_CONTROLS; i++)
- {
- if (controls & ( 1 << i))
- {
- if (passon)
- {
- gAgent.mControlsTakenPassedOnCount[i]++;
- }
- else
- {
- gAgent.mControlsTakenCount[i]++;
- }
- total_count++;
- }
- }
-
- // Any control taken? If so, might be first time.
- //if (total_count > 0)
- //{
- //LLFirstUse::useOverrideKeys();
- //}
- }
- else
- {
- // release controls
- msg->getU32("Data", "Controls", controls, block_index );
- msg->getBOOL("Data", "PassToAgent", passon, block_index );
- for (i = 0; i < TOTAL_CONTROLS; i++)
- {
- if (controls & ( 1 << i))
- {
- if (passon)
- {
- gAgent.mControlsTakenPassedOnCount[i]--;
- if (gAgent.mControlsTakenPassedOnCount[i] < 0)
- {
- gAgent.mControlsTakenPassedOnCount[i] = 0;
- }
- }
- else
- {
- gAgent.mControlsTakenCount[i]--;
- if (gAgent.mControlsTakenCount[i] < 0)
- {
- gAgent.mControlsTakenCount[i] = 0;
- }
- }
- }
- }
- }
- }
- }
- /*
- // static
- void LLAgent::processControlTake(LLMessageSystem *msg, void **)
- {
- U32 controls;
- msg->getU32("Data", "Controls", controls );
- U32 passon;
- msg->getBOOL("Data", "PassToAgent", passon );
- S32 i;
- S32 total_count = 0;
- for (i = 0; i < TOTAL_CONTROLS; i++)
- {
- if (controls & ( 1 << i))
- {
- if (passon)
- {
- gAgent.mControlsTakenPassedOnCount[i]++;
- }
- else
- {
- gAgent.mControlsTakenCount[i]++;
- }
- total_count++;
- }
- }
- // Any control taken? If so, might be first time.
- if (total_count > 0)
- {
- LLFirstUse::useOverrideKeys();
- }
- }
- // static
- void LLAgent::processControlRelease(LLMessageSystem *msg, void **)
- {
- U32 controls;
- msg->getU32("Data", "Controls", controls );
- U32 passon;
- msg->getBOOL("Data", "PassToAgent", passon );
- S32 i;
- for (i = 0; i < TOTAL_CONTROLS; i++)
- {
- if (controls & ( 1 << i))
- {
- if (passon)
- {
- gAgent.mControlsTakenPassedOnCount[i]--;
- if (gAgent.mControlsTakenPassedOnCount[i] < 0)
- {
- gAgent.mControlsTakenPassedOnCount[i] = 0;
- }
- }
- else
- {
- gAgent.mControlsTakenCount[i]--;
- if (gAgent.mControlsTakenCount[i] < 0)
- {
- gAgent.mControlsTakenCount[i] = 0;
- }
- }
- }
- }
- }
- */
- //static
- void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)
- {
- gAgentQueryManager.mNumPendingQueries--;
- LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
- if (!avatarp || avatarp->isDead())
- {
- llwarns << "No avatar for user in cached texture update!" << llendl;
- return;
- }
- if (gAgent.cameraCustomizeAvatar())
- {
- // ignore baked textures when in customize mode
- return;
- }
- S32 query_id;
- mesgsys->getS32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, query_id);
- S32 num_texture_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_WearableData);
- S32 num_results = 0;
- for (S32 texture_block = 0; texture_block < num_texture_blocks; texture_block++)
- {
- LLUUID texture_id;
- U8 texture_index;
- mesgsys->getUUIDFast(_PREHASH_WearableData, _PREHASH_TextureID, texture_id, texture_block);
- mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);
- if (texture_id.notNull()
- && (S32)texture_index < BAKED_NUM_INDICES
- && gAgentQueryManager.mActiveCacheQueries[texture_index] == query_id)
- {
- //llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
- avatarp->setCachedBakedTexture(LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)texture_index), texture_id);
- //avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
- gAgentQueryManager.mActiveCacheQueries[texture_index] = 0;
- num_results++;
- }
- }
- llinfos << "Received cached texture response for " << num_results << " textures." << llendl;
- avatarp->updateMeshTextures();
- if (gAgentQueryManager.mNumPendingQueries == 0)
- {
- // RN: not sure why composites are disabled at this point
- avatarp->setCompositeUpdatesEnabled(TRUE);
- gAgent.sendAgentSetAppearance();
- }
- }
- BOOL LLAgent::anyControlGrabbed() const
- {
- for (U32 i = 0; i < TOTAL_CONTROLS; i++)
- {
- if (gAgent.mControlsTakenCount[i] > 0)
- return TRUE;
- if (gAgent.mControlsTakenPassedOnCount[i] > 0)
- return TRUE;
- }
- return FALSE;
- }
- BOOL LLAgent::isControlGrabbed(S32 control_index) const
- {
- return mControlsTakenCount[control_index] > 0;
- }
- void LLAgent::forceReleaseControls()
- {
- gMessageSystem->newMessage("ForceScriptControlRelease");
- gMessageSystem->nextBlock("AgentData");
- gMessageSystem->addUUID("AgentID", getID());
- gMessageSystem->addUUID("SessionID", getSessionID());
- sendReliableMessage();
- }
- void LLAgent::setHomePosRegion( const U64& region_handle, const LLVector3& pos_region)
- {
- mHaveHomePosition = TRUE;
- mHomeRegionHandle = region_handle;
- mHomePosRegion = pos_region;
- }
- BOOL LLAgent::getHomePosGlobal( LLVector3d* pos_global )
- {
- if(!mHaveHomePosition)
- {
- return FALSE;
- }
- F32 x = 0;
- F32 y = 0;
- from_region_handle( mHomeRegionHandle, &x, &y);
- pos_global->setVec( x + mHomePosRegion.mV[VX], y + mHomePosRegion.mV[VY], mHomePosRegion.mV[VZ] );
- return TRUE;
- }
- void LLAgent::clearVisualParams(void *data)
- {
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
- if (avatarp)
- {
- avatarp->clearVisualParamWeights();
- avatarp->updateVisualParams();
- }
- }
- //---------------------------------------------------------------------------
- // Teleport
- //---------------------------------------------------------------------------
- // teleportCore() - stuff to do on any teleport
- // protected
- bool LLAgent::teleportCore(bool is_local)
- {
- if(TELEPORT_NONE != mTeleportState)
- {
- llwarns << "Attempt to teleport when already teleporting." << llendl;
- return false;
- }
- #if 0
- // This should not exist. It has been added, removed, added, and now removed again.
- // This change needs to come from the simulator. Otherwise, the agent ends up out of
- // sync with other viewers. Discuss in DEV-14145/VWR-6744 before reenabling.
- // Stop all animation before actual teleporting
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
- if (avatarp)
- {
- for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin();
- anim_it != avatarp->mPlayingAnimations.end();
- ++anim_it)
- {
- avatarp->stopMotion(anim_it->first);
- }
- avatarp->processAnimationStateChanges();
- }
- #endif
- // Don't call LLFirstUse::useTeleport because we don't know
- // yet if the teleport will succeed. Look in
- // process_teleport_location_reply
- // close the map and find panels so we can see our destination
- LLFloaterReg::hideInstance("world_map");
- LLFloaterReg::hideInstance("search");
- // hide land floater too - it'll be out of date
- LLFloaterReg::hideInstance("about_land");
- LLViewerParcelMgr::getInstance()->deselectLand();
- LLViewerMediaFocus::getInstance()->clearFocus();
- // Close all pie menus, deselect land, etc.
- // Don't change the camera until we know teleport succeeded. JC
- resetView(FALSE);
- // local logic
- LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
- if (!is_local)
- {
- gTeleportDisplay = TRUE;
- gAgent.setTeleportState( LLAgent::TELEPORT_START );
- //release geometry from old location
- gPipeline.resetVertexBuffers();
- }
- make_ui_sound("UISndTeleportOut");
-
- // MBW -- Let the voice client know a teleport has begun so it can leave the existing channel.
- // This was breaking the case of teleporting within a single sim. Backing it out for now.
- // gVoiceClient->leaveChannel();
-
- return true;
- }
- void LLAgent::teleportRequest(
- const U64& region_handle,
- const LLVector3& pos_local)
- {
- LLViewerRegion* regionp = getRegion();
- if(regionp && teleportCore())
- {
- llinfos << "TeleportRequest: '" << region_handle << "':" << pos_local
- << llendl;
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("TeleportLocationRequest");
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- msg->nextBlockFast(_PREHASH_Info);
- msg->addU64("RegionHandle", region_handle);
- msg->addVector3("Position", pos_local);
- LLVector3 look_at(0,1,0);
- msg->addVector3("LookAt", look_at);
- sendReliableMessage();
- }
- }
- // Landmark ID = LLUUID::null means teleport home
- void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
- {
- LLViewerRegion *regionp = getRegion();
- if(regionp && teleportCore())
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_TeleportLandmarkRequest);
- msg->nextBlockFast(_PREHASH_Info);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- msg->addUUIDFast(_PREHASH_LandmarkID, landmark_asset_id);
- sendReliableMessage();
- }
- }
- void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
- {
- LLViewerRegion* regionp = getRegion();
- if(regionp && teleportCore())
- {
- U32 teleport_flags = 0x0;
- if (godlike)
- {
- teleport_flags |= TELEPORT_FLAGS_VIA_GODLIKE_LURE;
- teleport_flags |= TELEPORT_FLAGS_DISABLE_CANCEL;
- }
- else
- {
- teleport_flags |= TELEPORT_FLAGS_VIA_LURE;
- }
- // send the message
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_TeleportLureRequest);
- msg->nextBlockFast(_PREHASH_Info);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- msg->addUUIDFast(_PREHASH_LureID, lure_id);
- // teleport_flags is a legacy field, now derived sim-side:
- msg->addU32("TeleportFlags", teleport_flags);
- sendReliableMessage();
- }
- }
- // James Cook, July 28, 2005
- void LLAgent::teleportCancel()
- {
- LLViewerRegion* regionp = getRegion();
- if(regionp)
- {
- // send the message
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage("TeleportCancel");
- msg->nextBlockFast(_PREHASH_Info);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- sendReliableMessage();
- }
- gTeleportDisplay = FALSE;
- gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
- }
- void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
- {
- LLViewerRegion* regionp = getRegion();
- U64 handle = to_region_handle(pos_global);
- LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle);
- if(regionp && info)
- {
- LLVector3d region_origin = info->getGlobalOrigin();
- LLVector3 pos_local(
- (F32)(pos_global.mdV[VX] - region_origin.mdV[VX]),
- (F32)(pos_global.mdV[VY] - region_origin.mdV[VY]),
- (F32)(pos_global.mdV[VZ]));
- teleportRequest(handle, pos_local);
- }
- else if(regionp &&
- teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
- {
- llwarns << "Using deprecated teleportlocationrequest." << llendl;
- // send the message
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_TeleportLocationRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- msg->nextBlockFast(_PREHASH_Info);
- F32 width = regionp->getWidth();
- LLVector3 pos(fmod((F32)pos_global.mdV[VX], width),
- fmod((F32)pos_global.mdV[VY], width),
- (F32)pos_global.mdV[VZ]);
- F32 region_x = (F32)(pos_global.mdV[VX]);
- F32 region_y = (F32)(pos_global.mdV[VY]);
- U64 region_handle = to_region_handle_global(region_x, region_y);
- msg->addU64Fast(_PREHASH_RegionHandle, region_handle);
- msg->addVector3Fast(_PREHASH_Position, pos);
- pos.mV[VX] += 1;
- msg->addVector3Fast(_PREHASH_LookAt, pos);
- sendReliableMessage();
- }
- }
- void LLAgent::setTeleportState(ETeleportState state)
- {
- mTeleportState = state;
- if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
- {
- LLFloaterReg::hideInstance("snapshot");
- }
- if (mTeleportState == TELEPORT_MOVING)
- {
- // We're outa here. Save "back" slurl.
- mTeleportSourceSLURL = LLAgentUI::buildSLURL();
- }
- else if(mTeleportState == TELEPORT_ARRIVING)
- {
- // Let the interested parties know we've teleported.
- LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
- }
- }
- void LLAgent::stopCurrentAnimations()
- {
- // This function stops all current overriding animations on this
- // avatar, propagating this change back to the server.
- LLVOAvatar* avatarp = gAgent.getAvatarObject();
- if (avatarp)
- {
- for ( LLVOAvatar::AnimIterator anim_it =
- avatarp->mPlayingAnimations.begin();
- anim_it != avatarp->mPlayingAnimations.end();
- anim_it++)
- {
- if (anim_it->first ==
- ANIM_AGENT_SIT_GROUND_CONSTRAINED)
- {
- // don't cancel a ground-sit anim, as viewers
- // use this animation's status in
- // determining whether we're sitting. ick.
- }
- else
- {
- // stop this animation locally
- avatarp->stopMotion(anim_it->first, TRUE);
- // ...and tell the server to tell everyone.
- sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP);
- }
- }
- // re-assert at least the default standing animation, because
- // viewers get confused by avs with no associated anims.
- sendAnimationRequest(ANIM_AGENT_STAND,
- ANIM_REQUEST_START);
- }
- }
- void LLAgent::fidget()
- {
- if (!getAFK())
- {
- F32 curTime = mFidgetTimer.getElapsedTimeF32();
- if (curTime > mNextFidgetTime)
- {
- // pick a random fidget anim here
- S32 oldFidget = mCurrentFidget;
- mCurrentFidget = ll_rand(NUM_AGENT_STAND_ANIMS);
- if (mCurrentFidget != oldFidget)
- {
- LLAgent::stopFidget();
-
- switch(mCurrentFidget)
- {
- case 0:
- mCurrentFidget = 0;
- break;
- case 1:
- sendAnimationRequest(ANIM_AGENT_STAND_1, ANIM_REQUEST_START);
- mCurrentFidget = 1;
- break;
- case 2:
- sendAnimationRequest(ANIM_AGENT_STAND_2, ANIM_REQUEST_START);
- mCurrentFidget = 2;
- break;
- case 3:
- sendAnimationRequest(ANIM_AGENT_STAND_3, ANIM_REQUEST_START);
- mCurrentFidget = 3;
- break;
- case 4:
- sendAnimationRequest(ANIM_AGENT_STAND_4, ANIM_REQUEST_START);
- mCurrentFidget = 4;
- break;
- }
- }
- // calculate next fidget time
- mNextFidgetTime = curTime + ll_frand(MAX_FIDGET_TIME - MIN_FIDGET_TIME) + MIN_FIDGET_TIME;
- }
- }
- }
- void LLAgent::stopFidget()
- {
- LLDynamicArray<LLUUID> anims;
- anims.put(ANIM_AGENT_STAND_1);
- anims.put(ANIM_AGENT_STAND_2);
- anims.put(ANIM_AGENT_STAND_3);
- anims.put(ANIM_AGENT_STAND_4);
- gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP);
- }
- void LLAgent::requestEnterGodMode()
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RequestGodlikePowers);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_RequestBlock);
- msg->addBOOLFast(_PREHASH_Godlike, TRUE);
- msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
- // simulators need to know about your request
- sendReliableMessage();
- }
- void LLAgent::requestLeaveGodMode()
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RequestGodlikePowers);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_RequestBlock);
- msg->addBOOLFast(_PREHASH_Godlike, FALSE);
- msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
- // simulator needs to know about your request
- sendReliableMessage();
- }
- //-----------------------------------------------------------------------------
- // sendAgentSetAppearance()
- //-----------------------------------------------------------------------------
- void LLAgent::sendAgentSetAppearance()
- {
- if (mAvatarObject.isNull()) return;
- if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar())
- {
- return;
- }
- llinfos << "TAT: Sent AgentSetAppearance: " << mAvatarObject->getBakedStatusForPrintout() << llendl;
- //dumpAvatarTEs( "sendAgentSetAppearance()" );
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_AgentSetAppearance);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, getID());
- msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
- // correct for the collision tolerance (to make it look like the
- // agent is actually walking on the ground/object)
- // NOTE -- when we start correcting all of the other Havok geometry
- // to compensate for the COLLISION_TOLERANCE ugliness we will have
- // to tweak this number again
- const LLVector3 body_size = mAvatarObject->mBodySize;
- msg->addVector3Fast(_PREHASH_Size, body_size);
- // To guard against out of order packets
- // Note: always start by sending 1. This resets the server's count. 0 on the server means "uninitialized"
- mAppearanceSerialNum++;
- msg->addU32Fast(_PREHASH_SerialNum, mAppearanceSerialNum );
- // is texture data current relative to wearables?
- // KLW - TAT this will probably need to check the local queue.
- BOOL textures_current = mAvatarObject->areTexturesCurrent();
- for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
- {
- const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
- // if we're not wearing a skirt, we don't need the texture to be baked
- if (texture_index == TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT))
- {
- continue;
- }
- // IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
- if (!mAvatarObject->isTextureDefined(texture_index, 0))
- {
- textures_current = FALSE;
- break;
- }
- }
- // only update cache entries if we have all our baked textures
- if (textures_current)
- {
- llinfos << "TAT: Sending cached texture data" << llendl;
- for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
- {
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
- LLUUID hash;
- for (U8 i=0; i < baked_dict->mWearables.size(); i++)
- {
- // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num];
- const EWearableType wearable_type = baked_dict->mWearables[i];
- // MULTI-WEARABLE: fixed to 0th - extend to everything once messaging works.
- const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,0);
- if (wearable)
- {
- hash ^= wearable->getAssetID();
- }
- }
- if (hash.notNull())
- {
- hash ^= baked_dict->mWearablesHashID;
- }
- const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
- msg->nextBlockFast(_PREHASH_WearableData);
- msg->addUUIDFast(_PREHASH_CacheID, hash);
- msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
- }
- msg->nextBlockFast(_PREHASH_ObjectData);
- mAvatarObject->sendAppearanceMessage( gMessageSystem );
- }
- else
- {
- // If the textures aren't baked, send NULL for texture IDs
- // This means the baked texture IDs on the server will be untouched.
- // Once all textures are baked, another AvatarAppearance message will be sent to update the TEs
- msg->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addBinaryDataFast(_PREHASH_TextureEntry, NULL, 0);
- }
- S32 transmitted_params = 0;
- for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam();
- param;
- param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam())
- {
- if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
- {
- msg->nextBlockFast(_PREHASH_VisualParam );
-
- // We don't send the param ids. Instead, we assume that the receiver has the same params in the same sequence.
- const F32 param_value = param->getWeight();
- const U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight());
- msg->addU8Fast(_PREHASH_ParamValue, new_weight );
- transmitted_params++;
- }
- }
- // llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
- sendReliableMessage();
- }
- void LLAgent::sendAgentDataUpdateRequest()
- {
- gMessageSystem->newMessageFast(_PREHASH_AgentDataUpdateRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- sendReliableMessage();
- }
- void LLAgent::sendAgentUserInfoRequest()
- {
- if(getID().isNull())
- return; // not logged in
- gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
- sendReliableMessage();
- }
- void LLAgent::observeFriends()
- {
- if(!mFriendObserver)
- {
- mFriendObserver = new LLAgentFriendObserver;
- LLAvatarTracker::instance().addObserver(mFriendObserver);
- friendsChanged();
- }
- }
- void LLAgent::parseTeleportMessages(const std::string& xml_filename)
- {
- LLXMLNodePtr root;
- BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
- if (!success || !root || !root->hasName( "teleport_messages" ))
- {
- llerrs << "Problem reading teleport string XML file: "
- << xml_filename << llendl;
- return;
- }
- for (LLXMLNode* message_set = root->getFirstChild();
- message_set != NULL;
- message_set = message_set->getNextSibling())
- {
- if ( !message_set->hasName("message_set") ) continue;
- std::map<std::string, std::string> *teleport_msg_map = NULL;
- std::string message_set_name;
- if ( message_set->getAttributeString("name", message_set_name) )
- {
- //now we loop over all the string in the set and add them
- //to the appropriate set
- if ( message_set_name == "errors" )
- {
- teleport_msg_map = &sTeleportErrorMessages;
- }
- else if ( message_set_name == "progress" )
- {
- teleport_msg_map = &sTeleportProgressMessages;
- }
- }
- if ( !teleport_msg_map ) continue;
- std::string message_name;
- for (LLXMLNode* message_node = message_set->getFirstChild();
- message_node != NULL;
- message_node = message_node->getNextSibling())
- {
- if ( message_node->hasName("message") &&
- message_node->getAttributeString("name", message_name) )
- {
- (*teleport_msg_map)[message_name] =
- message_node->getTextContents();
- } //end if ( message exists and has a name)
- } //end for (all message in set)
- }//end for (all message sets in xml file)
- }
- void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )
- {
- gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_UserData);
- gMessageSystem->addBOOLFast(_PREHASH_IMViaEMail, im_via_email);
- gMessageSystem->addString("DirectoryVisibility", directory_visibility);
- gAgent.sendReliableMessage();
- }
- // static
- void LLAgent::dumpGroupInfo()
- {
- llinfos << "group " << gAgent.mGroupName << llendl;
- llinfos << "ID " << gAgent.mGroupID << llendl;
- llinfos << "powers " << gAgent.mGroupPowers << llendl;
- llinfos << "title " << gAgent.mGroupTitle << llendl;
- //llinfos << "insig " << gAgent.mGroupInsigniaID << llendl;
- }
- /********************************************************************************/
- LLAgentQueryManager gAgentQueryManager;
- LLAgentQueryManager::LLAgentQueryManager() :
- mWearablesCacheQueryID(0),
- mNumPendingQueries(0),
- mUpdateSerialNum(0)
- {
- for (U32 i = 0; i < BAKED_NUM_INDICES; i++)
- {
- mActiveCacheQueries[i] = 0;
- }
- }
- LLAgentQueryManager::~LLAgentQueryManager()
- {
- }
- // EOF