diff --git a/indra/llrender/llglimmediate.cpp b/indra/llrender/llglimmediate.cpp deleted file mode 100644 index 17c2182df..000000000 --- a/indra/llrender/llglimmediate.cpp +++ /dev/null @@ -1 +0,0 @@ -#error This file has been renamed llrender.cpp diff --git a/indra/llrender/llglimmediate.h b/indra/llrender/llglimmediate.h deleted file mode 100644 index 4a7a0ebec..000000000 --- a/indra/llrender/llglimmediate.h +++ /dev/null @@ -1 +0,0 @@ -#error This file has been renamed llrender.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9be7663a2..95d419d6e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -434,7 +434,6 @@ static void settings_to_globals() LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay")); LLToolBar::sInventoryAutoOpenTime = gSavedSettings.getF32("InventoryAutoOpenDelay"); LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive"); - LLSelectMgr::sRenderSelectionHighlights = gSavedSettings.getBOOL("RenderHighlightSelections"); LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index f6fd26f41..afe43a353 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -33,6 +33,7 @@ #include "llviewerprecompiledheaders.h" // file include +#define LLSELECTMGR_CPP #include "llselectmgr.h" // library includes @@ -93,8 +94,6 @@ #include "rlvhandler.h" // [/RLVa:KB] -#include "llglheaders.h" - LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; // // Consts @@ -102,7 +101,6 @@ LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; const S32 NUM_SELECTION_UNDO_ENTRIES = 200; const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f; -const S32 OWNERSHIP_COST_PER_OBJECT = 10; // Must be the same as economy_constants.price_object_claim in the database. const S32 MAX_ACTION_QUEUE_SIZE = 20; const S32 MAX_SILS_PER_FRAME = 50; const S32 MAX_OBJECTS_PER_PACKET = 254; @@ -112,13 +110,12 @@ const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; // Globals // -BOOL gDebugSelectMgr = FALSE; +//BOOL gDebugSelectMgr = FALSE; -BOOL gHideSelectedObjects = FALSE; -BOOL gAllowSelectAvatar = FALSE; +//BOOL gHideSelectedObjects = FALSE; +//BOOL gAllowSelectAvatar = FALSE; BOOL LLSelectMgr::sRectSelectInclusive = TRUE; -BOOL LLSelectMgr::sRenderSelectionHighlights = TRUE; BOOL LLSelectMgr::sRenderHiddenSelections = TRUE; BOOL LLSelectMgr::sRenderLightRadius = FALSE; F32 LLSelectMgr::sHighlightThickness = 0.f; @@ -134,7 +131,6 @@ LLColor4 LLSelectMgr::sHighlightInspectColor; LLColor4 LLSelectMgr::sHighlightParentColor; LLColor4 LLSelectMgr::sHighlightChildColor; LLColor4 LLSelectMgr::sContextSilhouetteColor; -std::set LLSelectMgr::sObjectPropertiesFamilyRequests; static LLObjectSelection *get_null_object_selection(); template<> @@ -181,11 +177,17 @@ LLObjectSelection *get_null_object_selection() return sNullSelection; } +// Build time optimization, generate this function once here +template class LLSelectMgr* LLSingleton::getInstance(); //----------------------------------------------------------------------------- // LLSelectMgr() //----------------------------------------------------------------------------- LLSelectMgr::LLSelectMgr() + : mHideSelectedObjects(LLCachedControl("HideSelectedObjects", false)), + mRenderHighlightSelections(LLCachedControl("RenderHighlightSelections", false)), + mAllowSelectAvatar( LLCachedControl("AllowSelectAvatar", false)), + mDebugSelectMgr(LLCachedControl( "DebugSelectMgr", false)) { mTEMode = FALSE; mLastCameraPos.clearVec(); @@ -564,6 +566,121 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id) return object_found; } +bool LLSelectMgr::linkObjects() +{ + if (!LLSelectMgr::getInstance()->selectGetAllRootsValid()) + { + LLNotifications::getInstance()->add("UnableToLinkWhileDownloading"); + return true; + } + + S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (object_count > MAX_CHILDREN_PER_TASK + 1) + { + LLSD args; + args["COUNT"] = llformat("%d", object_count); + int max = MAX_CHILDREN_PER_TASK+1; + args["MAX"] = llformat("%d", max); + LLNotifications::getInstance()->add("UnableToLinkObjects", args); + return true; + } + + if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) + { + LLNotifications::instance().add("CannotLinkIncompleteSet"); + return true; + } + + if (!LLSelectMgr::getInstance()->selectGetRootsModify()) + { + LLNotifications::instance().add("CannotLinkModify"); + return true; + } + + LLUUID owner_id; + std::string owner_name; + if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name)) + { + // we don't actually care if you're the owner, but novices are + // the most likely to be stumped by this one, so offer the + // easiest and most likely solution. + LLNotifications::instance().add("CannotLinkDifferentOwners"); + return true; + } + + LLSelectMgr::getInstance()->sendLink(); + + return true; +} + +bool LLSelectMgr::unlinkObjects() +{ +// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.1.3b) | Modified: RLVa-0.2.0g | OK + if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand()) ) + { + // Allow only if the avie isn't sitting on any of the selected objects + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); + RlvSelectIsSittingOn f(gAgent.getAvatarObject()->getRoot()); + if ( (hSel.notNull()) && (hSel->getFirstRootNode(&f, TRUE)) ) + return true; + } +// [/RLVa:KB] + LLSelectMgr::getInstance()->sendDelink(); + return true; +} + +// in order to link, all objects must have the same owner, and the +// agent must have the ability to modify all of the objects. However, +// we're not answering that question with this method. The question +// we're answering is: does the user have a reasonable expectation +// that a link operation should work? If so, return true, false +// otherwise. this allows the handle_link method to more finely check +// the selection and give an error message when the uer has a +// reasonable expectation for the link to work, but it will fail. +bool LLSelectMgr::enableLinkObjects() +{ + bool new_value = false; + // check if there are at least 2 objects selected, and that the + // user can modify at least one of the selected objects. + + // in component mode, can't link + if (!gSavedSettings.getBOOL("EditLinkedParts")) + { + if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2) + { + struct f : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + return object->permModify(); + } + } func; + const bool firstonly = true; + new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); + } + } + return new_value; +} + +bool LLSelectMgr::enableUnlinkObjects() +{ + LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject(); + + bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() && + first_editable_object && + !first_editable_object->isAttachment(); +// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.1.3b) | Modified: RLVa-0.2.0g | OK + if ( (new_value) && (!gRlvHandler.canStand()) ) + { + // Allow only if the avie isn't sitting on any of the selected objects + LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection(); + RlvSelectIsSittingOn f(gAgent.getAvatarObject()->getRoot()); + new_value = handleSel->getFirstRootNode(&f, TRUE) == NULL; + } +// [/RLVa:KB] + return new_value; +} + void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object) { // bail if nothing selected or if object wasn't selected in the first place @@ -690,7 +807,7 @@ void LLSelectMgr::addAsFamily(std::vector& objects, BOOL add_to // Can't select yourself if (objectp->mID == gAgentID - && !gAllowSelectAvatar) + && !LLSelectMgr::getInstance()->mAllowSelectAvatar) { continue; } @@ -839,7 +956,12 @@ LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 LLSelectNode *LLSelectMgr::getHoverNode() { - return getHoverObjects()->getFirstRootNode(); + return mHoverObjects->getFirstRootNode(); +} + +LLSelectNode *LLSelectMgr::getPrimaryHoverNode() +{ + return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject]; } void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) @@ -854,8 +976,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) return; } - if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove())) + if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) + || (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove())) { // only select my own objects return; @@ -2253,6 +2375,26 @@ BOOL LLSelectMgr::selectGetAllValid() return TRUE; } +//----------------------------------------------------------------------------- +// selectGetAllValidAndObjectsFound() - return TRUE if selections are +// valid and objects are found. +// +// For EXT-3114 - same as selectGetModify() without the modify check. +//----------------------------------------------------------------------------- +BOOL LLSelectMgr::selectGetAllValidAndObjectsFound() +{ + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !object || !node->mValid ) + { + return FALSE; + } + } + return TRUE; +} //----------------------------------------------------------------------------- // selectGetModify() - return TRUE if current agent can modify all @@ -2382,6 +2524,7 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) } if (first_id.isNull()) { + name.assign("Nobody"); return FALSE; } @@ -2664,11 +2807,6 @@ BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off) -BOOL LLSelectMgr::selectGetOwnershipCost(S32* out_cost) -{ - return mSelectedObjects->getOwnershipCost(*out_cost); -} - BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm) { BOOL first = TRUE; @@ -3517,7 +3655,7 @@ void LLSelectMgr::deselectAllIfTooFar() if (select_dist_sq > deselect_dist_sq) { - if (gDebugSelectMgr) + if (mDebugSelectMgr) { llinfos << "Selection manager: auto-deselecting, select_dist = " << fsqrtf(select_dist_sq) << llendl; llinfos << "agent pos global = " << gAgent.getPositionGlobal() << llendl; @@ -3596,7 +3734,7 @@ void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info) // Attachments //---------------------------------------------------------------------- -void LLSelectMgr::sendAttach(U8 attachment_point) +void LLSelectMgr::sendAttach(U8 attachment_point, bool replace) { LLViewerObject* attach_object = mSelectedObjects->getFirstRootObject(); @@ -3610,7 +3748,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point) if (0 == attachment_point || get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL)) { - if (attachment_point != 0 && gHippoGridManager->getConnectedGrid()->supportsInvLinks()) + if ((!replace || attachment_point != 0) && gHippoGridManager->getConnectedGrid()->supportsInvLinks()) { // If we know the attachment point then we got here by clicking an // "Attach to..." context menu item, so we should add, not replace. @@ -4300,10 +4438,6 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name, void LLSelectMgr::requestObjectPropertiesFamily(LLViewerObject* object) { - // Remember that we asked the properties of this object. - sObjectPropertiesFamilyRequests.insert(object->mID); - //llinfos << "Registered an ObjectPropertiesFamily request for object " << object->mID << llendl; - LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); @@ -4381,7 +4515,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, sit_name, i); //unpack TE IDs - std::vector texture_ids; + uuid_vec_t texture_ids; S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID); if (size > 0) { @@ -4493,8 +4627,9 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data // static void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data) { - U32 request_flags; LLUUID id; + + U32 request_flags; LLUUID creator_id; LLUUID owner_id; LLUUID group_id; @@ -4525,15 +4660,6 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use std::string desc; msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc); - //llinfos << "Got ObjectPropertiesFamily reply for object " << id << llendl; - if(sObjectPropertiesFamilyRequests.count(id) != 0 ) - { - // Send to export floaters - //LLFloaterExport::receiveObjectProperties(id, name, desc); - // We got the reply, so remove the object from the list of pending requests - sObjectPropertiesFamilyRequests.erase(id); - } - // the reporter widget askes the server for info about picked objects if (request_flags & (COMPLAINT_REPORT_REQUEST | BUG_REPORT_REQUEST)) { @@ -4562,7 +4688,7 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use return (node->getObject() && node->getObject()->mID == mID); } } func(id); - LLSelectNode* node = LLSelectMgr::getInstance()->getHoverObjects()->getFirstNode(&func); + LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func); if (node) { @@ -4897,12 +5023,12 @@ void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handl } void LLSelectMgr::renderSilhouettes(BOOL for_hud) { - if (!mRenderSilhouettes || !LLSelectMgr::sRenderSelectionHighlights) + if (!mRenderSilhouettes || !mRenderHighlightSelections) { return; } - gGL.getTexUnit(0)->bind(mSilhouetteImagep.get()); + gGL.getTexUnit(0)->bind(mSilhouetteImagep); LLGLSPipelineSelection gls_select; gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); LLGLEnable blend(GL_BLEND); @@ -4932,7 +5058,8 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) if (mSelectedObjects->getNumNodes()) { LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); - + + LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getSelectedUUID(); // //for (S32 pass = 0; pass < 2; pass++) //{ @@ -4948,7 +5075,11 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) { continue; } - if(objectp->getID() == inspect_item_id) + if (objectp->getID() == focus_item_id) + { + node->renderOneSilhouette(gFocusMgr.getFocusColor()); + } + else if(objectp->getID() == inspect_item_id) { node->renderOneSilhouette(sHighlightInspectColor); } @@ -5118,13 +5249,14 @@ void LLSelectNode::selectTE(S32 te_index, BOOL selected) { return; } - if (selected) - { - mTESelectMask |= (0x1 << te_index); + S32 mask = 0x1 << te_index; + if(selected) + { + mTESelectMask |= mask; } else { - mTESelectMask &= ~(0x1 << te_index); + mTESelectMask &= ~mask; } mLastTESelected = te_index; } @@ -5178,13 +5310,13 @@ void LLSelectNode::saveColors() } } -void LLSelectNode::saveTextures(const std::vector& textures) +void LLSelectNode::saveTextures(const uuid_vec_t& textures) { if (mObject.notNull()) { mSavedTextures.clear(); - for (std::vector::const_iterator texture_it = textures.begin(); + for (uuid_vec_t::const_iterator texture_it = textures.begin(); texture_it != textures.end(); ++texture_it) { mSavedTextures.push_back(*texture_it); @@ -5477,13 +5609,21 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) // Update everyone who cares about the selection list void dialog_refresh_all() + { + // This is the easiest place to fire the update signal, as it will + // make cleaning up the functions below easier. Also, sometimes entities + // outside the selection manager change properties of selected objects + // and call into this function. Yuck. + LLSelectMgr::getInstance()->mUpdateSignal(); + if (gNoRender) { return; } - //could refresh selected object info in toolbar here + // *TODO: Eliminate all calls into outside classes below, make those + // objects register with the update signal. gFloaterTools->dirty(); @@ -5897,6 +6037,27 @@ void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) gAgent.mHUDCurZoom = current_zoom; } +///////////////////////////////////////////////////////////////////////////// +// Object selection iterator helpers +///////////////////////////////////////////////////////////////////////////// +bool LLObjectSelection::is_root::operator()(LLSelectNode *node) +{ + LLViewerObject* object = node->getObject(); + return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); +} + +bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node) +{ + LLViewerObject* object = node->getObject(); + return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); +} + +bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node) +{ + LLViewerObject* object = node->getObject(); + return (object != NULL) && (object->isRootEdit() || object->isJointChild()); +} + LLObjectSelection::LLObjectSelection() : LLRefCount(), mSelectType(SELECT_TYPE_WORLD) @@ -5988,16 +6149,6 @@ BOOL LLObjectSelection::isEmpty() const return (mList.size() == 0); } -//----------------------------------------------------------------------------- -// getOwnershipCost() -//----------------------------------------------------------------------------- -BOOL LLObjectSelection::getOwnershipCost(S32 &cost) -{ - S32 count = getObjectCount(); - cost = count * OWNERSHIP_COST_PER_OBJECT; - return (count > 0); -} - //----------------------------------------------------------------------------- // getObjectCount() - returns number of non null objects @@ -6138,6 +6289,29 @@ bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool first return result; } +BOOL LLObjectSelection::isMultipleTESelected() +{ + BOOL te_selected = FALSE; + // ...all faces + for (LLObjectSelection::iterator iter = begin(); + iter != end(); iter++) + { + LLSelectNode* nodep = *iter; + for (S32 i = 0; i < SELECT_MAX_TES; i++) + { + if(nodep->isTESelected(i)) + { + if(te_selected) + { + return TRUE; + } + te_selected = TRUE; + } + } + } + return FALSE; +} + //----------------------------------------------------------------------------- // contains() //----------------------------------------------------------------------------- diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 1ebe341bf..1472cc8b7 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -35,7 +35,6 @@ #include "llcharacter.h" #include "lleditmenuhandler.h" -#include "llstring.h" #include "llundo.h" #include "lluuid.h" #include "llmemory.h" @@ -47,14 +46,15 @@ #include "llframetimer.h" #include "llbbox.h" #include "llpermissions.h" -#include "llviewerobject.h" +#include "llcontrol.h" +#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template #include -#include "boost/iterator/filter_iterator.hpp" +#include +#include class LLMessageSystem; class LLViewerTexture; -class LLViewerObject; class LLColor4; class LLVector3; class LLSelectNode; @@ -146,7 +146,7 @@ public: void setObject(LLViewerObject* object); // *NOTE: invalidate stored textures and colors when # faces change void saveColors(); - void saveTextures(const std::vector& textures); + void saveTextures(const uuid_vec_t& textures); void saveTextureScaleRatios(); BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; @@ -182,7 +182,7 @@ public: std::string mSitName; U64 mCreationDate; std::vector mSavedColors; - std::vector mSavedTextures; + uuid_vec_t mSavedTextures; std::vector mTextureScaleRatios; std::vector mSilhouetteVertices; // array of vertices to render silhouette of object std::vector mSilhouetteNormals; // array of normals to render silhouette of object @@ -202,13 +202,9 @@ class LLObjectSelection : public LLRefCount protected: ~LLObjectSelection(); - // List public: typedef std::list list_t; -private: - list_t mList; -public: // Iterators struct is_non_null { @@ -234,11 +230,7 @@ public: struct is_root { - bool operator()(LLSelectNode* node) - { - LLViewerObject* object = node->getObject(); - return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); - } + bool operator()(LLSelectNode* node); }; typedef boost::filter_iterator root_iterator; root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); } @@ -246,11 +238,7 @@ public: struct is_valid_root { - bool operator()(LLSelectNode* node) - { - LLViewerObject* object = node->getObject(); - return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild()); - } + bool operator()(LLSelectNode* node); }; typedef boost::filter_iterator valid_root_iterator; valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); } @@ -258,11 +246,7 @@ public: struct is_root_object { - bool operator()(LLSelectNode* node) - { - LLViewerObject* object = node->getObject(); - return (object != NULL) && (object->isRootEdit() || object->isJointChild()); - } + bool operator()(LLSelectNode* node); }; typedef boost::filter_iterator root_object_iterator; root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); } @@ -272,12 +256,9 @@ public: LLObjectSelection(); void updateEffects(); - void cleanupNodes(); BOOL isEmpty() const; - S32 getOwnershipCost(S32 &cost); - LLSelectNode* getFirstNode(LLSelectedNodeFunctor* func = NULL); LLSelectNode* getFirstRootNode(LLSelectedNodeFunctor* func = NULL, BOOL non_root_ok = FALSE); LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent = FALSE); @@ -294,12 +275,8 @@ public: // iterate through texture entries template bool getSelectedTEValue(LLSelectedTEGetFunctor* func, T& res); - - void addNode(LLSelectNode *nodep); - void addNodeAtEnd(LLSelectNode *nodep); - void moveNodeToFront(LLSelectNode *nodep); - void removeNode(LLSelectNode *nodep); - void deleteAllNodes(); // Delete all nodes + template bool isMultipleTEValue(LLSelectedTEGetFunctor* func, const T& ignore_value); + S32 getNumNodes(); LLSelectNode* findNode(LLViewerObject* objectp); @@ -308,6 +285,7 @@ public: S32 getTECount(); S32 getRootObjectCount(); + BOOL isMultipleTESelected(); BOOL contains(LLViewerObject* object); BOOL contains(LLViewerObject* object, S32 te); @@ -326,6 +304,16 @@ public: ESelectType getSelectType() const { return mSelectType; } private: + void addNode(LLSelectNode *nodep); + void addNodeAtEnd(LLSelectNode *nodep); + void moveNodeToFront(LLSelectNode *nodep); + void removeNode(LLSelectNode *nodep); + void deleteAllNodes(); + void cleanupNodes(); + + +private: + list_t mList; const LLObjectSelection &operator=(const LLObjectSelection &); LLPointer mPrimaryObject; @@ -335,11 +323,15 @@ private: typedef LLSafeHandle LLObjectSelectionHandle; +// Build time optimization, generate this once in .cpp file +#ifndef LLSELECTMGR_CPP +extern template class LLSelectMgr* LLSingleton::getInstance(); +#endif + class LLSelectMgr : public LLEditMenuHandler, public LLSingleton { public: static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? - static BOOL sRenderSelectionHighlights; // do we show selection silhouettes? static BOOL sRenderHiddenSelections; // do we show selection silhouettes that are occluded? static BOOL sRenderLightRadius; // do we show the radius of selected lights? static F32 sHighlightThickness; @@ -356,6 +348,11 @@ public: static LLColor4 sHighlightInspectColor; static LLColor4 sContextSilhouetteColor; + LLCachedControl mHideSelectedObjects; + LLCachedControl mRenderHighlightSelections; + LLCachedControl mAllowSelectAvatar; + LLCachedControl mDebugSelectMgr; + public: LLSelectMgr(); ~LLSelectMgr(); @@ -394,13 +391,16 @@ public: // Add //////////////////////////////////////////////////////////////// + // This method is meant to select an object, and then select all + // of the ancestors and descendants. This should be the normal behavior. + // + // *NOTE: You must hold on to the object selection handle, otherwise + // the objects will be automatically deselected in 1 frame. + LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE); + // For when you want just a child object. LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES); - // This method is meant to select an object, and then select all - // of the ancestors and descendents. This should be the normal behavior. - LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE); - // Same as above, but takes a list of objects. Used by rectangle select. LLObjectSelectionHandle selectObjectAndFamily(const std::vector& object_list, BOOL send_to_sim = TRUE); @@ -408,6 +408,8 @@ public: LLObjectSelectionHandle selectHighlightedObjects(); LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1); + LLSelectNode *getHoverNode(); + LLSelectNode *getPrimaryHoverNode(); void highlightObjectOnly(LLViewerObject *objectp); void highlightObjectAndFamily(LLViewerObject *objectp); @@ -439,16 +441,25 @@ public: BOOL removeObjectFromSelections(const LLUUID &id); + //////////////////////////////////////////////////////////////// + // Selection editing + //////////////////////////////////////////////////////////////// + bool linkObjects(); + + bool unlinkObjects(); + + bool enableLinkObjects(); + + bool enableUnlinkObjects(); + //////////////////////////////////////////////////////////////// // Selection accessors //////////////////////////////////////////////////////////////// - LLObjectSelectionHandle getHoverObjects() { return mHoverObjects; } LLObjectSelectionHandle getSelection() { return mSelectedObjects; } // right now this just renders the selection with root/child colors instead of a single color LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; } LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; } - - LLSelectNode *getHoverNode(); + LLObjectSelectionHandle getHoverObjects() { return mHoverObjects; } //////////////////////////////////////////////////////////////// // Grid manipulation @@ -503,7 +514,7 @@ public: void selectionSetTexGen( U8 texgen ); void selectionSetShiny( U8 shiny ); void selectionSetFullbright( U8 fullbright ); - void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); + void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url); void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); void selectionSetGlow(const F32 glow); @@ -535,6 +546,7 @@ public: // Returns TRUE if the viewer has information on all selected objects BOOL selectGetAllRootsValid(); BOOL selectGetAllValid(); + BOOL selectGetAllValidAndObjectsFound(); // returns TRUE if you can modify all selected objects. BOOL selectGetRootsModify(); @@ -554,7 +566,6 @@ public: // the value found if available. BOOL selectGetGroup(LLUUID& id); BOOL selectGetPerm( U8 which_perm, U32* mask_on, U32* mask_off); // TRUE if all have data, returns two masks, each indicating which bits are all on and all off - BOOL selectGetOwnershipCost(S32* cost); // sum of all ownership costs BOOL selectIsGroupOwned(); // TRUE if all root objects have valid data and are group owned. @@ -610,7 +621,7 @@ public: // verification only, if it doesn't match region info then sale is // canceled void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info); - void sendAttach(U8 attachment_point); + void sendAttach(U8 attachment_point, bool replace=true); void sendDetach(); void sendDropAttachment(); void sendLink(); @@ -689,7 +700,13 @@ private: static void packPermissionsHead(void* user_data); static void packGodlikeHead(void* user_data); static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); - + +public: + // Observer/callback support for when object selection changes or + // properties are received/updated + typedef boost::signals2::signal< void ()> update_signal_t; + update_signal_t mUpdateSignal; + private: LLPointer mSilhouetteImagep; LLObjectSelectionHandle mSelectedObjects; @@ -719,12 +736,12 @@ private: BOOL mForceSelection; LLAnimPauseRequest mPauseRequest; - - static std::set sObjectPropertiesFamilyRequests; }; -// Utilities -void dialog_refresh_all(); // Update subscribers to the selection list +// *DEPRECATED: For callbacks or observers, use +// LLSelectMgr::getInstance()->mUpdateSignal.connect( callback ) +// Update subscribers to the selection list +void dialog_refresh_all(); // Templates //----------------------------------------------------------------------------- diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 1e412de26..b68e19f19 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -56,9 +56,6 @@ #include "llfloatertools.h" // [/RLVa:KB] -// Globals -extern BOOL gAllowSelectAvatar; - const F32 SELECTION_ROTATION_TRESHOLD = 0.1f; LLToolSelect::LLToolSelect( LLToolComposite* composite ) @@ -137,7 +134,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); // *NOTE: These settings must be cleaned up at bottom of function. - if (temp_select || gAllowSelectAvatar) + if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); gSavedSettings.setBOOL("SelectMovableOnly", FALSE); @@ -267,7 +264,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi } //if(!object) // Cleanup temp select settings above. - if (temp_select || gAllowSelectAvatar) + if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); gSavedSettings.setBOOL("SelectMovableOnly", select_movable); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 61c64db32..9d5a01049 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -282,13 +282,15 @@ void handle_test_load_url(void*); // // Evil hackish imported globals // -extern BOOL gRenderLightGlows; -extern BOOL gRenderAvatar; -extern BOOL gHideSelectedObjects; +//extern BOOL gHideSelectedObjects; +//extern BOOL gAllowSelectAvatar; +extern BOOL gDebugClicks; +extern BOOL gDebugWindowProc; +extern BOOL gDebugTextEditorTips; +//extern BOOL gDebugSelectMgr; +extern BOOL gDebugAvatarRotation; extern BOOL gShowOverlayTitle; extern BOOL gOcclusionCull; -extern BOOL gAllowSelectAvatar; - // // Globals // @@ -1258,11 +1260,6 @@ static void handle_export_menus_to_xml_continued(AIFilePicker* filepicker) out.close(); } -extern BOOL gDebugClicks; -extern BOOL gDebugWindowProc; -extern BOOL gDebugTextEditorTips; -extern BOOL gDebugSelectMgr; - void init_debug_ui_menu(LLMenuGL* menu) { menu->append(new LLMenuItemCheckGL("Rotate Mini-Map", menu_toggle_control, NULL, menu_check_control, (void*)"MiniMapRotate")); @@ -1288,7 +1285,7 @@ void init_debug_ui_menu(LLMenuGL* menu) (void*)"DoubleClickTeleport")); menu->appendSeparator(); // menu->append(new LLMenuItemCallGL( "Print Packets Lost", &print_packets_lost, NULL, NULL, 'L', MASK_SHIFT )); - menu->append(new LLMenuItemToggleGL("Debug SelectMgr", &gDebugSelectMgr)); + menu->append(new LLMenuItemCheckGL("Debug SelectMgr", menu_toggle_control, NULL, menu_check_control, (void*)"DebugSelectMgr")); menu->append(new LLMenuItemToggleGL("Debug Clicks", &gDebugClicks)); menu->append(new LLMenuItemToggleGL("Debug Views", &LLView::sDebugRects)); menu->append(new LLMenuItemCheckGL("Show Name Tooltips", toggle_show_xui_names, NULL, check_show_xui_names, NULL)); @@ -1517,7 +1514,7 @@ void init_debug_rendering_menu(LLMenuGL* menu) //menu->append(new LLMenuItemCheckGL("Cull Small Objects", toggle_cull_small, NULL, menu_check_control, (void*)"RenderCullBySize")); menu->appendSeparator(); - menu->append(new LLMenuItemToggleGL("Hide Selected", &gHideSelectedObjects)); + menu->append(new LLMenuItemCheckGL("Hide Selected", menu_toggle_control, NULL, menu_check_control, (void*)"HideSelectedObjects")); menu->appendSeparator(); menu->append(new LLMenuItemCheckGL("Tangent Basis", menu_toggle_control, NULL, menu_check_control, (void*)"ShowTangentBasis")); menu->append(new LLMenuItemCallGL("Selected Texture Info", handle_selected_texture_info, NULL, NULL, 'T', MASK_CONTROL|MASK_SHIFT|MASK_ALT)); @@ -1603,7 +1600,7 @@ void init_debug_avatar_menu(LLMenuGL* menu) sub_menu->append(new LLMenuItemCallGL("Toggle PG", handle_toggle_pg)); - sub_menu->append(new LLMenuItemToggleGL("Allow Select Avatar", &gAllowSelectAvatar)); + sub_menu->append(new LLMenuItemCheckGL("Allow Select Avatar", menu_toggle_control, NULL, menu_check_control, (void*)"AllowSelectAvatar")); sub_menu->createJumpKeys(); menu->appendMenu(sub_menu); @@ -5338,26 +5335,7 @@ class LLToolsEnableLink : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = false; - // check if there are at least 2 objects selected, and that the - // user can modify at least one of the selected objects. - - // in component mode, can't link - if (!gSavedSettings.getBOOL("EditLinkedParts")) - { - if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2) - { - struct f : public LLSelectedObjectFunctor - { - virtual bool apply(LLViewerObject* object) - { - return object->permModify(); - } - } func; - const bool firstonly = true; - new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); - } - } + bool new_value = LLSelectMgr::getInstance()->enableLinkObjects(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -5367,45 +5345,7 @@ class LLToolsLink : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if(!LLSelectMgr::getInstance()->selectGetAllRootsValid()) - { - LLNotifications::instance().add("UnableToLinkWhileDownloading"); - return true; - } - - S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - if (object_count > MAX_CHILDREN_PER_TASK + 1) - { - LLSD args; - args["COUNT"] = llformat("%d", object_count); - int max = MAX_CHILDREN_PER_TASK+1; - args["MAX"] = llformat("%d", max); - LLNotifications::instance().add("UnableToLinkObjects", args); - return true; - } - - if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) - { - LLNotifications::instance().add("CannotLinkIncompleteSet"); - return true; - } - if(!LLSelectMgr::getInstance()->selectGetRootsModify()) - { - LLNotifications::instance().add("CannotLinkModify"); - return true; - } - LLUUID owner_id; - std::string owner_name; - if(!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name)) - { - // we don't actually care if you're the owner, but novices are - // the most likely to be stumped by this one, so offer the - // easiest and most likely solution. - LLNotifications::instance().add("CannotLinkDifferentOwners"); - return true; - } - LLSelectMgr::getInstance()->sendLink(); - return true; + return LLSelectMgr::getInstance()->linkObjects(); } }; @@ -5413,19 +5353,7 @@ class LLToolsEnableUnlink : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() && - LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() && - !LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject()->isAttachment(); -// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.1.3b) | Modified: RLVa-0.2.0g | OK - if ( (new_value) && (!gRlvHandler.canStand()) ) - { - // Allow only if the avie isn't sitting on any of the selected objects - LLObjectSelectionHandle handleSel = LLSelectMgr::getInstance()->getSelection(); - RlvSelectIsSittingOn f(gAgent.getAvatarObject()->getRoot()); - if (handleSel->getFirstRootNode(&f, TRUE) != NULL) - new_value = false; - } -// [/RLVa:KB] + bool new_value = LLSelectMgr::getInstance()->enableUnlinkObjects(); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -5435,18 +5363,7 @@ class LLToolsUnlink : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { -// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.1.3b) | Modified: RLVa-0.2.0g | OK - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand()) ) - { - // Allow only if the avie isn't sitting on any of the selected objects - LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); - RlvSelectIsSittingOn f(gAgent.getAvatarObject()->getRoot()); - if ( (hSel.notNull()) && (hSel->getFirstRootNode(&f, TRUE)) ) - return true; - } -// [/RLVa:KB] - - LLSelectMgr::getInstance()->sendDelink(); + LLSelectMgr::getInstance()->unlinkObjects(); return true; } }; @@ -8303,9 +8220,8 @@ class LLToolsShowSelectionHighlights : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLSelectMgr::sRenderSelectionHighlights = !LLSelectMgr::sRenderSelectionHighlights; - - gSavedSettings.setBOOL("RenderHighlightSelections", LLSelectMgr::sRenderSelectionHighlights); + LLControlVariable *ctrl = gSavedSettings.getControl("RenderHighlightSelections"); + ctrl->setValue(!ctrl->getValue().asBoolean()); return true; } }; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index bddefa52b..a7c797f51 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -72,7 +72,7 @@ const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; BOOL gAnimateTextures = TRUE; -extern BOOL gHideSelectedObjects; +//extern BOOL gHideSelectedObjects; F32 LLVOVolume::sLODFactor = 1.f; F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop @@ -2204,7 +2204,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (!mbCanSelect || // (gHideSelectedObjects && isSelected()) || // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b - ( (gHideSelectedObjects && isSelected()) && + ( (LLSelectMgr::getInstance()->mHideSelectedObjects && isSelected()) && ((!rlv_handler_t::isEnabled()) || (!isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(getRootEdit()))) ) || // [/RLVa:KB] mDrawable->isDead() || @@ -2351,7 +2351,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, // if (facep->getViewerObject()->isSelected() && gHideSelectedObjects) // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.2.1f const LLViewerObject* pObj = facep->getViewerObject(); - if ( (pObj->isSelected() && gHideSelectedObjects) && + if ( (pObj->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) && ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(pObj->getRootEdit()))) ) // [/RLVa:KB] { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 89637a691..2f764db05 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -146,7 +146,7 @@ const S32 MAX_OCCLUDER_COUNT = 2; extern S32 gBoxFrame; extern BOOL gRenderLightGlows; -extern BOOL gHideSelectedObjects; +//extern BOOL gHideSelectedObjects; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; @@ -2639,7 +2639,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) return; } - if (gHideSelectedObjects) + if (LLSelectMgr::getInstance()->mHideSelectedObjects) { // if (drawablep->getVObj().notNull() && // drawablep->getVObj()->isSelected()) @@ -4159,7 +4159,7 @@ void LLPipeline::renderForSelect(std::set& objects, BOOL render LLDrawable* drawable = vobj->mDrawable; if (vobj->isDead() || vobj->isHUDAttachment() || - (gHideSelectedObjects && vobj->isSelected()) || + (LLSelectMgr::getInstance()->mHideSelectedObjects && vobj->isSelected()) || drawable->isDead() || !hasRenderType(drawable->getRenderType())) {