diff options
author | Bryan O'Sullivan <bos@lindenlab.com> | 2009-06-22 15:02:19 -0700 |
---|---|---|
committer | Bryan O'Sullivan <bos@lindenlab.com> | 2009-06-22 15:02:19 -0700 |
commit | baa73fddd9287ddafd2d31551cb253b355ed910a (patch) | |
tree | e3f0986617fe6c0ee0a14df6aac13c6bb6f92507 /indra/newview/llagent.cpp | |
parent | dc3833f31b8a20220ddb1775e1625c016c397435 (diff) | |
parent | fcaa1ad46fd1df4cfec9dee12caf6e7b5bf32136 (diff) |
Merge with viewer-2.0.0-3 branch
Diffstat (limited to 'indra/newview/llagent.cpp')
-rw-r--r-- | indra/newview/llagent.cpp | 1828 |
1 files changed, 288 insertions, 1540 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index f97f9f607f..a70d31431f 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -32,110 +32,69 @@ #include "llviewerprecompiledheaders.h" -#include "stdtypes.h" -#include "stdenums.h" - #include "llagent.h" +#include "llagentwearables.h" -#include "llcamera.h" -#include "llcoordframe.h" -#include "indra_constants.h" -#include "llmath.h" -#include "llcriticaldamp.h" -#include "llfocusmgr.h" -#include "llglheaders.h" -#include "llmenugl.h" -#include "llparcel.h" -#include "llpermissions.h" -#include "llregionhandle.h" -#include "m3math.h" -#include "m4math.h" -#include "message.h" -#include "llquaternion.h" -#include "v3math.h" -#include "v4math.h" -#include "llsmoothstep.h" -#include "llsdutil.h" -//#include "vmath.h" - -#include "imageids.h" -#include "llbox.h" -#include "llbutton.h" +#include "llanimationstates.h" #include "llcallingcard.h" #include "llchatbar.h" #include "llconsole.h" #include "lldrawable.h" -#include "llface.h" #include "llfirstuse.h" -#include "llfloater.h" #include "llfloaterreg.h" #include "llfloateractivespeakers.h" #include "llfloateravatarinfo.h" -#include "llfloaterbuildoptions.h" #include "llfloatercamera.h" -#include "llfloaterchat.h" #include "llfloatercustomize.h" #include "llfloaterdirectory.h" #include "llfloatergroupinfo.h" -#include "llfloatergroups.h" #include "llfloaterland.h" #include "llfloatermute.h" #include "llfloatersnapshot.h" #include "llfloatertools.h" #include "llfloaterworldmap.h" + +#include "llfocusmgr.h" #include "llgroupmgr.h" #include "llhomelocationresponder.h" -#include "llhudeffectlookat.h" +#include "llimview.h" #include "llhudmanager.h" -#include "llinventorymodel.h" -#include "llinventoryview.h" #include "lljoystickbutton.h" #include "llmenugl.h" #include "llmorphview.h" #include "llmoveview.h" -#include "llteleporthistory.h" -#include "llnotify.h" -#include "llquantize.h" +#include "llparcel.h" #include "llsdutil.h" #include "llselectmgr.h" #include "llsky.h" #include "llslurl.h" -#include "llrendersphere.h" +#include "llsmoothstep.h" +#include "llsidetray.h" #include "llstatusbar.h" -#include "llstartup.h" -#include "llimview.h" +#include "llteleporthistory.h" #include "lltool.h" #include "lltoolcomp.h" -#include "lltoolfocus.h" -#include "lltoolgrab.h" #include "lltoolmgr.h" -#include "lltoolpie.h" -#include "llui.h" // for make_ui_sound +#include "lluictrlfactory.h" +#include "llurldispatcher.h" + #include "llviewercamera.h" -#include "llviewerinventory.h" -#include "llviewermenu.h" -#include "llviewernetwork.h" +#include "llviewerdisplay.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" -#include "llviewerparceloverlay.h" -#include "llviewerregion.h" #include "llviewerstats.h" #include "llviewerwindow.h" -#include "llviewerdisplay.h" -#include "llvoavatar.h" -#include "llvoground.h" -#include "llvosky.h" -#include "llwearable.h" -#include "llwearablelist.h" +#include "llviewercontrol.h" +#include "llviewerjoystick.h" + +#include "llvoavatarself.h" +#include "llwindow.h" #include "llworld.h" #include "llworldmap.h" + #include "pipeline.h" -#include "roles_constants.h" -#include "llviewercontrol.h" -#include "llappviewer.h" -#include "llviewerjoystick.h" -#include "llfollowcam.h" #include "lltrans.h" +#include "llbottomtray.h" #include "stringize.h" #include "llcapabilitylistener.h" @@ -145,6 +104,10 @@ using namespace LLVOAvatarDefines; extern LLMenuBarGL* gMenuBarView; +const BOOL ANIMATE = TRUE; +const U8 AGENT_STATE_TYPING = 0x04; +const U8 AGENT_STATE_EDITING = 0x10; + //drone wandering constants const F32 MAX_WANDER_TIME = 20.f; // seconds const F32 MAX_HEADING_HALF_ERROR = 0.2f; // radians @@ -220,7 +183,7 @@ const F64 CHAT_AGE_FAST_RATE = 3.0; // The agent instance. LLAgent gAgent; -// +//-------------------------------------------------------------------- // Statics // @@ -259,7 +222,6 @@ bool handleSlowMotionAnimation(const LLSD& newvalue) return true; } - // ************************************************************ // Enabled this definition to compile a 'hacked' viewer that // locally believes the end user has godlike powers. @@ -282,19 +244,12 @@ LLAgent::LLAgent() : mHideGroupTitle(FALSE), mGroupID(), - mMapOriginX(0.F), - mMapOriginY(0.F), - mMapWidth(0), - mMapHeight(0), - mLookAt(NULL), mPointAt(NULL), mHUDTargetZoom(1.f), mHUDCurZoom(1.f), mInitialized(FALSE), - mNumPendingQueries(0), - mActiveCacheQueries(NULL), mForceMouselook(FALSE), mDoubleTapRunTimer(), @@ -413,9 +368,6 @@ LLAgent::LLAgent() : mFirstLogin(FALSE), mGenderChosen(FALSE), - mAgentWearablesUpdateSerialNum(0), - mWearablesLoaded(FALSE), - mTextureCacheQueryID(0), mAppearanceSerialNum(0) { for (U32 i = 0; i < TOTAL_CONTROLS; i++) @@ -424,12 +376,6 @@ LLAgent::LLAgent() : mControlsTakenPassedOnCount[i] = 0; } - mActiveCacheQueries = new S32[BAKED_NUM_INDICES]; - for (U32 i = 0; i < (U32)BAKED_NUM_INDICES; i++) - { - mActiveCacheQueries[i] = 0; - } - mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT ); } @@ -450,7 +396,7 @@ void LLAgent::init() // Leave at 0.1 meters until we have real near clip management LLViewerCamera::getInstance()->setNear(0.1f); LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h - LLViewerCamera::getInstance()->setAspect( gViewerWindow->getDisplayAspectRatio() ); // default, overridden in LLViewerWindow::reshape + LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape setFlying( gSavedSettings.getBOOL("FlyingAtExit") ); @@ -464,7 +410,7 @@ void LLAgent::init() mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); mEffectColor = gSavedSkinSettings.getColor4("EffectColor"); - + gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); @@ -477,7 +423,9 @@ void LLAgent::init() void LLAgent::cleanup() { setSitCamera(LLUUID::null); + mAvatarObject = NULL; + if(mLookAt) { mLookAt->markDead() ; @@ -499,9 +447,6 @@ LLAgent::~LLAgent() { cleanup(); - delete [] mActiveCacheQueries; - mActiveCacheQueries = NULL; - // *Note: this is where LLViewerCamera::getInstance() used to be deleted. } @@ -549,7 +494,7 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) { LLViewerJoystick::getInstance()->moveAvatar(true); } - + LLFloaterReg::hideInstance("build"); gViewerWindow->showCursor(); @@ -1350,167 +1295,171 @@ LLQuaternion LLAgent::getQuat() const //----------------------------------------------------------------------------- // calcFocusOffset() //----------------------------------------------------------------------------- -LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y) +LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y) { - // calculate offset based on view direction - BOOL is_avatar = object->isAvatar(); - LLMatrix4 obj_matrix = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldMatrix() : object->getRenderMatrix(); - LLQuaternion obj_rot = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldRotation() : object->getRenderRotation(); - LLVector3 obj_pos = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldPosition() : object->getRenderPosition(); - LLQuaternion inv_obj_rot = ~obj_rot; + LLMatrix4 obj_matrix = object->getRenderMatrix(); + LLQuaternion obj_rot = object->getRenderRotation(); + LLVector3 obj_pos = object->getRenderPosition(); - LLVector3 obj_dir_abs = obj_pos - LLViewerCamera::getInstance()->getOrigin(); - obj_dir_abs.rotVec(inv_obj_rot); - obj_dir_abs.normalize(); - obj_dir_abs.abs(); + BOOL is_avatar = object->isAvatar(); + // if is avatar - don't do any funk heuristics to position the focal point + // see DEV-30589 + if (is_avatar) + { + return original_focus_point - obj_pos; + } + + LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation LLVector3 object_extents = object->getScale(); // make sure they object extents are non-zero object_extents.clamp(0.001f, F32_MAX); - LLVector3 object_half_extents = object_extents * 0.5f; - obj_dir_abs.mV[VX] = obj_dir_abs.mV[VX] / object_extents.mV[VX]; - obj_dir_abs.mV[VY] = obj_dir_abs.mV[VY] / object_extents.mV[VY]; - obj_dir_abs.mV[VZ] = obj_dir_abs.mV[VZ] / object_extents.mV[VZ]; + // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object + LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin(); + obj_to_cam_ray.rotVec(inv_obj_rot); + obj_to_cam_ray.normalize(); - LLVector3 normal; - if (obj_dir_abs.mV[VX] > obj_dir_abs.mV[VY] && obj_dir_abs.mV[VX] > obj_dir_abs.mV[VZ]) + // obj_to_cam_ray_proportions are the (positive) ratios of + // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions. + LLVector3 obj_to_cam_ray_proportions; + obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]); + obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]); + obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]); + + // find the largest ratio stored in obj_to_cam_ray_proportions + // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera + LLVector3 longest_object_axis; + // is x-axis longest? + if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY] + && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ]) { - normal.setVec(obj_matrix.getFwdRow4()); + // then grab it + longest_object_axis.setVec(obj_matrix.getFwdRow4()); } - else if (obj_dir_abs.mV[VY] > obj_dir_abs.mV[VZ]) + // is y-axis longest? + else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ]) { - normal.setVec(obj_matrix.getLeftRow4()); + // then grab it + longest_object_axis.setVec(obj_matrix.getLeftRow4()); } + // otherwise, use z axis else { - normal.setVec(obj_matrix.getUpRow4()); + longest_object_axis.setVec(obj_matrix.getUpRow4()); } - normal.normalize(); + + // Use this axis as the normal to project mouse click on to plane with that normal, at the object center. + // This generates a point behind the mouse cursor that is approximately in the middle of the object in + // terms of depth. + // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera. + // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable + // eccentricity to the object orientation + LLVector3 focus_plane_normal(longest_object_axis); + focus_plane_normal.normalize(); LLVector3d focus_pt_global; - // RN: should we check return value for valid pick? - gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), normal); + gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal); LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global); - // find vector from camera to focus point in object coordinates - LLVector3 camera_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin(); - // convert to object-local space - camera_focus_vec.rotVec(inv_obj_rot); + + // find vector from camera to focus point in object space + LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin(); + camera_to_focus_vec.rotVec(inv_obj_rot); // find vector from object origin to focus point in object coordinates - LLVector3 focus_delta = focus_pt - obj_pos; + LLVector3 focus_offset_from_object_center = focus_pt - obj_pos; // convert to object-local space - focus_delta.rotVec(inv_obj_rot); + focus_offset_from_object_center.rotVec(inv_obj_rot); - // calculate clip percentage needed to get focus offset back in bounds along the camera_focus axis + // We need to project the focus point back into the bounding box of the focused object. + // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis LLVector3 clip_fraction; + // for each axis... for (U32 axis = VX; axis <= VZ; axis++) { - F32 clip_amt; - if (focus_delta.mV[axis] > 0.f) + //...calculate distance that focus offset sits outside of bounding box along that axis... + //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center + F32 dist_out_of_bounds; + if (focus_offset_from_object_center.mV[axis] > 0.f) { - clip_amt = llmax(0.f, focus_delta.mV[axis] - object_half_extents.mV[axis]); + dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f)); } else { - clip_amt = llmin(0.f, focus_delta.mV[axis] + object_half_extents.mV[axis]); + dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f)); } - // don't divide by very small nunber - if (llabs(camera_focus_vec.mV[axis]) < 0.0001f) + //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis + if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f) { + // don't divide by very small number clip_fraction.mV[axis] = 0.f; } else { - clip_fraction.mV[axis] = clip_amt / camera_focus_vec.mV[axis]; + clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis]; } } LLVector3 abs_clip_fraction = clip_fraction; abs_clip_fraction.abs(); - // find greatest shrinkage factor and + // find axis of focus offset that is *most* outside the bounding box and use that to // rescale focus offset to inside object extents - if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY] && - abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ]) + if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY] + && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ]) { - focus_delta -= clip_fraction.mV[VX] * camera_focus_vec; + focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec; } else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ]) { - focus_delta -= clip_fraction.mV[VY] * camera_focus_vec; + focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec; } else { - focus_delta -= clip_fraction.mV[VZ] * camera_focus_vec; + focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec; } // convert back to world space - focus_delta.rotVec(obj_rot); + focus_offset_from_object_center.rotVec(obj_rot); + // now, based on distance of camera from object relative to object size + // push the focus point towards the near surface of the object when (relatively) close to the objcet + // or keep the focus point in the object middle when (relatively) far + // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars + // is almost always "tumble about middle" and not "spin around surface point" if (!is_avatar) { - //unproject relative clicked coordinate from window coordinate using GL - /*GLint viewport[4]; - GLdouble modelview[16]; - GLdouble projection[16]; - GLfloat winX, winY, winZ; - GLdouble posX, posY, posZ; - - // convert our matrices to something that has a multiply that works - glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix); - glh::matrix4f tmpObjMat((F32*)obj_matrix.mMatrix); - newModel *= tmpObjMat; - - for(U32 i = 0; i < 16; ++i) - { - modelview[i] = newModel.m[i]; - projection[i] = LLViewerCamera::getInstance()->getProjection().mMatrix[i/4][i%4]; - } - glGetIntegerv( GL_VIEWPORT, viewport ); - - winX = ((F32)x) * gViewerWindow->getDisplayScale().mV[VX]; - winY = ((F32)y) * gViewerWindow->getDisplayScale().mV[VY]; - glReadPixels( llfloor(winX), llfloor(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ ); - - gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);*/ - - LLVector3 obj_rel = pos_agent - object->getRenderPosition(); + LLVector3 obj_rel = original_focus_point - object->getRenderPosition(); - LLVector3 obj_center = LLVector3(0, 0, 0) * object->getRenderMatrix(); - //now that we have the object relative position, we should bias toward the center of the object //based on the distance of the camera to the focus point vs. the distance of the camera to the focus F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis()); - F32 viewDist = dist_vec(obj_center + obj_rel, LLViewerCamera::getInstance()->getOrigin()); + F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin()); LLBBox obj_bbox = object->getBoundingBoxAgent(); F32 bias = 0.f; + // virtual_camera_pos is the camera position we are simulating by backing the camera off + // and adjusting the FOV LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor)); - if(obj_bbox.containsPointAgent(virtual_camera_pos)) - { - // if the camera is inside the object (large, hollow objects, for example) - // force focus point all the way to destination depth, away from object center - bias = 1.f; - } - else + // if the camera is inside the object (large, hollow objects, for example) + // leave focus point all the way to destination depth, away from object center + if(!obj_bbox.containsPointAgent(virtual_camera_pos)) { // perform magic number biasing of focus point towards surface vs. planar center bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f); + obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias); } - - obj_rel = lerp(focus_delta, obj_rel, bias); - - return LLVector3(obj_rel); + + focus_offset_from_object_center = obj_rel; } - return LLVector3(focus_delta.mV[VX], focus_delta.mV[VY], focus_delta.mV[VZ]); + return focus_offset_from_object_center; } //----------------------------------------------------------------------------- @@ -2200,7 +2149,7 @@ void LLAgent::setBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy")); } - LLFloaterMute::getInstance()->updateButtons(); + LLFloaterReg::getTypedInstance<LLFloaterMute>("mute")->updateButtons(); } //----------------------------------------------------------------------------- @@ -2214,7 +2163,7 @@ void LLAgent::clearBusy() { gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy")); } - LLFloaterMute::getInstance()->updateButtons(); + LLFloaterReg::getTypedInstance<LLFloaterMute>("mute")->updateButtons(); } //----------------------------------------------------------------------------- @@ -2694,7 +2643,7 @@ std::ostream& operator<<(std::ostream &s, const LLAgent &agent) //----------------------------------------------------------------------------- // setAvatarObject() //----------------------------------------------------------------------------- -void LLAgent::setAvatarObject(LLVOAvatar *avatar) +void LLAgent::setAvatarObject(LLVOAvatarSelf *avatar) { mAvatarObject = avatar; @@ -2721,8 +2670,6 @@ void LLAgent::setAvatarObject(LLVOAvatar *avatar) { mPointAt->setSourceObject(avatar); } - - sendAgentWearablesRequest(); } // TRUE if your own avatar needs to be rendered. Usually only @@ -2773,7 +2720,7 @@ void LLAgent::startTyping() { sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START); } - gChatBar->sendChatFromViewer("", CHAT_TYPE_START, FALSE); + LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE); } //----------------------------------------------------------------------------- @@ -2785,7 +2732,7 @@ void LLAgent::stopTyping() { clearRenderState(AGENT_STATE_TYPING); sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP); - gChatBar->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); + LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE); } } @@ -2860,6 +2807,10 @@ void LLAgent::endAnimationUpdateUI() LLNavigationBar::getInstance()->setVisible(TRUE); gStatusBar->setVisibleForMouselook(true); + LLBottomTray::getInstance()->setVisible(TRUE); + + LLSideTray::getInstance()->setVisible(TRUE); + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); // Only pop if we have pushed... @@ -2874,7 +2825,7 @@ void LLAgent::endAnimationUpdateUI() #endif mViewsPushed = FALSE; } - + gAgent.setLookAt(LOOKAT_TARGET_CLEAR); if( gMorphView ) @@ -2946,6 +2897,10 @@ void LLAgent::endAnimationUpdateUI() LLNavigationBar::getInstance()->setVisible(FALSE); gStatusBar->setVisibleForMouselook(false); + LLBottomTray::getInstance()->setVisible(FALSE); + + LLSideTray::getInstance()->setVisible(FALSE); + // clear out camera lag effect mCameraLag.clearVec(); @@ -2955,7 +2910,7 @@ void LLAgent::endAnimationUpdateUI() LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); mViewsPushed = TRUE; - + // hide all floaters except the mini map #if 0 // Use this once all floaters are registered @@ -4275,7 +4230,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani gFocusMgr.setKeyboardFocus( NULL ); gFocusMgr.setMouseCapture( NULL ); - LLVOAvatar::onCustomizeStart(); + LLVOAvatarSelf::onCustomizeStart(); } if (mAvatarObject.notNull()) @@ -5239,15 +5194,15 @@ BOOL LLAgent::buildLocationString(std::string& str, ELocationFormat fmt) switch (fmt) { case LOCATION_FORMAT_LANDMARK: - buffer = llformat("%.32s (%d, %d, %d)", - region_name.c_str(), - pos_x, pos_y, pos_z); + buffer = llformat("%.100s", region_name.c_str()); break; case LOCATION_FORMAT_NORMAL: + buffer = llformat("%s", region_name.c_str()); + break; case LOCATION_FORMAT_FULL: buffer = llformat("%s (%d, %d, %d)", region_name.c_str(), - pos_x, pos_y, pos_z); + pos_x, pos_y, pos_z); break; } } @@ -5257,20 +5212,16 @@ BOOL LLAgent::buildLocationString(std::string& str, ELocationFormat fmt) switch (fmt) { case LOCATION_FORMAT_LANDMARK: - buffer = llformat("%.32s, %.32s (%d, %d, %d)", - parcel_name.c_str(), - region_name.c_str(), - pos_x, pos_y, pos_z); + buffer = llformat("%.100s", parcel_name.c_str()); break; case LOCATION_FORMAT_NORMAL: - buffer = llformat("%s/%s (%d, %d, %d)", + buffer = llformat("%s, %s", region_name.c_str(), - parcel_name.c_str(), - pos_x, pos_y, pos_z); + parcel_name.c_str()); break; case LOCATION_FORMAT_FULL: std::string sim_access_string = region->getSimAccessString(); - buffer = llformat("%s/%s (%d, %d, %d)%s%s", + buffer = llformat("%s, %s (%d, %d, %d)%s%s", region_name.c_str(), parcel_name.c_str(), pos_x, pos_y, pos_z, @@ -5445,7 +5396,7 @@ BOOL LLAgent::allowOperation(PermissionBit op, } -void LLAgent::getName(std::string& name) +void LLAgent::getName(std::string& name) const { name.clear(); @@ -5483,16 +5434,51 @@ 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) { LLFloaterGroupInfo::refreshGroup(group_id); + //*TODO Implement group update for Profile View // update avatar info - LLFloaterAvatarInfo* fa = LLFloaterReg::findTypedInstance<LLFloaterAvatarInfo>("preview_avatar", LLSD(gAgent.getID())); - if(fa) - { - fa->resetGroupList(); - } +// LLFloaterAvatarInfo* fa = LLFloaterReg::findTypedInstance<LLFloaterAvatarInfo>("preview_avatar", LLSD(gAgent.getID())); +// if(fa) +// { +// fa->resetGroupList(); +// } if (gIMMgr) { @@ -5928,9 +5914,9 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **) //static void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data) { - gAgent.mNumPendingQueries--; + gAgentQueryManager.mNumPendingQueries--; - LLVOAvatar* avatarp = gAgent.getAvatarObject(); + LLVOAvatarSelf* avatarp = gAgent.getAvatarObject(); if (!avatarp || avatarp->isDead()) { llwarns << "No avatar for user in cached texture update!" << llendl; @@ -5960,12 +5946,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * if (texture_id.notNull() && (S32)texture_index < BAKED_NUM_INDICES - && gAgent.mActiveCacheQueries[ texture_index ] == query_id) + && gAgentQueryManager.mActiveCacheQueries[texture_index] == query_id) { //llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl; - avatarp->setCachedBakedTexture(getTextureIndex((EBakedTextureIndex)texture_index), texture_id); + avatarp->setCachedBakedTexture(LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)texture_index), texture_id); //avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id ); - gAgent.mActiveCacheQueries[ texture_index ] = 0; + gAgentQueryManager.mActiveCacheQueries[texture_index] = 0; num_results++; } } @@ -5974,7 +5960,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * avatarp->updateMeshTextures(); - if (gAgent.mNumPendingQueries == 0) + if (gAgentQueryManager.mNumPendingQueries == 0) { // RN: not sure why composites are disabled at this point avatarp->setCompositeUpdatesEnabled(TRUE); @@ -5984,8 +5970,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * BOOL LLAgent::anyControlGrabbed() const { - U32 i; - for (i = 0; i < TOTAL_CONTROLS; i++) + for (U32 i = 0; i < TOTAL_CONTROLS; i++) { if (gAgent.mControlsTakenCount[i] > 0) return TRUE; @@ -6082,7 +6067,7 @@ bool LLAgent::teleportCore(bool is_local) // hide land floater too - it'll be out of date LLFloaterLand::hideInstance(); - + LLViewerParcelMgr::getInstance()->deselectLand(); // Close all pie menus, deselect land, etc. @@ -6382,878 +6367,6 @@ void LLAgent::requestLeaveGodMode() sendReliableMessage(); } -// wearables -LLAgent::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback() -{ - gAgent.createStandardWearablesAllDone(); -} - -LLAgent::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback() -{ - gAgent.sendAgentWearablesUpdate(); -} - -LLAgent::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback( - LLPointer<LLRefCount> cb, S32 index, LLWearable* wearable, U32 todo) : - mIndex(index), - mWearable(wearable), - mTodo(todo), - mCB(cb) -{ -} - -void LLAgent::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item) -{ - if (inv_item.isNull()) - return; - - gAgent.addWearabletoAgentInventoryDone(mIndex, inv_item, mWearable); - - if (mTodo & CALL_UPDATE) - { - gAgent.sendAgentWearablesUpdate(); - } - if (mTodo & CALL_RECOVERDONE) - { - gAgent.recoverMissingWearableDone(); - } - /* - * Do this for every one in the loop - */ - if (mTodo & CALL_CREATESTANDARDDONE) - { - gAgent.createStandardWearablesDone(mIndex); - } - if (mTodo & CALL_MAKENEWOUTFITDONE) - { - gAgent.makeNewOutfitDone(mIndex); - } -} - -void LLAgent::addWearabletoAgentInventoryDone( - S32 index, - const LLUUID& item_id, - LLWearable* wearable) -{ - if (item_id.isNull()) - return; - - LLUUID old_item_id = mWearableEntry[index].mItemID; - mWearableEntry[index].mItemID = item_id; - mWearableEntry[index].mWearable = wearable; - if (old_item_id.notNull()) - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - LLViewerInventoryItem* item = gInventory.getItem(item_id); - if(item && wearable) - { - // We're changing the asset id, so we both need to set it - // locally via setAssetUUID() and via setTransactionID() which - // will be decoded on the server. JC - item->setAssetUUID(wearable->getID()); - item->setTransactionID(wearable->getTransactionID()); - gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); - item->updateServer(FALSE); - } - gInventory.notifyObservers(); -} - -void LLAgent::sendAgentWearablesUpdate() -{ - // First make sure that we have inventory items for each wearable - S32 i; - for(i=0; i < WT_COUNT; ++i) - { - LLWearable* wearable = mWearableEntry[ i ].mWearable; - if (wearable) - { - if( mWearableEntry[ i ].mItemID.isNull() ) - { - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - i, - wearable, - addWearableToAgentInventoryCallback::CALL_NONE); - addWearableToAgentInventory(cb, wearable); - } - else - { - gInventory.addChangedMask( LLInventoryObserver::LABEL, - mWearableEntry[i].mItemID ); - } - } - } - - // Then make sure the inventory is in sync with the avatar. - gInventory.notifyObservers(); - - // Send the AgentIsNowWearing - gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing); - - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); - - lldebugs << "sendAgentWearablesUpdate()" << llendl; - for(i=0; i < WT_COUNT; ++i) - { - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - - U8 type_u8 = (U8)i; - gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 ); - - LLWearable* wearable = mWearableEntry[ i ].mWearable; - if( wearable ) - { - //llinfos << "Sending wearable " << wearable->getName() << llendl; - gMessageSystem->addUUIDFast(_PREHASH_ItemID, mWearableEntry[ i ].mItemID ); - } - else - { - //llinfos << "Not wearing wearable type " << LLWearable::typeToTypeName((EWearableType)i) << llendl; - gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null ); - } - - lldebugs << " " << LLWearable::typeToTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getID() : LLUUID::null) << llendl; - } - gAgent.sendReliableMessage(); -} - -void LLAgent::saveWearable( EWearableType type, BOOL send_update ) -{ - LLWearable* old_wearable = mWearableEntry[(S32)type].mWearable; - if( old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()) ) - { - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); - mWearableEntry[(S32)type].mWearable = new_wearable; - - LLInventoryItem* item = gInventory.getItem(mWearableEntry[(S32)type].mItemID); - if( item ) - { - // Update existing inventory item - LLPointer<LLViewerInventoryItem> template_item = - new LLViewerInventoryItem(item->getUUID(), - item->getParentUUID(), - item->getPermissions(), - new_wearable->getID(), - new_wearable->getAssetType(), - item->getInventoryType(), - item->getName(), - item->getDescription(), - item->getSaleInfo(), - item->getFlags(), - item->getCreationDate()); - template_item->setTransactionID(new_wearable->getTransactionID()); - template_item->updateServer(FALSE); - gInventory.updateItem(template_item); - } - else - { - // Add a new inventory item (shouldn't ever happen here) - U32 todo = addWearableToAgentInventoryCallback::CALL_NONE; - if (send_update) - { - todo |= addWearableToAgentInventoryCallback::CALL_UPDATE; - } - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - (S32)type, - new_wearable, - todo); - addWearableToAgentInventory(cb, new_wearable); - return; - } - - getAvatarObject()->wearableUpdated( type ); - - if( send_update ) - { - sendAgentWearablesUpdate(); - } - } -} - -void LLAgent::saveWearableAs( - EWearableType type, - const std::string& new_name, - BOOL save_in_lost_and_found) -{ - if(!isWearableCopyable(type)) - { - llwarns << "LLAgent::saveWearableAs() not copyable." << llendl; - return; - } - LLWearable* old_wearable = getWearable(type); - if(!old_wearable) - { - llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; - return; - } - LLInventoryItem* item = gInventory.getItem(mWearableEntry[type].mItemID); - if(!item) - { - llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl; - return; - } - std::string trunc_name(new_name); - LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( - old_wearable, - trunc_name); - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - type, - new_wearable, - addWearableToAgentInventoryCallback::CALL_UPDATE); - LLUUID category_id; - if (save_in_lost_and_found) - { - category_id = gInventory.findCategoryUUIDForType( - LLAssetType::AT_LOST_AND_FOUND); - } - else - { - // put in same folder as original - category_id = item->getParentUUID(); - } - - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - category_id, - new_name, - cb); - -/* - LLWearable* old_wearable = getWearable( type ); - if( old_wearable ) - { - std::string old_name = old_wearable->getName(); - old_wearable->setName( new_name ); - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); - old_wearable->setName( old_name ); - - LLUUID category_id; - LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID ); - if( item ) - { - new_wearable->setPermissions(item->getPermissions()); - if (save_in_lost_and_found) - { - category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); - } - else - { - // put in same folder as original - category_id = item->getParentUUID(); - } - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) - { - view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); - } - } - - mWearableEntry[ type ].mWearable = new_wearable; - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - type, - addWearableToAgentInventoryCallback::CALL_UPDATE); - addWearableToAgentInventory(cb, new_wearable, category_id); - } -*/ -} - -void LLAgent::revertWearable( EWearableType type ) -{ - LLWearable* wearable = mWearableEntry[(S32)type].mWearable; - if( wearable ) - { - wearable->writeToAvatar( TRUE ); - } - sendAgentSetAppearance(); -} - -void LLAgent::revertAllWearables() -{ - for( S32 i=0; i < WT_COUNT; i++ ) - { - revertWearable( (EWearableType)i ); - } -} - -void LLAgent::saveAllWearables() -{ - //if(!gInventory.isLoaded()) - //{ - // return; - //} - - for( S32 i=0; i < WT_COUNT; i++ ) - { - saveWearable( (EWearableType)i, FALSE ); - } - sendAgentWearablesUpdate(); -} - -// Called when the user changes the name of a wearable inventory item that is currenlty being worn. -void LLAgent::setWearableName( const LLUUID& item_id, const std::string& new_name ) -{ - for( S32 i=0; i < WT_COUNT; i++ ) - { - if( mWearableEntry[i].mItemID == item_id ) - { - LLWearable* old_wearable = mWearableEntry[i].mWearable; - llassert( old_wearable ); - - std::string old_name = old_wearable->getName(); - old_wearable->setName( new_name ); - LLWearable* new_wearable = gWearableList.createCopy( old_wearable ); - LLInventoryItem* item = gInventory.getItem(item_id); - if(item) - { - new_wearable->setPermissions(item->getPermissions()); - } - old_wearable->setName( old_name ); - - mWearableEntry[i].mWearable = new_wearable; - sendAgentWearablesUpdate(); - break; - } - } -} - - -BOOL LLAgent::isWearableModifiable(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - if(!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if(item && item->getPermissions().allowModifyBy(gAgent.getID(), - gAgent.getGroupID())) - { - return TRUE; - } - } - return FALSE; -} - -BOOL LLAgent::isWearableCopyable(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - if(!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if(item && item->getPermissions().allowCopyBy(gAgent.getID(), - gAgent.getGroupID())) - { - return TRUE; - } - } - return FALSE; -} - -U32 LLAgent::getWearablePermMask(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - if(!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if(item) - { - return item->getPermissions().getMaskOwner(); - } - } - return PERM_NONE; -} - -LLInventoryItem* LLAgent::getWearableInventoryItem(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - LLInventoryItem* item = NULL; - if(item_id.notNull()) - { - item = gInventory.getItem(item_id); - } - return item; -} - -LLWearable* LLAgent::getWearableFromWearableItem( const LLUUID& item_id ) -{ - for( S32 i=0; i < WT_COUNT; i++ ) - { - if( mWearableEntry[i].mItemID == item_id ) - { - return mWearableEntry[i].mWearable; - } - } - return NULL; -} - - -void LLAgent::sendAgentWearablesRequest() -{ - gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - sendReliableMessage(); -} - -// Used to enable/disable menu items. -// static -BOOL LLAgent::selfHasWearable( void* userdata ) -{ - EWearableType type = (EWearableType)(intptr_t)userdata; - return gAgent.getWearable( type ) != NULL; -} - -BOOL LLAgent::isWearingItem( const LLUUID& item_id ) -{ - return (getWearableFromWearableItem( item_id ) != NULL); -} - -// static -void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data ) -{ - // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates - // that may result from AgentWearablesRequest having been sent more than once. - static bool first = true; - if (!first) return; - first = false; - - LLUUID agent_id; - gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); - - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar && (agent_id == avatar->getID()) ) - { - gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgent.mAgentWearablesUpdateSerialNum ); - - S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData); - if( num_wearables < 4 ) - { - // Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin). - // The fact that they don't have any here (only a dummy is sent) implies that this account existed - // before we had wearables, or that the database has gotten messed up. - return; - } - - //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; - // Add wearables - LLUUID asset_id_array[ WT_COUNT ]; - S32 i; - for( i=0; i < num_wearables; i++ ) - { - U8 type_u8 = 0; - gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i ); - if( type_u8 >= WT_COUNT ) - { - continue; - } - EWearableType type = (EWearableType) type_u8; - - LLUUID item_id; - gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i ); - - LLUUID asset_id; - gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i ); - if( asset_id.isNull() ) - { - LLWearable::removeFromAvatar( type, FALSE ); - } - else - { - LLAssetType::EType asset_type = LLWearable::typeToAssetType( type ); - if( asset_type == LLAssetType::AT_NONE ) - { - continue; - } - - gAgent.mWearableEntry[type].mItemID = item_id; - asset_id_array[type] = asset_id; - } - - lldebugs << " " << LLWearable::typeToTypeLabel(type) << llendl; - } - - // now that we have the asset ids...request the wearable assets - for( i = 0; i < WT_COUNT; i++ ) - { - if( !gAgent.mWearableEntry[i].mItemID.isNull() ) - { - gWearableList.getAsset( - asset_id_array[i], - LLStringUtil::null, - LLWearable::typeToAssetType( (EWearableType) i ), - LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i ); - } - } - } -} - -// A single wearable that the avatar was wearing on start-up has arrived from the database. -// static -void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdata ) -{ - EWearableType type = (EWearableType)(intptr_t)userdata; - - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( !avatar ) - { - return; - } - - if( wearable ) - { - llassert( type == wearable->getType() ); - gAgent.mWearableEntry[ type ].mWearable = wearable; - - // disable composites if initial textures are baked - avatar->setupComposites(); - gAgent.queryWearableCache(); - - wearable->writeToAvatar( FALSE ); - avatar->setCompositeUpdatesEnabled(TRUE); - gInventory.addChangedMask( LLInventoryObserver::LABEL, gAgent.mWearableEntry[type].mItemID ); - } - else - { - // Somehow the asset doesn't exist in the database. - gAgent.recoverMissingWearable( type ); - } - - gInventory.notifyObservers(); - - // Have all the wearables that the avatar was wearing at log-in arrived? - if( !gAgent.mWearablesLoaded ) - { - gAgent.mWearablesLoaded = TRUE; - for( S32 i = 0; i < WT_COUNT; i++ ) - { - if( !gAgent.mWearableEntry[i].mItemID.isNull() && !gAgent.mWearableEntry[i].mWearable ) - { - gAgent.mWearablesLoaded = FALSE; - break; - } - } - } - - if( gAgent.mWearablesLoaded ) - { - // Make sure that the server's idea of the avatar's wearables actually match the wearables. - gAgent.sendAgentSetAppearance(); - - // Check to see if there are any baked textures that we hadn't uploaded before we logged off last time. - // If there are any, schedule them to be uploaded as soon as the layer textures they depend on arrive. - if( !gAgent.cameraCustomizeAvatar() ) - { - avatar->requestLayerSetUploads(); - } - } -} - -// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the -// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that -// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.) -void LLAgent::recoverMissingWearable( EWearableType type ) -{ - // Try to recover by replacing missing wearable with a new one. - LLNotifications::instance().add("ReplacedMissingWearable"); - lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; - LLWearable* new_wearable = gWearableList.createNewWearable(type); - - S32 type_s32 = (S32) type; - mWearableEntry[type_s32].mWearable = new_wearable; - new_wearable->writeToAvatar( TRUE ); - - // Add a new one in the lost and found folder. - // (We used to overwrite the "not found" one, but that could potentially - // destory content.) JC - LLUUID lost_and_found_id = - gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - type_s32, - new_wearable, - addWearableToAgentInventoryCallback::CALL_RECOVERDONE); - addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE); -} - -void LLAgent::recoverMissingWearableDone() -{ - // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated? - mWearablesLoaded = TRUE; - for( S32 i = 0; i < WT_COUNT; i++ ) - { - if( !mWearableEntry[i].mItemID.isNull() && !mWearableEntry[i].mWearable ) - { - mWearablesLoaded = FALSE; - break; - } - } - - if( mWearablesLoaded ) - { - // Make sure that the server's idea of the avatar's wearables actually match the wearables. - sendAgentSetAppearance(); - } - else - { - gInventory.addChangedMask( LLInventoryObserver::LABEL, LLUUID::null ); - gInventory.notifyObservers(); - } -} - -void LLAgent::createStandardWearables(BOOL female) -{ - llwarns << "Creating Standard " << (female ? "female" : "male" ) - << " Wearables" << llendl; - - if (mAvatarObject.isNull()) - { - return; - } - - if(female) mAvatarObject->setSex(SEX_FEMALE); - else mAvatarObject->setSex(SEX_MALE); - - BOOL create[WT_COUNT] = - { - TRUE, //WT_SHAPE - TRUE, //WT_SKIN - TRUE, //WT_HAIR - TRUE, //WT_EYES - TRUE, //WT_SHIRT - TRUE, //WT_PANTS - TRUE, //WT_SHOES - TRUE, //WT_SOCKS - FALSE, //WT_JACKET - FALSE, //WT_GLOVES - TRUE, //WT_UNDERSHIRT - TRUE, //WT_UNDERPANTS - FALSE //WT_SKIRT - }; - - for( S32 i=0; i < WT_COUNT; i++ ) - { - bool once = false; - LLPointer<LLRefCount> donecb = NULL; - if( create[i] ) - { - if (!once) - { - once = true; - donecb = new createStandardWearablesAllDoneCallback; - } - llassert( mWearableEntry[i].mWearable == NULL ); - LLWearable* wearable = gWearableList.createNewWearable((EWearableType)i); - mWearableEntry[i].mWearable = wearable; - // no need to update here... - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - donecb, - i, - wearable, - addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE); - addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE); - } - } -} -void LLAgent::createStandardWearablesDone(S32 index) -{ - LLWearable* wearable = mWearableEntry[index].mWearable; - - if (wearable) - { - wearable->writeToAvatar(TRUE); - } -} - -void LLAgent::createStandardWearablesAllDone() -{ - // ... because sendAgentWearablesUpdate will notify inventory - // observers. - mWearablesLoaded = TRUE; - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); - - // Treat this as the first texture entry message, if none received yet - mAvatarObject->onFirstTEMessageReceived(); -} - -void LLAgent::makeNewOutfit( - const std::string& new_folder_name, - const LLDynamicArray<S32>& wearables_to_include, - const LLDynamicArray<S32>& attachments_to_include, - BOOL rename_clothing) -{ - if (mAvatarObject.isNull()) - { - return; - } - - // First, make a folder in the Clothes directory. - LLUUID folder_id = gInventory.createNewCategory( - gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING), - LLAssetType::AT_NONE, - new_folder_name); - - bool found_first_item = false; - - /////////////////// - // Wearables - - if( wearables_to_include.count() ) - { - // Then, iterate though each of the wearables and save copies of them in the folder. - S32 i; - S32 count = wearables_to_include.count(); - LLDynamicArray<LLUUID> delete_items; - LLPointer<LLRefCount> cbdone = NULL; - for( i = 0; i < count; ++i ) - { - S32 index = wearables_to_include[i]; - LLWearable* old_wearable = mWearableEntry[ index ].mWearable; - if( old_wearable ) - { - std::string new_name; - LLWearable* new_wearable; - new_wearable = gWearableList.createCopy(old_wearable); - if (rename_clothing) - { - new_name = new_folder_name; - new_name.append(" "); - new_name.append(old_wearable->getTypeLabel()); - LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); - new_wearable->setName(new_name); - } - - LLViewerInventoryItem* item = gInventory.getItem(mWearableEntry[index].mItemID); - S32 todo = addWearableToAgentInventoryCallback::CALL_NONE; - if (!found_first_item) - { - found_first_item = true; - /* set the focus to the first item */ - todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE; - /* send the agent wearables update when done */ - cbdone = new sendAgentWearablesUpdateCallback; - } - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - cbdone, - index, - new_wearable, - todo); - if (isWearableCopyable((EWearableType)index)) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - folder_id, - new_name, - cb); - } - else - { - move_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), - item->getUUID(), - folder_id, - new_name, - cb); - } - } - } - gInventory.notifyObservers(); - } - - - /////////////////// - // Attachments - - if( attachments_to_include.count() ) - { - BOOL msg_started = FALSE; - LLMessageSystem* msg = gMessageSystem; - for( S32 i = 0; i < attachments_to_include.count(); i++ ) - { - S32 attachment_pt = attachments_to_include[i]; - LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL ); - if(!attachment) continue; - LLViewerObject* attached_object = attachment->getObject(); - if(!attached_object) continue; - const LLUUID& item_id = attachment->getItemID(); - if(item_id.isNull()) continue; - LLInventoryItem* item = gInventory.getItem(item_id); - if(!item) continue; - if(!msg_started) - { - msg_started = TRUE; - msg->newMessage("CreateNewOutfitAttachments"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", getID()); - msg->addUUID("SessionID", getSessionID()); - msg->nextBlock("HeaderData"); - msg->addUUID("NewFolderID", folder_id); - } - msg->nextBlock("ObjectData"); - msg->addUUID("OldItemID", item_id); - msg->addUUID("OldFolderID", item->getParentUUID()); - } - - if( msg_started ) - { - sendReliableMessage(); - } - - } -} - -void LLAgent::makeNewOutfitDone(S32 index) -{ - LLUUID first_item_id = mWearableEntry[index].mItemID; - // Open the inventory and select the first item we added. - if( first_item_id.notNull() ) - { - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) - { - view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO); - } - } -} - - -void LLAgent::addWearableToAgentInventory( - LLPointer<LLInventoryCallback> cb, - LLWearable* wearable, - const LLUUID& category_id, - BOOL notify) -{ - create_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), - category_id, - wearable->getTransactionID(), - wearable->getName(), - wearable->getDescription(), - wearable->getAssetType(), - LLInventoryType::IT_WEARABLE, - wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - cb); -} - //----------------------------------------------------------------------------- // sendAgentSetAppearance() //----------------------------------------------------------------------------- @@ -7261,7 +6374,7 @@ void LLAgent::sendAgentSetAppearance() { if (mAvatarObject.isNull()) return; - if (mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar()) + if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar()) { return; } @@ -7291,11 +6404,11 @@ void LLAgent::sendAgentSetAppearance() // is texture data current relative to wearables? // KLW - TAT this will probably need to check the local queue. - BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded; + BOOL textures_current = mAvatarObject->areTexturesCurrent(); for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) { - const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)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)) @@ -7317,13 +6430,14 @@ void LLAgent::sendAgentSetAppearance() llinfos << "TAT: Sending cached texture data" << llendl; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) { - const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index); + const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); LLUUID hash; - for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++) + for (U8 i=0; i < baked_dict->mWearables.size(); i++) { // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; - const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; - const LLWearable* wearable = getWearable(wearable_type); + 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->getID(); @@ -7331,10 +6445,10 @@ void LLAgent::sendAgentSetAppearance() } if (hash.notNull()) { - hash ^= wearable_dict->mHashID; + hash ^= baked_dict->mWearablesHashID; } - const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index); + const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index); msg->nextBlockFast(_PREHASH_WearableData); msg->addUUIDFast(_PREHASH_CacheID, hash); @@ -7376,12 +6490,10 @@ void LLAgent::sendAgentSetAppearance() void LLAgent::sendAgentDataUpdateRequest() { - if(getID().isNull()) - return; // not logged in gMessageSystem->newMessageFast(_PREHASH_AgentDataUpdateRequest); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); sendReliableMessage(); } @@ -7396,453 +6508,6 @@ void LLAgent::sendAgentUserInfoRequest() sendReliableMessage(); } -void LLAgent::removeWearable( EWearableType type ) -{ - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - - if ( (gAgent.isTeen()) - && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) - { - // Can't take off underclothing in simple UI mode or on PG accounts - return; - } - - if( old_wearable ) - { - if( old_wearable->isDirty() ) - { - LLSD payload; - payload["wearable_type"] = (S32)type; - // Bring up view-modal dialog: Save changes? Yes, No, Cancel - LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgent::onRemoveWearableDialog); - return; - } - else - { - removeWearableFinal( type ); - } - } -} - -// static -bool LLAgent::onRemoveWearableDialog(const LLSD& notification, const LLSD& response ) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger(); - switch( option ) - { - case 0: // "Save" - gAgent.saveWearable( type ); - gAgent.removeWearableFinal( type ); - break; - - case 1: // "Don't Save" - gAgent.removeWearableFinal( type ); - break; - - case 2: // "Cancel" - break; - - default: - llassert(0); - break; - } - return false; -} - -// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal. -void LLAgent::removeWearableFinal( EWearableType type ) -{ - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - - gInventory.addChangedMask( LLInventoryObserver::LABEL, mWearableEntry[type].mItemID ); - - mWearableEntry[ type ].mWearable = NULL; - mWearableEntry[ type ].mItemID.setNull(); - - queryWearableCache(); - - if( old_wearable ) - { - old_wearable->removeFromAvatar( TRUE ); - } - - // Update the server - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); - gInventory.notifyObservers(); -} - -void LLAgent::copyWearableToInventory( EWearableType type ) -{ - LLWearable* wearable = mWearableEntry[ type ].mWearable; - if( wearable ) - { - // Save the old wearable if it has changed. - if( wearable->isDirty() ) - { - wearable = gWearableList.createCopyFromAvatar( wearable ); - mWearableEntry[ type ].mWearable = wearable; - } - - // Make a new entry in the inventory. (Put it in the same folder as the original item if possible.) - LLUUID category_id; - LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID ); - if( item ) - { - category_id = item->getParentUUID(); - wearable->setPermissions(item->getPermissions()); - } - LLPointer<LLInventoryCallback> cb = - new addWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - type, - wearable); - addWearableToAgentInventory(cb, wearable, category_id); - } -} - - -// A little struct to let setWearable() communicate more than one value with onSetWearableDialog(). -struct LLSetWearableData -{ - LLSetWearableData( const LLUUID& new_item_id, LLWearable* new_wearable ) : - mNewItemID( new_item_id ), mNewWearable( new_wearable ) {} - LLUUID mNewItemID; - LLWearable* mNewWearable; -}; - -BOOL LLAgent::needsReplacement(EWearableType wearableType, S32 remove) -{ - return TRUE; - /*if (remove) return TRUE; - - return getWearable(wearableType) ? TRUE : FALSE;*/ -} - -// Assumes existing wearables are not dirty. -void LLAgent::setWearableOutfit( - const LLInventoryItem::item_array_t& items, - const LLDynamicArray< LLWearable* >& wearables, - BOOL remove ) -{ - lldebugs << "setWearableOutfit() start" << llendl; - - BOOL wearables_to_remove[WT_COUNT]; - wearables_to_remove[WT_SHAPE] = FALSE; - wearables_to_remove[WT_SKIN] = FALSE; - wearables_to_remove[WT_HAIR] = FALSE; - wearables_to_remove[WT_EYES] = FALSE; - wearables_to_remove[WT_SHIRT] = remove; - wearables_to_remove[WT_PANTS] = remove; - wearables_to_remove[WT_SHOES] = remove; - wearables_to_remove[WT_SOCKS] = remove; - wearables_to_remove[WT_JACKET] = remove; - wearables_to_remove[WT_GLOVES] = remove; - wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove; - wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove; - wearables_to_remove[WT_SKIRT] = remove; - - S32 count = wearables.count(); - llassert( items.count() == count ); - - S32 i; - for( i = 0; i < count; i++ ) - { - LLWearable* new_wearable = wearables[i]; - LLPointer<LLInventoryItem> new_item = items[i]; - - EWearableType type = new_wearable->getType(); - wearables_to_remove[type] = FALSE; - - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - if( old_wearable ) - { - const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; - if( (old_wearable->getID() == new_wearable->getID()) && - (old_item_id == new_item->getUUID()) ) - { - lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl; - continue; - } - - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - - // Assumes existing wearables are not dirty. - if( old_wearable->isDirty() ) - { - llassert(0); - continue; - } - } - - mWearableEntry[ type ].mItemID = new_item->getUUID(); - mWearableEntry[ type ].mWearable = new_wearable; - } - - std::vector<LLWearable*> wearables_being_removed; - - for( i = 0; i < WT_COUNT; i++ ) - { - if( wearables_to_remove[i] ) - { - wearables_being_removed.push_back(mWearableEntry[ i ].mWearable); - mWearableEntry[ i ].mWearable = NULL; - - gInventory.addChangedMask(LLInventoryObserver::LABEL, mWearableEntry[ i ].mItemID); - mWearableEntry[ i ].mItemID.setNull(); - } - } - - gInventory.notifyObservers(); - - queryWearableCache(); - - std::vector<LLWearable*>::iterator wearable_iter; - - for( wearable_iter = wearables_being_removed.begin(); - wearable_iter != wearables_being_removed.end(); - ++wearable_iter) - { - LLWearable* wearablep = *wearable_iter; - if (wearablep) - { - wearablep->removeFromAvatar( TRUE ); - } - } - - for( i = 0; i < count; i++ ) - { - wearables[i]->writeToAvatar( TRUE ); - } - - // Start rendering & update the server - mWearablesLoaded = TRUE; - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); - - lldebugs << "setWearableOutfit() end" << llendl; -} - - -// User has picked "wear on avatar" from a menu. -void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable ) -{ - EWearableType type = new_wearable->getType(); - - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - if( old_wearable ) - { - const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; - if( (old_wearable->getID() == new_wearable->getID()) && - (old_item_id == new_item->getUUID()) ) - { - lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl; - return; - } - - if( old_wearable->isDirty() ) - { - // Bring up modal dialog: Save changes? Yes, No, Cancel - LLSD payload; - payload["item_id"] = new_item->getUUID(); - LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgent::onSetWearableDialog, _1, _2, new_wearable)); - return; - } - } - - setWearableFinal( new_item, new_wearable ); -} - -// static -bool LLAgent::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable ) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID()); - if( !new_item ) - { - delete wearable; - return false; - } - - switch( option ) - { - case 0: // "Save" - gAgent.saveWearable( wearable->getType() ); - gAgent.setWearableFinal( new_item, wearable ); - break; - - case 1: // "Don't Save" - gAgent.setWearableFinal( new_item, wearable ); - break; - - case 2: // "Cancel" - break; - - default: - llassert(0); - break; - } - - delete wearable; - return false; -} - -// Called from setWearable() and onSetWearableDialog() to actually set the wearable. -void LLAgent::setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable ) -{ - EWearableType type = new_wearable->getType(); - - // Replace the old wearable with a new one. - llassert( new_item->getAssetUUID() == new_wearable->getID() ); - LLUUID old_item_id = mWearableEntry[ type ].mItemID; - mWearableEntry[ type ].mItemID = new_item->getUUID(); - mWearableEntry[ type ].mWearable = new_wearable; - - if (old_item_id.notNull()) - { - gInventory.addChangedMask( LLInventoryObserver::LABEL, old_item_id ); - gInventory.notifyObservers(); - } - - //llinfos << "LLVOAvatar::setWearable()" << llendl; - queryWearableCache(); - new_wearable->writeToAvatar( TRUE ); - - // Update the server - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); -} - -void LLAgent::queryWearableCache() -{ - if (!mWearablesLoaded) - { - return; - } - - // Look up affected baked textures. - // If they exist: - // disallow updates for affected layersets (until dataserver responds with cache request.) - // If cache miss, turn updates back on and invalidate composite. - // If cache hit, modify baked texture entries. - // - // Cache requests contain list of hashes for each baked texture entry. - // Response is list of valid baked texture assets. (same message) - - gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); - gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID); - - S32 num_queries = 0; - for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) - { - const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index); - LLUUID hash; - for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++) - { - // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; - const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; - const LLWearable* wearable = getWearable(wearable_type); - if (wearable) - { - hash ^= wearable->getID(); - } - } - if (hash.notNull()) - { - hash ^= wearable_dict->mHashID; - num_queries++; - // *NOTE: make sure at least one request gets packed - - //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl; - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - gMessageSystem->addUUIDFast(_PREHASH_ID, hash); - gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index); - } - - mActiveCacheQueries[ baked_index ] = mTextureCacheQueryID; - } - - llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; - gMessageSystem->sendReliable(getRegion()->getHost()); - mNumPendingQueries++; - mTextureCacheQueryID++; -} - -// User has picked "remove from avatar" from a menu. -// static -void LLAgent::userRemoveWearable( void* userdata ) -{ - EWearableType type = (EWearableType)(intptr_t)userdata; - - if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR ) ) //&& - //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) - { - gAgent.removeWearable( type ); - } -} - -void LLAgent::userRemoveAllClothes( void* userdata ) -{ - // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty. - if( gFloaterCustomize ) - { - gFloaterCustomize->askToSaveIfDirty( LLAgent::userRemoveAllClothesStep2 ); - } - else - { - LLAgent::userRemoveAllClothesStep2( TRUE ); - } -} - -void LLAgent::userRemoveAllClothesStep2( BOOL proceed ) -{ - if( proceed ) - { - gAgent.removeWearable( WT_SHIRT ); - gAgent.removeWearable( WT_PANTS ); - gAgent.removeWearable( WT_SHOES ); - gAgent.removeWearable( WT_SOCKS ); - gAgent.removeWearable( WT_JACKET ); - gAgent.removeWearable( WT_GLOVES ); - gAgent.removeWearable( WT_UNDERSHIRT ); - gAgent.removeWearable( WT_UNDERPANTS ); - gAgent.removeWearable( WT_SKIRT ); - } -} - -void LLAgent::userRemoveAllAttachments( void* userdata ) -{ - LLVOAvatar* avatarp = gAgent.getAvatarObject(); - if(!avatarp) - { - llwarns << "No avatar found." << llendl; - return; - } - - gMessageSystem->newMessage("ObjectDetach"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); - iter != avatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - LLViewerObject* objectp = attachment->getObject(); - if (objectp) - { - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); - } - } - gMessageSystem->sendReliable( gAgent.getRegionHost() ); -} - void LLAgent::observeFriends() { if(!mFriendObserver) @@ -7905,4 +6570,87 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename) }//end for (all message sets in xml file) } +// static +void LLAgent::createLandmarkHere() +{ + std::string landmark_name, landmark_desc; + + gAgent.buildLocationString(landmark_name, LLAgent::LOCATION_FORMAT_LANDMARK); + gAgent.buildLocationString(landmark_desc, LLAgent::LOCATION_FORMAT_FULL); + LLUUID folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + + createLandmarkHere(landmark_name, landmark_desc, folder_id); +} + +// static +void LLAgent::createLandmarkHere(const std::string& name, const std::string& desc, const LLUUID& folder_id) +{ + LLViewerRegion* agent_region = gAgent.getRegion(); + if(!agent_region) + { + llwarns << "No agent region" << llendl; + return; + } + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!agent_parcel) + { + llwarns << "No agent parcel" << llendl; + return; + } + if (!agent_parcel->getAllowLandmark() + && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) + { + LLNotifications::instance().add("CannotCreateLandmarkNotOwner"); + return; + } + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, LLTransactionID::tnull, + name, desc, + LLAssetType::AT_LANDMARK, + LLInventoryType::IT_LANDMARK, + NOT_WEARABLE, PERM_ALL, + NULL); +} + +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 |