From 215f423cbe18fe9ca14a26caef918d303bad28ff Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:45:11 -0500 Subject: Second Life viewer sources 1.18.4.0-RC --- linden/indra/newview/llselectmgr.cpp | 3287 +++++++++++++++------------------- 1 file changed, 1416 insertions(+), 1871 deletions(-) (limited to 'linden/indra/newview/llselectmgr.cpp') diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index ec01d54..128a802 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -2,6 +2,8 @@ * @file llselectmgr.cpp * @brief A manager for selected objects and faces. * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * * Copyright (c) 2001-2007, Linden Research, Inc. * * Second Life Viewer Source Code @@ -24,6 +26,7 @@ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" @@ -210,6 +213,11 @@ LLSelectMgr::LLSelectMgr() //----------------------------------------------------------------------------- LLSelectMgr::~LLSelectMgr() { + clearSelections(); +} + +void LLSelectMgr::clearSelections() +{ mHoverObjects->deleteAllNodes(); mSelectedObjects->deleteAllNodes(); mHighlightedObjects->deleteAllNodes(); @@ -217,21 +225,27 @@ LLSelectMgr::~LLSelectMgr() mGridObjects.deleteAllNodes(); } -void LLSelectMgr::updateEffects() +void LLSelectMgr::update() { + mSelectedObjects->cleanupNodes(); +} +void LLSelectMgr::updateEffects() +{ //keep reference grid objects active - for (LLSelectNode* grid_nodep = mGridObjects.getFirstNode(); - grid_nodep; - grid_nodep = mGridObjects.getNextNode()) + struct f : public LLSelectedObjectFunctor { - LLViewerObject* grid_object = grid_nodep->getObject(); - LLDrawable* drawable = grid_object->mDrawable; - if (drawable) + virtual bool apply(LLViewerObject* object) { - gPipeline.markMoved(drawable); + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + gPipeline.markMoved(drawable); + } + return true; } - } + } func; + mGridObjects.applyToObjects(&func); if (mEffectsTimer.getElapsedTimeF32() > 1.f) { @@ -243,29 +257,30 @@ void LLSelectMgr::updateEffects() void LLSelectMgr::overrideObjectUpdates() { //override any position updates from simulator on objects being edited - LLSelectNode* selectNode; - for (selectNode = gSelectMgr->getSelection()->getFirstNode(); - selectNode != NULL; - selectNode = gSelectMgr->getSelection()->getNextNode()) + struct f : public LLSelectedNodeFunctor { - LLViewerObject* object = selectNode->getObject(); - - if (object->permMove()) + virtual bool apply(LLSelectNode* selectNode) { - if (!selectNode->mLastPositionLocal.isExactlyZero()) - { - object->setPosition(selectNode->mLastPositionLocal); - } - if (selectNode->mLastRotation != LLQuaternion()) - { - object->setRotation(selectNode->mLastRotation); - } - if (!selectNode->mLastScale.isExactlyZero()) + LLViewerObject* object = selectNode->getObject(); + if (object->permMove()) { - object->setScale(selectNode->mLastScale); + if (!selectNode->mLastPositionLocal.isExactlyZero()) + { + object->setPosition(selectNode->mLastPositionLocal); + } + if (selectNode->mLastRotation != LLQuaternion()) + { + object->setRotation(selectNode->mLastRotation); + } + if (!selectNode->mLastScale.isExactlyZero()) + { + object->setScale(selectNode->mLastScale); + } } + return true; } - } + } func; + getSelection()->applyToNodes(&func); } //----------------------------------------------------------------------------- @@ -414,24 +429,26 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, //----------------------------------------------------------------------------- // Select the object, parents and children. //----------------------------------------------------------------------------- -LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const LLDynamicArray& object_list, - BOOL send_to_sim) +LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector& object_list, + BOOL send_to_sim) { // Collect all of the objects, children included LLDynamicArray objects; - LLViewerObject *object; - S32 i; //clear primary object (no primary object) mSelectedObjects->mPrimaryObject = NULL; - if (object_list.count() < 1) return NULL; - + if (object_list.size() < 1) + { + return NULL; + } + // NOTE -- we add the objects in REVERSE ORDER // to preserve the order in the mSelectedObjects list - for (i = object_list.count() - 1; i >= 0; i--) + for (std::vector::const_reverse_iterator riter = object_list.rbegin(); + riter != object_list.rend(); ++riter) { - object = object_list.get(i); + LLViewerObject *object = *riter; llassert( object ); @@ -503,44 +520,30 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id) // Iterate through selected objects list and kill the object if( !object_found ) { - LLViewerObject* prevobjp = NULL; - for( LLViewerObject* tobjp = mSelectedObjects->getFirstObject(); tobjp != NULL; tobjp = mSelectedObjects->getNextObject() ) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); ) { - if (tobjp == prevobjp) - { - // Somehow we got stuck in an infinite loop... (DaveP) - // this logic is kind of twisted, not sure how this is happening, so... - llwarns << "Detected infinite loop #1 in LLSelectMgr::removeObjectFromSelections:|" << llendl; - //MikeS. adding warning and comment... - //These infinite loops happen because the LLSelectMgr iteration routines are non-reentrant. - //deselectObjectAndFamily uses getFirstObject and getNextObject to mess with the array, - //resetting the arrays internal iterator state. This needs fixing BAD. - continue; - } - // It's possible the item being removed has an avatar sitting on it - // So remove the avatar that is sitting on the object. - if (tobjp->mID == id || tobjp->isAvatar()) + LLObjectSelection::iterator curiter = iter++; + LLViewerObject* object = (*curiter)->getObject(); + if (object->mID == id) { - if (!gNoRender) + if (tool) { tool->stopEditing(); } // lose the selection, don't tell simulator, it knows - deselectObjectAndFamily(tobjp, FALSE); - - if (tobjp->mID == id) - { - if(object_found == TRUE){ - //MikeS. adding warning... This happens when removing a linked attachment while sitting on an object.. - //I think the selection manager needs to be rewritten. BAD. - llwarns << "Detected infinite loop #2 in LLSelectMgr::removeObjectFromSelections:|" << llendl; - break; - } - object_found = TRUE; - } + deselectObjectAndFamily(object, FALSE); + object_found = TRUE; + break; // must break here, may have removed multiple objects from list + } + else if (object->isAvatar()) + { + // It's possible the item being removed has an avatar sitting on it + // So remove the avatar that is sitting on the object. + deselectObjectAndFamily(object, FALSE); + break; // must break here, may have removed multiple objects from list } - prevobjp = tobjp; } } @@ -593,7 +596,7 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s S32 select_count = 0; LLMessageSystem* msg = gMessageSystem; - for (S32 i = 0; i < objects.count(); i++) + for (U32 i = 0; i < objects.size(); i++) { if (start_new_message) { @@ -656,15 +659,12 @@ void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim) // addAsFamily //----------------------------------------------------------------------------- -void LLSelectMgr::addAsFamily(LLDynamicArray& objects, BOOL add_to_end) +void LLSelectMgr::addAsFamily(std::vector& objects, BOOL add_to_end) { - S32 count = objects.count(); - LLViewerObject *objectp = NULL; - - LLSelectNode *nodep = NULL; - for (S32 i = 0; i < count; i++) + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) { - objectp = objects.get(i); + LLViewerObject* objectp = *iter; // Can't select yourself if (objectp->mID == gAgentID @@ -675,7 +675,7 @@ void LLSelectMgr::addAsFamily(LLDynamicArray& objects, BOOL add if (!objectp->isSelected()) { - nodep = new LLSelectNode(objectp, TRUE); + LLSelectNode *nodep = new LLSelectNode(objectp, TRUE); if (add_to_end) { mSelectedObjects->addNodeAtEnd(nodep); @@ -722,14 +722,14 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab { nodep = new LLSelectNode(objectp, TRUE); mSelectedObjects->addNode(nodep); + llassert_always(nodep->getObject()); } else { // make this a full-fledged selection nodep->setTransient(FALSE); // Move it to the front of the list - mSelectedObjects->removeNode(nodep); - mSelectedObjects->addNode(nodep); + mSelectedObjects->moveNodeToFront(nodep); } // Make sure the object is tagged as selected @@ -790,14 +790,11 @@ LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp) objectp = objectp->getRootEdit(); objectp->addThisAndNonJointChildren(objects); - - S32 count = objects.count(); - LLViewerObject* cur_objectp = NULL; - LLSelectNode* nodep = NULL; - for(S32 i = 0; i < count; i++) + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) { - cur_objectp = objects[i]; - nodep = new LLSelectNode(cur_objectp, FALSE); + LLViewerObject* cur_objectp = *iter; + LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); mHoverObjects->addNodeAtEnd(nodep); } @@ -850,28 +847,30 @@ void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp) } // Note that this ignores the "select owned only" flag -// It's also more efficient than calling the single-object version over and -// over. -void LLSelectMgr::highlightObjectAndFamily(const LLDynamicArray& list) +// It's also more efficient than calling the single-object version over and over. +void LLSelectMgr::highlightObjectAndFamily(const std::vector& objects) { - S32 i; - S32 count = list.count(); - - for (i = 0; i < count; i++) + for (std::vector::const_iterator iter1 = objects.begin(); + iter1 != objects.end(); ++iter1) { - LLViewerObject* object = list.get(i); + LLViewerObject* object = *iter1; - if (!object) continue; - if (object->getPCode() != LL_PCODE_VOLUME) continue; + if (!object) + { + continue; + } + if (object->getPCode() != LL_PCODE_VOLUME) + { + continue; + } LLViewerObject* root = (LLViewerObject*)object->getRoot(); mRectSelectedObjects.insert(root); - S32 j; - S32 child_count = root->mChildList.size(); - for (j = 0; j < child_count; j++) + for (LLViewerObject::child_list_t::const_iterator iter2 = root->mChildList.begin(); + iter2 != root->mChildList.end(); ++iter2) { - LLViewerObject* child = root->mChildList[j]; + LLViewerObject* child = *iter2; mRectSelectedObjects.insert(child); } } @@ -898,9 +897,11 @@ void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp) unhighlightObjectOnly(root_obj); - for(U32 i = 0; i < root_obj->mChildList.size(); i++) + for (LLViewerObject::child_list_t::iterator iter2 = root_obj->mChildList.begin(); + iter2 != root_obj->mChildList.end(); ++iter2) { - unhighlightObjectOnly(root_obj->mChildList[i]); + LLViewerObject* child = *iter2; + unhighlightObjectOnly(child); } } @@ -921,11 +922,12 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects() //clear primary object mSelectedObjects->mPrimaryObject = NULL; - LLSelectNode *nodep; - for (nodep = mHighlightedObjects->getFirstNode(); - nodep; - nodep = mHighlightedObjects->getNextNode()) + for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin(); + iter != getHighlightedObjects()->end(); ) { + LLObjectSelection::iterator curiter = iter++; + + LLSelectNode *nodep = *curiter; LLViewerObject* objectp = nodep->getObject(); if (!canSelectObject(objectp)) @@ -997,9 +999,12 @@ void LLSelectMgr::addGridObject(LLViewerObject* objectp) { LLSelectNode* nodep = new LLSelectNode(objectp, FALSE); mGridObjects.addNodeAtEnd(nodep); - for (U32 i = 0; i < objectp->mChildList.size(); i++) + + for (LLViewerObject::child_list_t::iterator iter2 = objectp->mChildList.begin(); + iter2 != objectp->mChildList.end(); ++iter2) { - nodep = new LLSelectNode(objectp->mChildList[i], FALSE); + LLViewerObject* child = *iter2; + nodep = new LLSelectNode(child, FALSE); mGridObjects.addNodeAtEnd(nodep); } } @@ -1019,14 +1024,9 @@ void LLSelectMgr::setGridMode(EGridMode mode) void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale) { - LLSelectNode* grid_node = mGridObjects.getFirstNode(); - LLViewerObject* grid_object = mGridObjects.getFirstObject(); - // *TODO: get to work with multiple grid objects - if (grid_node && grid_node->getObject()->isDead()) - { - mGridObjects.removeNode(grid_node); - grid_object = NULL; - } + mGridObjects.cleanupNodes(); + + LLViewerObject* first_grid_object = mGridObjects.getFirstObject(); if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount()) { @@ -1035,47 +1035,42 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & mGridRotation = mSavedSelectionBBox.getRotation(); mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; } - else if (mGridMode == GRID_MODE_REF_OBJECT && grid_object && grid_object->mDrawable.notNull()) + else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull()) { - mGridRotation = grid_object->getRenderRotation(); - LLVector3 first_grid_obj_pos = grid_object->getRenderPosition(); + mGridRotation = first_grid_object->getRenderRotation(); + LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition(); LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX); - LLVector3 max_extents(-min_extents); + LLVector3 max_extents(-F32_MAX, -F32_MAX, -F32_MAX); BOOL grid_changed = FALSE; - LLSelectNode* grid_nodep; - for (grid_nodep = mGridObjects.getFirstNode(); - grid_nodep; - grid_nodep = mGridObjects.getNextNode()) + for (LLObjectSelection::iterator iter = mGridObjects.begin(); + iter != mGridObjects.end(); ++iter) + { + LLViewerObject* object = (*iter)->getObject(); + LLDrawable* drawable = object->mDrawable; + if (drawable) { - grid_object = grid_nodep->getObject(); - LLDrawable* drawable = grid_object->mDrawable; - if (drawable) - { - const LLVector3* ext = drawable->getSpatialExtents(); - update_min_max(min_extents, max_extents, ext[0]); - update_min_max(min_extents, max_extents, ext[1]); - grid_changed = TRUE; - } + const LLVector3* ext = drawable->getSpatialExtents(); + update_min_max(min_extents, max_extents, ext[0]); + update_min_max(min_extents, max_extents, ext[1]); + grid_changed = TRUE; } + } if (grid_changed) { mGridOrigin = lerp(min_extents, max_extents, 0.5f); - LLDrawable* drawable = grid_object->mDrawable; + LLDrawable* drawable = first_grid_object->mDrawable; if (drawable && drawable->isActive()) { - mGridOrigin = mGridOrigin * grid_object->getRenderMatrix(); + mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix(); } mGridScale = (max_extents - min_extents) * 0.5f; } } else // GRID_MODE_WORLD or just plain default { - LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(); - if (!first_object) - { - first_object = mSelectedObjects->getFirstObject(); - } + const BOOL non_root_ok = TRUE; + LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok); mGridOrigin.clearVec(); mGridRotation.loadIdentity(); @@ -1115,26 +1110,20 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & // remove() - an array of objects //----------------------------------------------------------------------------- -void LLSelectMgr::remove(LLDynamicArray& objects) +void LLSelectMgr::remove(std::vector& objects) { - S32 count = objects.count(); - LLViewerObject *objectp = NULL; - LLSelectNode *nodep = NULL; - for(S32 i = 0; i < count; i++) + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) { - objectp = objects.get(i); - for(nodep = mSelectedObjects->getFirstNode(); - nodep != NULL; - nodep = mSelectedObjects->getNextNode()) + LLViewerObject* objectp = *iter; + LLSelectNode* nodep = mSelectedObjects->findNode(objectp); + if (nodep) { - if(nodep->getObject() == objectp) - { - objectp->setSelected(FALSE); - mSelectedObjects->removeNode(nodep); - break; - } + objectp->setSelected(FALSE); + mSelectedObjects->removeNode(nodep); + nodep = NULL; } - } + } updateSelectionCenter(); dialog_refresh_all(); } @@ -1145,26 +1134,19 @@ void LLSelectMgr::remove(LLDynamicArray& objects) //----------------------------------------------------------------------------- void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) { - // check if object already in list - // *FIX: can we just check isSelected()? + // get object node (and verify it is in the selected list) LLSelectNode *nodep = mSelectedObjects->findNode(objectp); - if (!nodep) { return; } - // if face = all, remove object from list - if (objectp->getNumTEs() <= 0) - { - // object doesn't have faces, so blow it away - mSelectedObjects->removeNode(nodep); - objectp->setSelected( FALSE ); - } - else if (te == SELECT_ALL_TES) + if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES)) { + // Remove all faces (or the object doesn't have faces) so remove the node mSelectedObjects->removeNode(nodep); + nodep = NULL; objectp->setSelected( FALSE ); } else if (0 <= te && te < SELECT_MAX_TES) @@ -1191,9 +1173,9 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) if (!found) { mSelectedObjects->removeNode(nodep); + nodep = NULL; objectp->setSelected( FALSE ); - - // BUG: Doesn't update simulator that object is gone. + // *FIXME: Doesn't update simulator that object is no longer selected } } else @@ -1212,14 +1194,15 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) //----------------------------------------------------------------------------- void LLSelectMgr::removeAll() { - LLViewerObject *objectp; - for (objectp = mSelectedObjects->getFirstObject(); objectp; objectp = mSelectedObjects->getNextObject() ) + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++ ) { + LLViewerObject *objectp = (*iter)->getObject(); objectp->setSelected( FALSE ); } mSelectedObjects->deleteAllNodes(); - + updateSelectionCenter(); dialog_refresh_all(); } @@ -1233,19 +1216,19 @@ void LLSelectMgr::promoteSelectionToRoot() BOOL selection_changed = FALSE; - LLSelectNode* nodep; - LLViewerObject *objectp; - for (nodep = mSelectedObjects->getFirstNode(); - nodep; - nodep = mSelectedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); ) { + LLObjectSelection::iterator curiter = iter++; + LLSelectNode* nodep = *curiter; + LLViewerObject* object = nodep->getObject(); + if (nodep->mIndividualSelection) { selection_changed = TRUE; } - objectp = nodep->getObject(); - LLViewerObject* parentp = objectp; + LLViewerObject* parentp = object; while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild())) { parentp = (LLViewerObject*)parentp->getParent(); @@ -1273,19 +1256,21 @@ void LLSelectMgr::demoteSelectionToIndividuals() { LLDynamicArray objects; - for (LLViewerObject* root_objectp = mSelectedObjects->getFirstRootObject(); - root_objectp; - root_objectp = mSelectedObjects->getNextRootObject()) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) { - root_objectp->addThisAndNonJointChildren(objects); + LLViewerObject* object = (*iter)->getObject(); + object->addThisAndNonJointChildren(objects); } if (objects.getLength()) { deselectAll(); - for(S32 i = 0; i < objects.count(); i++) + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) { - selectObjectOnly(objects[i]); + LLViewerObject* objectp = *iter; + selectObjectOnly(objectp); } } } @@ -1299,14 +1284,12 @@ void LLSelectMgr::dump() llinfos << "TE mode " << mTEMode << llendl; - S32 i = 0; - - LLViewerObject *objectp; - for (objectp = mSelectedObjects->getFirstObject(); - objectp; - objectp = mSelectedObjects->getNextObject()) + S32 count = 0; + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - llinfos << "Object " << i << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl; + LLViewerObject* objectp = (*iter)->getObject(); + llinfos << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl; llinfos << " hasLSL " << objectp->flagScripted() << llendl; llinfos << " hasTouch " << objectp->flagHandleTouch() << llendl; llinfos << " hasMoney " << objectp->flagTakesMoney() << llendl; @@ -1317,16 +1300,22 @@ void LLSelectMgr::dump() LLDrawable* drawablep = objectp->mDrawable; llinfos << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << llendl; llinfos << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << llendl; - i++; + count++; } // Face iterator - S32 te; - for (mSelectedObjects->getFirstTE(&objectp, &te); - objectp; - mSelectedObjects->getNextTE(&objectp, &te)) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { - llinfos << "Object " << objectp << " te " << te << llendl; + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); + for (S32 te = 0; te < objectp->getNumTEs(); ++te ) + { + if (node->isTESelected(te)) + { + llinfos << "Object " << objectp << " te " << te << llendl; + } + } } llinfos << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << llendl; @@ -1347,6 +1336,18 @@ void LLSelectMgr::cleanup() // Manipulate properties of selected objects //--------------------------------------------------------------------------- +struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor +{ + virtual bool apply(LLViewerObject* object) + { + if (object->permModify()) + { + object->sendTEUpdate(); + } + return true; + } +}; + //----------------------------------------------------------------------------- // selectionSetImage() //----------------------------------------------------------------------------- @@ -1355,7 +1356,6 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) { // First for (no copy) textures and multiple object selection LLViewerInventoryItem* item = gInventory.getItem(imageid); - if(item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) && (mSelectedObjects->getNumNodes() > 1) ) @@ -1365,54 +1365,63 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) return; } - LLViewerObject* objectp; - S32 te; - - for (mSelectedObjects->getFirstTE(&objectp, &te); objectp; mSelectedObjects->getNextTE(&objectp, &te)) + struct f : public LLSelectedTEFunctor { - if (item) + LLViewerInventoryItem* mItem; + LLUUID mImageID; + f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {} + bool apply(LLViewerObject* objectp, S32 te) { - if (te == -1) // all faces + if (mItem) { - LLToolDragAndDrop::dropTextureAllFaces(objectp, - item, - LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); + if (te == -1) // all faces + { + LLToolDragAndDrop::dropTextureAllFaces(objectp, + mItem, + LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } + else // one face + { + LLToolDragAndDrop::dropTextureOneFace(objectp, + te, + mItem, + LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } } - else // one face + else // not an inventory item { - LLToolDragAndDrop::dropTextureOneFace(objectp, - te, - item, - LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); + // Texture picker defaults aren't inventory items + // * Don't need to worry about permissions for them + // * Can just apply the texture and be done with it. + objectp->setTEImage(te, gImageList.getImage(mImageID, TRUE, FALSE)); } + return true; } - - else // not an inventory item - { - // Texture picker defaults aren't inventory items - // * Don't need to worry about permissions for them - // * Can just apply the texture and be done with it. - objectp->setTEImage(te, gImageList.getImage(imageid)); - - objectp->sendTEUpdate(); - } - } + } setfunc(item, imageid); + getSelection()->applyToTEs(&setfunc); - - // 1 particle effect per object - if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD) + struct g : public LLSelectedObjectFunctor { - for (objectp = mSelectedObjects->getFirstObject(); objectp; objectp = mSelectedObjects->getNextObject()) + LLViewerInventoryItem* mItem; + g(LLViewerInventoryItem* item) : mItem(item) {} + virtual bool apply(LLViewerObject* object) { - LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); - effectp->setSourceObject(gAgent.getAvatarObject()); - effectp->setTargetObject(objectp); - effectp->setDuration(LL_HUD_DUR_SHORT); - effectp->setColor(LLColor4U(gAgent.getEffectColor())); + if (!mItem) + { + object->sendTEUpdate(); + // 1 particle effect per object + LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); + effectp->setSourceObject(gAgent.getAvatarObject()); + effectp->setTargetObject(object); + effectp->setDuration(LL_HUD_DUR_SHORT); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + } + return true; } - } + } sendfunc(item); + getSelection()->applyToObjects(&sendfunc); } //----------------------------------------------------------------------------- @@ -1420,24 +1429,23 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetColor(const LLColor4 &color) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, color); - } - } - - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + LLColor4 mColor; + f(const LLColor4& c) : mColor(c) {} + bool apply(LLViewerObject* object, S32 te) { - object->sendTEUpdate(); + if (object->permModify()) + { + object->setTEColor(te, mColor); + } + return true; } - } + } setfunc(color); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } //----------------------------------------------------------------------------- @@ -1445,27 +1453,26 @@ void LLSelectMgr::selectionSetColor(const LLColor4 &color) //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color) { - LLViewerObject* object; - LLColor4 new_color = color; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) - { - if (object->permModify()) - { - LLColor4 prev_color = object->getTE(te)->getColor(); - new_color.mV[VALPHA] = prev_color.mV[VALPHA]; - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, new_color); - } - } - - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + LLColor4 mColor; + f(const LLColor4& c) : mColor(c) {} + bool apply(LLViewerObject* object, S32 te) { - object->sendTEUpdate(); + if (object->permModify()) + { + LLColor4 prev_color = object->getTE(te)->getColor(); + mColor.mV[VALPHA] = prev_color.mV[VALPHA]; + // update viewer side color in anticipation of update from simulator + object->setTEColor(te, mColor); + } + return true; } - } + } setfunc(color); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } //----------------------------------------------------------------------------- @@ -1473,227 +1480,246 @@ void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color) //----------------------------------------------------------------------------- void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) - { - if (object->permModify()) - { - LLColor4 prev_color = object->getTE(te)->getColor(); - prev_color.mV[VALPHA] = alpha; - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, prev_color); - } - } - - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + F32 mAlpha; + f(const F32& a) : mAlpha(a) {} + bool apply(LLViewerObject* object, S32 te) { - object->sendTEUpdate(); + if (object->permModify()) + { + LLColor4 prev_color = object->getTE(te)->getColor(); + prev_color.mV[VALPHA] = mAlpha; + // update viewer side color in anticipation of update from simulator + object->setTEColor(te, prev_color); + } + return true; } - } + } setfunc(alpha); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionRevertColors() { - LLViewerObject* object; - S32 te; - - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + LLObjectSelectionHandle mSelectedObjects; + f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} + bool apply(LLViewerObject* object, S32 te) { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedColors.size()) + if (object->permModify()) { - LLColor4 color = nodep->mSavedColors[te]; - // update viewer side color in anticipation of update from simulator - object->setTEColor(te, color); + LLSelectNode* nodep = mSelectedObjects->findNode(object); + if (nodep && te < (S32)nodep->mSavedColors.size()) + { + LLColor4 color = nodep->mSavedColors[te]; + // update viewer side color in anticipation of update from simulator + object->setTEColor(te, color); + } } + return true; } - } - - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - } + } setfunc(mSelectedObjects); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } BOOL LLSelectMgr::selectionRevertTextures() { - LLViewerObject* object; - S32 te; - - BOOL revert_successful = TRUE; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + LLObjectSelectionHandle mSelectedObjects; + f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} + bool apply(LLViewerObject* object, S32 te) { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedTextures.size()) + if (object->permModify()) { - LLUUID id = nodep->mSavedTextures[te]; - // update textures on viewer side - if (id.isNull()) - { - // this was probably a no-copy texture, leave image as-is - revert_successful = FALSE; - } - else + LLSelectNode* nodep = mSelectedObjects->findNode(object); + if (nodep && te < (S32)nodep->mSavedTextures.size()) { - object->setTEImage(te, gImageList.getImage(id)); + LLUUID id = nodep->mSavedTextures[te]; + // update textures on viewer side + if (id.isNull()) + { + // this was probably a no-copy texture, leave image as-is + return FALSE; + } + else + { + object->setTEImage(te, gImageList.getImage(id)); + } } } + return true; } - } - - // propagate texture changes to server - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - } + } setfunc(mSelectedObjects); + BOOL revert_successful = getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); return revert_successful; } void LLSelectMgr::selectionSetBumpmap(U8 bumpmap) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) - { - if (object->permModify()) - { - // update viewer side color in anticipation of update from simulator - object->setTEBumpmap(te, bumpmap); - } - } - - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + U8 mBump; + f(const U8& b) : mBump(b) {} + bool apply(LLViewerObject* object, S32 te) { - object->sendTEUpdate(); + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEBumpmap(te, mBump); + } + return true; } - } + } setfunc(bumpmap); + getSelection()->applyToTEs(&setfunc); + + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetTexGen(U8 texgen) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + U8 mTexgen; + f(const U8& t) : mTexgen(t) {} + bool apply(LLViewerObject* object, S32 te) { - // update viewer side color in anticipation of update from simulator - object->setTETexGen(te, texgen); + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTETexGen(te, mTexgen); + } + return true; } - } + } setfunc(texgen); + getSelection()->applyToTEs(&setfunc); - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - } + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetShiny(U8 shiny) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + U8 mShiny; + f(const U8& t) : mShiny(t) {} + bool apply(LLViewerObject* object, S32 te) { - // update viewer side color in anticipation of update from simulator - object->setTEShiny(te, shiny); + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEShiny(te, mShiny); + } + return true; } - } + } setfunc(shiny); + getSelection()->applyToTEs(&setfunc); - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - } + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetFullbright(U8 fullbright) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + U8 mFullbright; + f(const U8& t) : mFullbright(t) {} + bool apply(LLViewerObject* object, S32 te) { - // update viewer side color in anticipation of update from simulator - object->setTEFullbright(te, fullbright); + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEFullbright(te, mFullbright); + } + return true; } - } + } setfunc(fullbright); + getSelection()->applyToTEs(&setfunc); - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct g : public LLSelectedObjectFunctor { - if (object->permModify()) + U8 mFullbright; + g(const U8& t) : mFullbright(t) {} + virtual bool apply(LLViewerObject* object) { - object->sendTEUpdate(); - if (fullbright) + if (object->permModify()) { - U8 material = object->getMaterial(); - U8 mcode = material & LL_MCODE_MASK; - if (mcode == LL_MCODE_LIGHT) + object->sendTEUpdate(); + if (mFullbright) { - mcode = LL_MCODE_GLASS; - material = (material & ~LL_MCODE_MASK) | mcode; - object->setMaterial(material); - object->sendMaterialUpdate(); + U8 material = object->getMaterial(); + U8 mcode = material & LL_MCODE_MASK; + if (mcode == LL_MCODE_LIGHT) + { + mcode = LL_MCODE_GLASS; + material = (material & ~LL_MCODE_MASK) | mcode; + object->setMaterial(material); + object->sendMaterialUpdate(); + } } } + return true; } - } + } sendfunc(fullbright); + getSelection()->applyToObjects(&sendfunc); } void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url) { - LLViewerObject* object; - S32 te; U8 media_flags = LLTextureEntry::MF_NONE; if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE) { media_flags = LLTextureEntry::MF_WEB_PAGE; } - - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) + + struct f : public LLSelectedTEFunctor { - if (object->permModify()) + U8 mMediaFlags; + f(const U8& t) : mMediaFlags(t) {} + bool apply(LLViewerObject* object, S32 te) { - // update viewer side color in anticipation of update from simulator - object->setTEMediaFlags(te, media_flags); + if (object->permModify()) + { + // update viewer side color in anticipation of update from simulator + object->setTEMediaFlags(te, mMediaFlags); + } + return true; } - } + } setfunc(media_flags); + getSelection()->applyToTEs(&setfunc); - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct g : public LLSelectedObjectFunctor { - if (object->permModify()) + U8 media_type; + const std::string& media_url ; + g(U8 a, const std::string& b) : media_type(a), media_url(b) {} + virtual bool apply(LLViewerObject* object) { - // JAMESDEBUG TODO set object media type - object->setMediaType(media_type); - object->setMediaURL(media_url); - - object->sendTEUpdate(); + if (object->permModify()) + { + object->sendTEUpdate(); + object->setMediaType(media_type); + object->setMediaURL(media_url); + } + return true; } - } + } sendfunc(media_type, media_url); + getSelection()->applyToObjects(&sendfunc); } @@ -1703,11 +1729,11 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& //----------------------------------------------------------------------------- LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object) { - LLSelectNode* nodep; - - for (nodep = mSelectedObjects->getFirstNode(); nodep; nodep = mSelectedObjects->getNextNode() ) + for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin(); + iter != getSelection()->valid_end(); iter++ ) { - if((nodep->getObject() == object) && nodep->mValid) + LLSelectNode* nodep = *iter; + if (nodep->getObject() == object) { return nodep->mPermissions; } @@ -1718,339 +1744,138 @@ LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object) //----------------------------------------------------------------------------- -// selectionGetTexUUID() +// selectionSetMaterial() //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectionGetTexUUID(LLUUID& id) +void LLSelectMgr::selectionSetMaterial(U8 material) { - LLViewerObject* first_objectp; - S32 first_te; - mSelectedObjects->getPrimaryTE(&first_objectp, &first_te); - - // nothing selected - if (!first_objectp) - { - return FALSE; - } - - LLViewerImage* first_imagep = first_objectp->getTEImage(first_te); - - if (!first_imagep) - { - return FALSE; - } - - BOOL identical = TRUE; - LLViewerObject *objectp; - S32 te; - for (mSelectedObjects->getFirstTE(&objectp, &te); objectp; mSelectedObjects->getNextTE(&objectp, &te) ) + struct f : public LLSelectedObjectFunctor { - if (objectp->getTEImage(te) != first_imagep) + U8 mMaterial; + f(const U8& t) : mMaterial(t) {} + virtual bool apply(LLViewerObject* object) { - identical = FALSE; - break; - } - } - - id = first_imagep->getID(); - return identical; -} - -//----------------------------------------------------------------------------- -// selectionGetColor() -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectionGetColor(LLColor4 &color) -{ - LLViewerObject* first_object; - S32 first_te; - mSelectedObjects->getPrimaryTE(&first_object, &first_te); - - // nothing selected - if (!first_object) - { - return FALSE; - } - - LLColor4 first_color; - if (!first_object->getTE(first_te)) - { - return FALSE; - } - else - { - first_color = first_object->getTE(first_te)->getColor(); - } - - BOOL identical = TRUE; - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te)) - { - if (!object->getTE(te) || (object->getTE(te)->getColor() != first_color)) - { - identical = FALSE; - break; + if (object->permModify()) + { + U8 cur_material = object->getMaterial(); + U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK); + object->setMaterial(material); + object->sendMaterialUpdate(); + } + return true; } - } - - color = first_color; - return identical; + } sendfunc(material); + getSelection()->applyToObjects(&sendfunc); } - -//----------------------------------------------------------------------------- -// selectionGetBumpmap() -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectionGetBumpmap(U8 *bumpmap) +// TRUE if all selected objects have this PCode +BOOL LLSelectMgr::selectionAllPCode(LLPCode code) { - LLViewerObject* first_object; - S32 first_te; - mSelectedObjects->getPrimaryTE(&first_object, &first_te); - - // nothing selected - if (!first_object) + struct f : public LLSelectedObjectFunctor { - return FALSE; - } - - U8 first_value; - if (!first_object->getTE(first_te)) - { - return FALSE; - } - else - { - first_value = first_object->getTE(first_te)->getBumpmap(); - } - - BOOL identical = TRUE; - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te)) - { - if (!object->getTE(te) || (object->getTE(te)->getBumpmap() != first_value)) + LLPCode mCode; + f(const LLPCode& t) : mCode(t) {} + virtual bool apply(LLViewerObject* object) { - identical = FALSE; - break; + if (object->getPCode() != mCode) + { + return FALSE; + } + return true; } - } - - *bumpmap = first_value; - return identical; + } func(code); + BOOL res = getSelection()->applyToObjects(&func); + return res; } -//----------------------------------------------------------------------------- -// selectionGetShiny() -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectionGetShiny(U8 *shiny) +bool LLSelectMgr::selectionGetIncludeInSearch(bool* include_in_search_out) { - LLViewerObject* first_object; - S32 first_te; - mSelectedObjects->getPrimaryTE(&first_object, &first_te); - - // nothing selected - if (!first_object) - { - return FALSE; - } - - U8 first_value; - if (!first_object->getTE(first_te)) - { - return FALSE; - } - else - { - first_value = first_object->getTE(first_te)->getShiny(); - } - - BOOL identical = TRUE; - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te)) - { - if (!object->getTE(te) || (object->getTE(te)->getShiny() != first_value)) - { - identical = FALSE; - break; - } - } - - *shiny = first_value; - return identical; -} + LLViewerObject *object = mSelectedObjects->getFirstRootObject(); + if (!object) return FALSE; -//----------------------------------------------------------------------------- -// selectionGetFullbright() -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectionGetFullbright(U8 *fullbright) -{ - LLViewerObject* first_object; - S32 first_te; - mSelectedObjects->getPrimaryTE(&first_object, &first_te); + bool include_in_search = object->getIncludeInSearch(); - // nothing selected - if (!first_object) - { - return FALSE; - } + bool identical = true; - U8 first_value; - if (!first_object->getTE(first_te)) - { - return FALSE; - } - else + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) { - first_value = first_object->getTE(first_te)->getFullbright(); - } + LLViewerObject* object = (*iter)->getObject(); - BOOL identical = TRUE; - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te)) - { - if (!object->getTE(te) || (object->getTE(te)->getFullbright() != first_value)) - { - identical = FALSE; - break; - } - } - - *fullbright = first_value; - return identical; -} - -// JAMESDEBUG TODO make this return mediatype off viewer object -bool LLSelectMgr::selectionGetMediaType(U8 *media_type) -{ - LLViewerObject* first_object; - S32 first_te; - mSelectedObjects->getPrimaryTE(&first_object, &first_te); - - // nothing selected - if (!first_object) - { - return false; - } - - U8 first_value; - if (!first_object->getTE(first_te)) - { - return false; - } - else - { - first_value = first_object->getTE(first_te)->getMediaFlags(); - } - - bool identical = true; - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te)) - { - if (!object->getTE(te) || (object->getTE(te)->getMediaFlags() != first_value)) + if ( include_in_search != object->getIncludeInSearch()) { identical = false; break; } } - *media_type = first_value; + *include_in_search_out = include_in_search; return identical; } - - -//----------------------------------------------------------------------------- -// selectionSetMaterial() -//----------------------------------------------------------------------------- -void LLSelectMgr::selectionSetMaterial(U8 material) -{ - LLViewerObject* object; - for (object = mSelectedObjects->getFirstObject(); object != NULL; object = mSelectedObjects->getNextObject() ) - { - if (object->permModify()) - { - U8 cur_material = object->getMaterial(); - material |= (cur_material & ~LL_MCODE_MASK); - object->setMaterial(material); - object->sendMaterialUpdate(); - } - } -} - -// True if all selected objects have this PCode -BOOL LLSelectMgr::selectionAllPCode(LLPCode code) +void LLSelectMgr::selectionSetIncludeInSearch(bool include_in_search) { - LLViewerObject *object; - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + LLViewerObject* object = NULL; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) { - if (object->getPCode() != code) - { - return FALSE; - } + object = (*iter)->getObject(); + object->setIncludeInSearch(include_in_search); } - return TRUE; + sendListToRegions( + "ObjectIncludeInSearch", + packAgentAndSessionID, + packObjectIncludeInSearch, + &include_in_search, + SEND_ONLY_ROOTS); } -//----------------------------------------------------------------------------- -// selectionGetMaterial() -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectionGetMaterial(U8 *out_material) +BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action) { LLViewerObject *object = mSelectedObjects->getFirstObject(); - if (!object) return FALSE; - - U8 material = object->getMaterial(); - - BOOL identical = TRUE; - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + if (!object) { - if ( material != object->getMaterial()) - { - identical = FALSE; - break; - } + return FALSE; } - - *out_material = material; - return identical; -} - -BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action) -{ - LLViewerObject *object = mSelectedObjects->getFirstObject(); - if (!object) return FALSE; - + U8 action = object->getClickAction(); + *out_action = action; - BOOL identical = TRUE; - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedObjectFunctor { - if ( action != object->getClickAction()) + U8 mAction; + f(const U8& t) : mAction(t) {} + virtual bool apply(LLViewerObject* object) { - identical = FALSE; - break; + if ( mAction != object->getClickAction()) + { + return false; + } + return true; } - } - - *out_action = action; - return identical; + } func(action); + BOOL res = getSelection()->applyToObjects(&func); + return res; } void LLSelectMgr::selectionSetClickAction(U8 action) { - LLViewerObject* object = NULL; - for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedObjectFunctor { - object->setClickAction(action); - } - sendListToRegions( - "ObjectClickAction", - packAgentAndSessionID, - packObjectClickAction, - &action, - SEND_INDIVIDUALS); + U8 mAction; + f(const U8& t) : mAction(t) {} + virtual bool apply(LLViewerObject* object) + { + object->setClickAction(mAction); + return true; + } + } func(action); + getSelection()->applyToObjects(&func); + + sendListToRegions("ObjectClickAction", + packAgentAndSessionID, + packObjectClickAction, + &action, + SEND_INDIVIDUALS); } @@ -2125,34 +1950,42 @@ void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *) //----------------------------------------------------------------------------- void LLSelectMgr::selectionResetRotation() { - LLQuaternion identity(0.f, 0.f, 0.f, 1.f); - - LLViewerObject* object; - for (object = mSelectedObjects->getFirstRootObject(); object; object = mSelectedObjects->getNextRootObject() ) + struct f : public LLSelectedObjectFunctor { - object->setRotation(identity); - if (object->mDrawable.notNull()) + virtual bool apply(LLViewerObject* object) { - gPipeline.markMoved(object->mDrawable, TRUE); + LLQuaternion identity(0.f, 0.f, 0.f, 1.f); + object->setRotation(identity); + if (object->mDrawable.notNull()) + { + gPipeline.markMoved(object->mDrawable, TRUE); + } + object->sendRotationUpdate(); + return true; } - object->sendRotationUpdate(); - } + } func; + getSelection()->applyToRootObjects(&func); } void LLSelectMgr::selectionRotateAroundZ(F32 degrees) { LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) ); - - LLViewerObject* object; - for (object = mSelectedObjects->getFirstRootObject(); object; object = mSelectedObjects->getNextRootObject() ) + struct f : public LLSelectedObjectFunctor { - object->setRotation( object->getRotationEdit() * rot ); - if (object->mDrawable.notNull()) + LLQuaternion mRot; + f(const LLQuaternion& rot) : mRot(rot) {} + virtual bool apply(LLViewerObject* object) { - gPipeline.markMoved(object->mDrawable, TRUE); + object->setRotation( object->getRotationEdit() * mRot ); + if (object->mDrawable.notNull()) + { + gPipeline.markMoved(object->mDrawable, TRUE); + } + object->sendRotationUpdate(); + return true; } - object->sendRotationUpdate(); - } + } func(rot); + getSelection()->applyToRootObjects(&func); } @@ -2161,86 +1994,37 @@ void LLSelectMgr::selectionRotateAroundZ(F32 degrees) //----------------------------------------------------------------------------- void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter) { - LLViewerObject* object; - S32 te; - for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te)) + struct f : public LLSelectedTEFunctor { - if (!object->permModify()) + F32 mRepeatsPerMeter; + f(const F32& t) : mRepeatsPerMeter(t) {} + bool apply(LLViewerObject* object, S32 te) { - continue; - } + + if (object->permModify()) + { + // Compute S,T to axis mapping + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + { + return TRUE; + } - if (object->getNumTEs() == 0) - { - continue; - } + F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; + F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; - // Compute S,T to axis mapping - U32 s_axis, t_axis; - if (!getTESTAxes(object, te, &s_axis, &t_axis)) - { - continue; + object->setTEScale(te, new_s, new_t); + } + return true; } + } setfunc(repeats_per_meter); + getSelection()->applyToTEs(&setfunc); - F32 new_s = object->getScale().mV[s_axis] * repeats_per_meter; - F32 new_t = object->getScale().mV[t_axis] * repeats_per_meter; - - object->setTEScale(te, new_s, new_t); - } - - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject()) - { - if (object->permModify()) - { - object->sendTEUpdate(); - } - } + LLSelectMgrSendFunctor sendfunc; + getSelection()->applyToObjects(&sendfunc); } -// BUG: Only works for boxes. -// Face numbering for flex boxes as of 1.14.2002 -//----------------------------------------------------------------------------- -// getFaceSTAxes() -//----------------------------------------------------------------------------- -BOOL LLSelectMgr::getTESTAxes(const LLViewerObject* object, const U8 face, U32* s_axis, U32* t_axis) -{ - if (face == 0) - { - *s_axis = VX; *t_axis = VY; - return TRUE; - } - else if (face == 1) - { - *s_axis = VX; *t_axis = VZ; - return TRUE; - } - else if (face == 2) - { - *s_axis = VY; *t_axis = VZ; - return TRUE; - } - else if (face == 3) - { - *s_axis = VX; *t_axis = VZ; - return TRUE; - } - else if (face == 4) - { - *s_axis = VY; *t_axis = VZ; - return TRUE; - } - else if (face == 5) - { - *s_axis = VX; *t_axis = VY; - return TRUE; - } - else - { - // unknown face - return FALSE; - } -} // Called at the end of a scale operation, this adjusts the textures to attempt to // maintain a constant repeats per meter. @@ -2250,14 +2034,12 @@ BOOL LLSelectMgr::getTESTAxes(const LLViewerObject* object, const U8 face, U32* //----------------------------------------------------------------------------- void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) { - LLViewerObject* object; - LLSelectNode* selectNode; - - BOOL send = FALSE; - - for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode()) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++) { - object = selectNode->getObject(); + LLSelectNode* selectNode = *iter; + LLViewerObject* object = selectNode->getObject(); + if (!object->permModify()) { continue; @@ -2268,6 +2050,8 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) continue; } + BOOL send = FALSE; + for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++) { const LLTextureEntry* tep = object->getTE(te_num); @@ -2277,8 +2061,11 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) { // Figure out how S,T changed with scale operation U32 s_axis, t_axis; - if (!getTESTAxes(object, te_num, &s_axis, &t_axis)) continue; - + if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis)) + { + continue; + } + LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num]; LLVector3 object_scale = object->getScale(); @@ -2301,70 +2088,23 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) { object->sendTEUpdate(); } - } -} - - -//----------------------------------------------------------------------------- -// selectionResetTexInfo() -//----------------------------------------------------------------------------- -void LLSelectMgr::selectionResetTexInfo(S32 selected_face) -{ - S32 start_face, end_face; - - LLViewerObject* object; - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject()) - { - if (!object->permModify()) - { - continue; - } - if (object->getNumTEs() == 0) - { - continue; - } - - if (selected_face == -1) - { - start_face = 0; - end_face = object->getNumTEs() - 1; - } - else - { - start_face = selected_face; - end_face = selected_face; - } - - for (S32 face = start_face; face <= end_face; face++) - { - // Actually, each object should reset to its appropriate value. - object->setTEScale(face, 1.f, 1.f); - object->setTEOffset(face, 0.f, 0.f); - object->setTERotation(face, 0.f); - } - - object->sendTEUpdate(); - } + } } //----------------------------------------------------------------------------- // selectGetAllRootsValid() -// Returns true if the viewer has information on all selected objects +// Returns TRUE if the viewer has information on all selected objects //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetAllRootsValid() { - for( LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); ++iter ) { - + LLSelectNode* node = *iter; if( !node->mValid ) { return FALSE; } - - if( !node->getObject() ) - { - return FALSE; - } } return TRUE; } @@ -2372,63 +2112,62 @@ BOOL LLSelectMgr::selectGetAllRootsValid() //----------------------------------------------------------------------------- // selectGetAllValid() -// Returns true if the viewer has information on all selected objects +// Returns TRUE if the viewer has information on all selected objects //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetAllValid() { - for( LLSelectNode* node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); ++iter ) { - + LLSelectNode* node = *iter; if( !node->mValid ) { return FALSE; } - - if( !node->getObject() ) - { - return FALSE; - } } return TRUE; } //----------------------------------------------------------------------------- -// selectGetModify() - return true if current agent can modify all +// selectGetModify() - return TRUE if current agent can modify all // selected objects. //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetModify() { - for( LLSelectNode* node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++ ) { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); if( !node->mValid ) { return FALSE; } - LLViewerObject* object = node->getObject(); - if( !object || !object->permModify() ) + if( !object->permModify() ) { return FALSE; } } - return TRUE; } //----------------------------------------------------------------------------- -// selectGetRootsModify() - return true if current agent can modify all +// selectGetRootsModify() - return TRUE if current agent can modify all // selected root objects. //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsModify() { - for( LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); if( !node->mValid ) { return FALSE; } - LLViewerObject* object = node->getObject(); - if( !object || !object->permModify() ) + if( !object->permModify() ) { return FALSE; } @@ -2439,19 +2178,21 @@ BOOL LLSelectMgr::selectGetRootsModify() //----------------------------------------------------------------------------- -// selectGetRootsTransfer() - return true if current agent can transfer all +// selectGetRootsTransfer() - return TRUE if current agent can transfer all // selected root objects. //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsTransfer() { - for(LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - if(!node->mValid) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) { return FALSE; } - LLViewerObject* object = node->getObject(); - if(!object || !object->permTransfer()) + if(!object->permTransfer()) { return FALSE; } @@ -2460,19 +2201,21 @@ BOOL LLSelectMgr::selectGetRootsTransfer() } //----------------------------------------------------------------------------- -// selectGetRootsCopy() - return true if current agent can copy all +// selectGetRootsCopy() - return TRUE if current agent can copy all // selected root objects. //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetRootsCopy() { - for(LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - if(!node->mValid) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if( !node->mValid ) { return FALSE; } - LLViewerObject* object = node->getObject(); - if(!object || !object->permCopy()) + if(!object->permCopy()) { return FALSE; } @@ -2484,39 +2227,42 @@ BOOL LLSelectMgr::selectGetRootsCopy() // selectGetCreator() // Creator information only applies to root objects. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetCreator(LLUUID& id, LLString& name) +BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, LLString& name) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if(!node) node = mSelectedObjects->getFirstNode(); - if(!node) return FALSE; - if(!node->mValid) return FALSE; - LLViewerObject* obj = node->getObject(); - if(!obj) return FALSE; - if(!(obj->isRoot() || obj->isJointChild())) return FALSE; - - id = node->mPermissions->getCreator(); - BOOL identical = TRUE; - for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + BOOL first = TRUE; + LLUUID first_id; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; if (!node->mValid) { - identical = FALSE; - break; + return FALSE; } - if ( !(id == node->mPermissions->getCreator() ) ) + if (first) { - identical = FALSE; - break; + first_id = node->mPermissions->getCreator(); + first = FALSE; + } + else + { + if ( !(first_id == node->mPermissions->getCreator() ) ) + { + identical = FALSE; + break; + } } } + result_id = first_id; + if (identical) { char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(id, firstname, lastname); + gCacheName->getName(first_id, firstname, lastname); name.assign( firstname ); name.append( " " ); name.append( lastname ); @@ -2534,44 +2280,45 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& id, LLString& name) // selectGetOwner() // Owner information only applies to roots. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name) +BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, LLString& name) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if(!node) node = mSelectedObjects->getFirstNode(); - if(!node) return FALSE; - if(!node->mValid) return FALSE; - LLViewerObject* obj = node->getObject(); - if(!obj) return FALSE; - if(!(obj->isRootEdit() || obj->isRoot() || obj->isJointChild())) return FALSE; - - BOOL group_owner = FALSE; - id.setNull(); - node->mPermissions->getOwnership(id, group_owner); - BOOL identical = TRUE; - for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + BOOL first = TRUE; + BOOL first_group_owned = FALSE; + LLUUID first_id; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; if (!node->mValid) { - identical = FALSE; - break; + return FALSE; } - - LLUUID owner_id; - BOOL is_group_owned = FALSE; - if (!(node->mPermissions->getOwnership(owner_id, is_group_owned)) - || owner_id != id ) + + if (first) { - identical = FALSE; - break; + node->mPermissions->getOwnership(first_id, first_group_owned); + first = FALSE; + } + else + { + LLUUID owner_id; + BOOL is_group_owned = FALSE; + if (!(node->mPermissions->getOwnership(owner_id, is_group_owned)) + || owner_id != first_id || is_group_owned != first_group_owned) + { + identical = FALSE; + break; + } } } - BOOL public_owner = (id.isNull() && !group_owner); - + result_id = first_id; + if (identical) { - if (group_owner) + BOOL public_owner = (first_id.isNull() && !first_group_owned); + if (first_group_owned) { name.assign( "(Group Owned)"); } @@ -2579,7 +2326,7 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name) { char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(id, firstname, lastname); + gCacheName->getName(first_id, firstname, lastname); name.assign( firstname ); name.append( " " ); name.append( lastname ); @@ -2602,43 +2349,45 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name) // selectGetLastOwner() // Owner information only applies to roots. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetLastOwner(LLUUID& id, LLString& name) +BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, LLString& name) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if(!node) node = mSelectedObjects->getFirstNode(); - if(!node) return FALSE; - if(!node->mValid) return FALSE; - LLViewerObject* obj = node->getObject(); - if(!obj) return FALSE; - if(!(obj->isRoot() || obj->isJointChild())) return FALSE; - - id = node->mPermissions->getLastOwner(); - BOOL identical = TRUE; - for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + BOOL first = TRUE; + LLUUID first_id; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; if (!node->mValid) { - identical = FALSE; - break; + return FALSE; } - if ( !(id == node->mPermissions->getLastOwner() ) ) + if (first) { - identical = FALSE; - break; + first_id = node->mPermissions->getLastOwner(); + first = FALSE; + } + else + { + if ( !(first_id == node->mPermissions->getLastOwner() ) ) + { + identical = FALSE; + break; + } } } - BOOL public_owner = (id.isNull()); - + result_id = first_id; + if (identical) { + BOOL public_owner = (first_id.isNull()); if(!public_owner) { char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ - gCacheName->getName(id, firstname, lastname); + gCacheName->getName(first_id, firstname, lastname); name.assign( firstname ); name.append( " " ); name.append( lastname ); @@ -2661,33 +2410,36 @@ BOOL LLSelectMgr::selectGetLastOwner(LLUUID& id, LLString& name) // selectGetGroup() // Group information only applies to roots. //----------------------------------------------------------------------------- -BOOL LLSelectMgr::selectGetGroup(LLUUID& id) +BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if(!node) node = mSelectedObjects->getFirstNode(); - if(!node) return FALSE; - if(!node->mValid) return FALSE; - LLViewerObject* obj = node->getObject(); - if(!obj) return FALSE; - if(!(obj->isRoot() || obj->isJointChild())) return FALSE; - - id = node->mPermissions->getGroup(); - BOOL identical = TRUE; - for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + BOOL first = TRUE; + LLUUID first_id; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; if (!node->mValid) { - identical = FALSE; - break; + return FALSE; } - if ( !(id == node->mPermissions->getGroup() ) ) + if (first) { - identical = FALSE; - break; + first_id = node->mPermissions->getGroup(); + first = FALSE; + } + else + { + if ( !(first_id == node->mPermissions->getGroup() ) ) + { + identical = FALSE; + break; + } } } + + result_id = first_id; return identical; } @@ -2699,64 +2451,53 @@ BOOL LLSelectMgr::selectGetGroup(LLUUID& id) //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectIsGroupOwned() { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if(!node) node = mSelectedObjects->getFirstNode(); - if(!node) return FALSE; - if(!node->mValid) return FALSE; - LLViewerObject* obj = node->getObject(); - if(!obj) return FALSE; - if(!(obj->isRoot() || obj->isJointChild())) return FALSE; - - BOOL is_group_owned = node->mPermissions->isGroupOwned(); - - if(is_group_owned) + BOOL found_one = FALSE; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + LLSelectNode* node = *iter; + if (!node->mValid) { - if (!node->mValid) - { - is_group_owned = FALSE; - break; - } - - if ( !( node->mPermissions->isGroupOwned() ) ) - { - is_group_owned = FALSE; - break; - } + return FALSE; } - } - return is_group_owned; + found_one = TRUE; + if (!node->mPermissions->isGroupOwned()) + { + return FALSE; + } + } + return found_one ? TRUE : FALSE; } //----------------------------------------------------------------------------- // selectGetPerm() // Only operates on root nodes. // Returns TRUE if all have valid data. -// mask_on has bits set to true where all permissions are true -// mask_off has bits set to true where all permissions are false +// mask_on has bits set to TRUE where all permissions are TRUE +// mask_off has bits set to TRUE where all permissions are FALSE // if a bit is off both in mask_on and mask_off, the values differ within // the selection. //----------------------------------------------------------------------------- BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if (!node) return FALSE; - if (!node->mValid) return FALSE; - U32 mask; U32 mask_and = 0xffffffff; U32 mask_or = 0x00000000; - BOOL all_valid = TRUE; + BOOL all_valid = FALSE; - for ( node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) { + LLSelectNode* node = *iter; + if (!node->mValid) { all_valid = FALSE; break; } + all_valid = TRUE; + switch( which_perm ) { case PERM_BASE: @@ -2784,10 +2525,10 @@ BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off) if (all_valid) { - // ...true through all ANDs means all true + // ...TRUE through all ANDs means all TRUE *mask_on = mask_and; - // ...false through all ORs means all false + // ...FALSE through all ORs means all FALSE *mask_off = ~mask_or; return TRUE; } @@ -2806,23 +2547,33 @@ BOOL LLSelectMgr::selectGetOwnershipCost(S32* out_cost) return mSelectedObjects->getOwnershipCost(*out_cost); } -BOOL LLSelectMgr::selectGetPermissions(LLPermissions& perm) +BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if (!node) return FALSE; - if (!node->mValid) return FALSE; - BOOL valid = TRUE; - perm = *(node->mPermissions); - for(node = mSelectedObjects->getNextRootNode(); node != NULL; node = mSelectedObjects->getNextRootNode()) + BOOL first = TRUE; + LLPermissions perm; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - if(!node->mValid) + LLSelectNode* node = *iter; + if (!node->mValid) { - valid = FALSE; - break; + return FALSE; + } + + if (first) + { + perm = *(node->mPermissions); + first = FALSE; + } + else + { + perm.accumulate(*(node->mPermissions)); } - perm.accumulate(*(node->mPermissions)); } - return valid; + + result_perm = perm; + + return TRUE; } @@ -2833,10 +2584,12 @@ void LLSelectMgr::selectDelete() BOOL locked_but_deleteable_object = FALSE; BOOL no_copy_but_deleteable_object = FALSE; BOOL all_owned_by_you = TRUE; - for(LLViewerObject* obj = mSelectedObjects->getFirstObject(); - obj != NULL; - obj = mSelectedObjects->getNextObject()) + + for (LLObjectSelection::iterator iter = getSelection()->begin(); + iter != getSelection()->end(); iter++) { + LLViewerObject* obj = (*iter)->getObject(); + if( obj->isAttachment() ) { continue; @@ -2958,10 +2711,10 @@ void LLSelectMgr::confirmDelete(S32 option, void* data) // attempt to derez into the trash. LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id); gSelectMgr->sendListToRegions("DeRezObject", - packDeRezHeader, - packObjectLocalID, - (void*)info, - SEND_ONLY_ROOTS); + packDeRezHeader, + packObjectLocalID, + (void*)info, + SEND_ONLY_ROOTS); // VEFFECT: Delete Object - one effect for all deletes if (gSelectMgr->mSelectedObjects->mSelectType != SELECT_TYPE_HUD) { @@ -3006,9 +2759,10 @@ BOOL LLSelectMgr::selectIsForSale(S32& price) BOOL any_for_sale = FALSE; price = 0; - LLSelectNode *node; - for (node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++) { + LLSelectNode* node = *iter; if (node->mSaleInfo.isForSale()) { price += node->mSaleInfo.getSalePrice(); @@ -3022,61 +2776,92 @@ BOOL LLSelectMgr::selectIsForSale(S32& price) // returns TRUE if all nodes are valid. method also stores an // accumulated sale info. -BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& sale_info) +BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& result_sale_info) { - LLSelectNode* node = mSelectedObjects->getFirstRootNode(); - if (!node) return FALSE; - if (!node->mValid) return FALSE; - BOOL valid = TRUE; - sale_info = node->mSaleInfo; - for(node = mSelectedObjects->getNextRootNode(); node != NULL; node = mSelectedObjects->getNextRootNode()) + BOOL first = TRUE; + LLSaleInfo sale_info; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - if(!node->mValid) + LLSelectNode* node = *iter; + if (!node->mValid) { - valid = FALSE; - break; + return FALSE; + } + + if (first) + { + sale_info = node->mSaleInfo; + first = FALSE; + } + else + { + sale_info.accumulate(node->mSaleInfo); } - sale_info.accumulate(node->mSaleInfo); } - return valid; + + result_sale_info = sale_info; + + return TRUE; } -BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& ag_perm) +BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& result_perm) { - LLSelectNode* node = mSelectedObjects->getFirstNode(); - if (!node) return FALSE; - if (!node->mValid) return FALSE; - BOOL valid = TRUE; - ag_perm = node->mAggregatePerm; - for(node = mSelectedObjects->getNextNode(); node != NULL; node = mSelectedObjects->getNextNode()) + BOOL first = TRUE; + LLAggregatePermissions perm; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - if(!node->mValid) + LLSelectNode* node = *iter; + if (!node->mValid) { - valid = FALSE; - break; + return FALSE; + } + + if (first) + { + perm = node->mAggregatePerm; + first = FALSE; + } + else + { + perm.aggregate(node->mAggregatePerm); } - ag_perm.aggregate(node->mAggregatePerm); } - return valid; + + result_perm = perm; + + return TRUE; } -BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm) +BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& result_perm) { - LLSelectNode* node = mSelectedObjects->getFirstNode(); - if (!node) return FALSE; - if (!node->mValid) return FALSE; - BOOL valid = TRUE; - ag_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm; - for(node = mSelectedObjects->getNextNode(); node != NULL; node = mSelectedObjects->getNextNode()) + BOOL first = TRUE; + LLAggregatePermissions perm; + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { - if(!node->mValid) + LLSelectNode* node = *iter; + if (!node->mValid) { - valid = FALSE; - break; + return FALSE; + } + + LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm; + if (first) + { + perm = t_perm; + first = FALSE; + } + else + { + perm.aggregate(t_perm); } - ag_perm.aggregate(node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm); } - return valid; + + result_perm = perm; + + return TRUE; } @@ -3115,8 +2900,10 @@ void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy) } else { - for (LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; node->mDuplicated = TRUE; node->mDuplicatePos = node->getObject()->getPositionGlobal(); node->mDuplicateRot = node->getObject()->getRotation(); @@ -3133,21 +2920,24 @@ void LLSelectMgr::repeatDuplicate() return; } - LLSelectNode* node; - LLDynamicArray non_duplicated_objects; + std::vector non_duplicated_objects; - for (node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; if (!node->mDuplicated) { - non_duplicated_objects.put(node->getObject()); + non_duplicated_objects.push_back(node->getObject()); } } // make sure only previously duplicated objects are selected - for (S32 i = 0; i < non_duplicated_objects.count(); i++) + for (std::vector::iterator iter = non_duplicated_objects.begin(); + iter != non_duplicated_objects.end(); ++iter) { - deselectObjectAndFamily(non_duplicated_objects[i]); + LLViewerObject* objectp = *iter; + deselectObjectAndFamily(objectp); } // duplicate objects in place @@ -3159,8 +2949,10 @@ void LLSelectMgr::repeatDuplicate() sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, &data, SEND_ONLY_ROOTS); // move current selection based on delta from duplication position and update duplication position - for (node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) + for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); + iter != getSelection()->root_end(); iter++ ) { + LLSelectNode* node = *iter; if (node->mDuplicated) { LLQuaternion cur_rot = node->getObject()->getRotation(); @@ -3380,7 +3172,7 @@ void LLSelectMgr::sendGroup(const LLUUID& group_id) struct LLBuyData { - LLDynamicArray mObjectsSent; + std::vector mObjectsSent; LLUUID mCategoryID; LLSaleInfo mSaleInfo; }; @@ -3403,9 +3195,9 @@ void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data) LLBuyData* buy = (LLBuyData*)data; LLViewerObject* object = node->getObject(); - if(buy->mObjectsSent.find(object) == LLDynamicArray::FAIL) + if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end()) { - buy->mObjectsSent.put(object); + buy->mObjectsSent.push_back(object); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType()); @@ -3480,7 +3272,6 @@ void LLSelectMgr::deselectAll() mLastSentSelectionCenterGlobal.clearVec(); updatePointAt(); - updateSelectionCenter(); } void LLSelectMgr::deselectUnused() @@ -3494,7 +3285,6 @@ void LLSelectMgr::deselectUnused() void LLSelectMgr::convertTransient() { - // use STL-style iteration to avoid recursive iteration problems LLObjectSelection::iterator node_it; for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it) { @@ -3772,32 +3562,42 @@ void LLSelectMgr::packHingeHead(void *user_data) void LLSelectMgr::selectionDump() { - LLViewerObject *object; - - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + struct f : public LLSelectedObjectFunctor { - object->dump(); - } + virtual bool apply(LLViewerObject* object) + { + object->dump(); + return true; + } + } func; + getSelection()->applyToObjects(&func); } void LLSelectMgr::saveSelectedObjectColors() { - LLSelectNode* selectNode; - for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode() ) + struct f : public LLSelectedNodeFunctor { - selectNode->saveColors(); - } + virtual bool apply(LLSelectNode* node) + { + node->saveColors(); + return true; + } + } func; + getSelection()->applyToNodes(&func); } void LLSelectMgr::saveSelectedObjectTextures() { - LLSelectNode* selectNode; - // invalidate current selection so we update saved textures - for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode() ) + struct f : public LLSelectedNodeFunctor { - selectNode->mValid = FALSE; - } + virtual bool apply(LLSelectNode* node) + { + node->mValid = FALSE; + return true; + } + } func; + getSelection()->applyToNodes(&func); // request object properties message to get updated permissions data sendSelect(); @@ -3808,113 +3608,95 @@ void LLSelectMgr::saveSelectedObjectTextures() // also need to know to which simulator to send update message void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type) { - LLSelectNode* selectNode; - if (mSelectedObjects->isEmpty()) { // nothing selected, so nothing to save return; } - for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode() ) + struct f : public LLSelectedNodeFunctor { - LLViewerObject* object; - object = selectNode->getObject(); - selectNode->mSavedPositionLocal = object->getPosition(); - if (object->isAttachment()) + EActionType mActionType; + f(EActionType a) : mActionType(a) {} + virtual bool apply(LLSelectNode* selectNode) { - if (object->isRootEdit()) + LLViewerObject* object = selectNode->getObject(); + selectNode->mSavedPositionLocal = object->getPosition(); + if (object->isAttachment()) { - LLXform* parent_xform = object->mDrawable->getXform()->getParent(); - if (parent_xform) + if (object->isRootEdit()) { - selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition()); + LLXform* parent_xform = object->mDrawable->getXform()->getParent(); + if (parent_xform) + { + selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition()); + } } + else + { + LLViewerObject* attachment_root = (LLViewerObject*)object->getParent(); + LLXform* parent_xform = attachment_root->mDrawable->getXform()->getParent(); + LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition(); + LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation()); + selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos); + } + selectNode->mSavedRotation = object->getRenderRotation(); } else { - LLViewerObject* attachment_root = (LLViewerObject*)object->getParent(); - LLXform* parent_xform = attachment_root->mDrawable->getXform()->getParent(); - LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition(); - LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation()); - selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos); + selectNode->mSavedPositionGlobal = object->getPositionGlobal(); + selectNode->mSavedRotation = object->getRotationRegion(); } - selectNode->mSavedRotation = object->getRenderRotation(); - } - else - { - selectNode->mSavedPositionGlobal = object->getPositionGlobal(); - selectNode->mSavedRotation = object->getRotationRegion(); - } - selectNode->mSavedScale = object->getScale(); - selectNode->saveTextureScaleRatios(); - - } + selectNode->mSavedScale = object->getScale(); + selectNode->saveTextureScaleRatios(); + return true; + } + } func(action_type); + getSelection()->applyToNodes(&func); + mSavedSelectionBBox = getBBoxOfSelection(); } -void LLSelectMgr::selectionUpdatePhysics(BOOL physics) +struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor { - LLViewerObject *object; - - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {} + U32 mFlags; + BOOL mState; + virtual bool apply(LLViewerObject* object) { - if ( !object->permModify() // preemptive permissions check - || !(object->isRoot() // don't send for child objects - || object->isJointChild())) + if ( object->permModify() && // preemptive permissions check + object->isRoot() && // don't send for child objects + !object->isJointChild()) { - continue; + object->setFlags( mFlags, mState); } - object->setFlags( FLAGS_USE_PHYSICS, physics); + return true; } +}; + +void LLSelectMgr::selectionUpdatePhysics(BOOL physics) +{ + LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics); + getSelection()->applyToObjects(&func); } void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary) { - LLViewerObject *object; - - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if ( !object->permModify() // preemptive permissions check - || !(object->isRoot() // don't send for child objects - || object->isJointChild())) - { - continue; - } - object->setFlags( FLAGS_TEMPORARY_ON_REZ, is_temporary); - } + LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary); + getSelection()->applyToObjects(&func); } void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom) { - LLViewerObject *object; - - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if ( !object->permModify() // preemptive permissions check - || !(object->isRoot() // don't send for child objects - || object->isJointChild())) - { - continue; - } - object->setFlags( FLAGS_PHANTOM, is_phantom); - } + LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom); + getSelection()->applyToObjects(&func); } void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows) { - LLViewerObject *object; - - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) - { - if ( !object->permModify() // preemptive permissions check - || object->isJointChild()) - { - continue; - } - object->setFlags( FLAGS_CAST_SHADOWS, cast_shadows); - } + LLSelectMgrApplyFlags func( FLAGS_CAST_SHADOWS, cast_shadows); + getSelection()->applyToObjects(&func); } @@ -4042,6 +3824,13 @@ void LLSelectMgr::packObjectClickAction(LLSelectNode* node, void *user_data) gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction()); } +void LLSelectMgr::packObjectIncludeInSearch(LLSelectNode* node, void *user_data) +{ + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); + gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch()); +} + // static void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *) { @@ -4130,82 +3919,81 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name, S32 packets_sent = 0; S32 objects_in_this_packet = 0; - //clear update override data (allow next update through) - for (node = mSelectedObjects->getFirstNode(); - node; - node = mSelectedObjects->getNextNode()) + struct f : public LLSelectedNodeFunctor { - node->mLastPositionLocal.setVec(0,0,0); - node->mLastRotation = LLQuaternion(); - node->mLastScale.setVec(0,0,0); - } + virtual bool apply(LLSelectNode* node) + { + node->mLastPositionLocal.setVec(0,0,0); + node->mLastRotation = LLQuaternion(); + node->mLastScale.setVec(0,0,0); + return true; + } + } func; + getSelection()->applyToNodes(&func); std::queue nodes_to_send; - - switch(send_type) + + struct push_all : public LLSelectedNodeFunctor { - case SEND_ONLY_ROOTS: - node = mSelectedObjects->getFirstRootNode(); - while(node) + std::queue& nodes_to_send; + push_all(std::queue& n) : nodes_to_send(n) {} + virtual bool apply(LLSelectNode* node) { nodes_to_send.push(node); - node = mSelectedObjects->getNextRootNode(); + return true; } - break; - case SEND_INDIVIDUALS: - node = mSelectedObjects->getFirstNode(); - while(node) - { - nodes_to_send.push(node); - node = mSelectedObjects->getNextNode(); - } - break; - case SEND_ROOTS_FIRST: - // first roots... - node = mSelectedObjects->getFirstNode(); - while(node) + }; + struct push_some : public LLSelectedNodeFunctor + { + std::queue& nodes_to_send; + bool mRoots; + push_some(std::queue& n, bool roots) : nodes_to_send(n), mRoots(roots) {} + virtual bool apply(LLSelectNode* node) { - if (node->getObject()->isRootEdit()) + BOOL is_root = node->getObject()->isRootEdit(); + if ((mRoots && is_root) || (!mRoots && !is_root)) { nodes_to_send.push(node); } - node = mSelectedObjects->getNextNode(); + return true; } - - // then children... - node = mSelectedObjects->getFirstNode(); - while(node) + }; + struct push_editable : public LLSelectedNodeFunctor + { + std::queue& nodes_to_send; + push_editable(std::queue& n) : nodes_to_send(n) {} + virtual bool apply(LLSelectNode* node) { - if (!node->getObject()->isRootEdit()) - { - nodes_to_send.push(node); - } - node = mSelectedObjects->getNextNode(); + + nodes_to_send.push(node); + return true; } + }; + struct push_all pushall(nodes_to_send); + struct push_some pushroots(nodes_to_send, TRUE); + struct push_some pushnonroots(nodes_to_send, FALSE); + struct push_editable pusheditable(nodes_to_send); + + switch(send_type) + { + case SEND_ONLY_ROOTS: + getSelection()->applyToRootNodes(&pusheditable); + break; + case SEND_INDIVIDUALS: + getSelection()->applyToNodes(&pushall); + break; + case SEND_ROOTS_FIRST: + // first roots... + getSelection()->applyToNodes(&pushroots); + // then children... + getSelection()->applyToNodes(&pushnonroots); break; - case SEND_CHILDREN_FIRST: + case SEND_CHILDREN_FIRST: // first children... - node = mSelectedObjects->getFirstNode(); - while(node) - { - if (!node->getObject()->isRootEdit()) - { - nodes_to_send.push(node); - } - node = mSelectedObjects->getNextNode(); - } - - // ...then roots - node = mSelectedObjects->getFirstNode(); - while(node) - { - if (node->getObject()->isRootEdit()) - { - nodes_to_send.push(node); - } - node = mSelectedObjects->getNextNode(); - } + getSelection()->applyToNodes(&pushnonroots); + // then roots... + getSelection()->applyToNodes(&pushroots); break; default: @@ -4213,8 +4001,11 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name, } // bail if nothing selected - if (nodes_to_send.empty()) return; - + if (nodes_to_send.empty()) + { + return; + } + node = nodes_to_send.front(); nodes_to_send.pop(); @@ -4376,27 +4167,24 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES) { - LLUUID id; - memcpy(id.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */ - texture_ids.push_back(id); + LLUUID tid; + memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */ + texture_ids.push_back(tid); } } // Iterate through nodes at end, since it can be on both the regular AND hover list - BOOL found = FALSE; - LLSelectNode* node; - for (node = gSelectMgr->mSelectedObjects->getFirstNode(); - node; - node = gSelectMgr->mSelectedObjects->getNextNode()) + struct f : public LLSelectedNodeFunctor { - if (node->getObject()->mID == id) + LLUUID mID; + f(const LLUUID& id) : mID(id) {} + virtual bool apply(LLSelectNode* node) { - found = TRUE; - break; + return (node->getObject()->mID == mID); } - } - + } func(id); + LLSelectNode* node = gSelectMgr->getSelection()->getFirstNode(&func); if (node) { @@ -4529,23 +4317,21 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use LLString fullname(first_name); fullname.append(" "); fullname.append(last_name); - reporterp->setPickedObjectProperties(name, fullname.c_str(), owner_id); + reporterp->setPickedObjectProperties(name, fullname, owner_id); } } // Now look through all of the hovered nodes - BOOL found = FALSE; - LLSelectNode* node; - for (node = gSelectMgr->mHoverObjects->getFirstNode(); - node; - node = gSelectMgr->mHoverObjects->getNextNode()) + struct f : public LLSelectedNodeFunctor { - if (node->getObject()->mID == id) + LLUUID mID; + f(const LLUUID& id) : mID(id) {} + virtual bool apply(LLSelectNode* node) { - found = TRUE; - break; + return (node->getObject()->mID == mID); } - } + } func(id); + LLSelectNode* node = gSelectMgr->getHoverObjects()->getFirstNode(&func); if (node) { @@ -4577,7 +4363,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**) LLUUID full_id; S32 local_id; LLViewerObject* object; - LLDynamicArray objects; + std::vector objects; S32 i; S32 block_count = msg->getNumberOfBlocks("Data"); @@ -4592,7 +4378,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**) object = gObjectList.findObject(full_id); if (object) { - objects.put(object); + objects.push_back(object); } } @@ -4605,7 +4391,6 @@ extern LLGLdouble gGLModelView[16]; void LLSelectMgr::updateSilhouettes() { - LLSelectNode *node; S32 num_sils_genned = 0; LLVector3d cameraPos = gAgent.getCameraPositionGlobal(); @@ -4618,21 +4403,24 @@ void LLSelectMgr::updateSilhouettes() mSilhouetteImagep = gImageList.getImage(id, TRUE, TRUE); } + mHighlightedObjects->cleanupNodes(); if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom) { - for (node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) + struct f : public LLSelectedObjectFunctor { - if (node->getObject()) + virtual bool apply(LLViewerObject* object) { - node->getObject()->setChanged(LLXform::SILHOUETTE); + object->setChanged(LLXform::SILHOUETTE); + return true; } - } + } func; + getSelection()->applyToObjects(&func); mLastCameraPos = gAgent.getCameraPositionGlobal(); } - LLDynamicArray changed_objects; + std::vector changed_objects; if (mSelectedObjects->getNumNodes()) { @@ -4643,8 +4431,10 @@ void LLSelectMgr::updateSilhouettes() for (S32 pass = 0; pass < 2; pass++) { - for (node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++) { + LLSelectNode* node = *iter; LLViewerObject* objectp = node->getObject(); // do roots first, then children so that root flags are cleared ASAP @@ -4662,7 +4452,7 @@ void LLSelectMgr::updateSilhouettes() if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible()) { generateSilhouette(node, gCamera->getOrigin()); - changed_objects.put(objectp); + changed_objects.push_back(objectp); } else if (objectp->isAttachment()) { @@ -4711,20 +4501,23 @@ void LLSelectMgr::updateSilhouettes() } // remove highlight nodes not in roots list - LLDynamicArray remove_these_nodes; - LLDynamicArray remove_these_roots; - for (LLSelectNode* nodep = mHighlightedObjects->getFirstNode(); nodep; nodep = mHighlightedObjects->getNextNode()) + std::vector remove_these_nodes; + std::vector remove_these_roots; + + for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); + iter != mHighlightedObjects->end(); iter++) { - LLViewerObject* objectp = nodep->getObject(); + LLSelectNode* node = *iter; + LLViewerObject* objectp = node->getObject(); if (objectp->isRoot() || !select_linked_set) { if (roots.count(objectp) == 0) { - remove_these_nodes.put(nodep); + remove_these_nodes.push_back(node); } else { - remove_these_roots.put(objectp); + remove_these_roots.push_back(objectp); } } else @@ -4733,22 +4526,25 @@ void LLSelectMgr::updateSilhouettes() if (roots.count(rootp) == 0) { - remove_these_nodes.put(nodep); + remove_these_nodes.push_back(node); } } } // remove all highlight nodes no longer in rectangle selection - S32 i; - for (i = 0; i < remove_these_nodes.count(); i++) + for (std::vector::iterator iter = remove_these_nodes.begin(); + iter != remove_these_nodes.end(); ++iter) { - mHighlightedObjects->removeNode(remove_these_nodes[i]); + LLSelectNode* nodep = *iter; + mHighlightedObjects->removeNode(nodep); } // remove all root objects already being highlighted - for (i = 0; i < remove_these_roots.count(); i++) + for (std::vector::iterator iter = remove_these_roots.begin(); + iter != remove_these_roots.end(); ++iter) { - roots.erase(remove_these_roots[i]); + LLViewerObject* objectp = *iter; + roots.erase(objectp); } // add all new objects in rectangle selection @@ -4756,36 +4552,38 @@ void LLSelectMgr::updateSilhouettes() iter != roots.end(); iter++) { LLViewerObject* objectp = *iter; - LLSelectNode* rect_select_node = new LLSelectNode(objectp, TRUE); - rect_select_node->selectAllTEs(TRUE); + LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE); + rect_select_root_node->selectAllTEs(TRUE); if (!canSelectObject(objectp)) { continue; } - mHighlightedObjects->addNode(rect_select_node); - if (!select_linked_set) { - rect_select_node->mIndividualSelection = TRUE; + rect_select_root_node->mIndividualSelection = TRUE; } else { - for (U32 i = 0; i < objectp->mChildList.size(); i++) + for (LLViewerObject::child_list_t::iterator iter = objectp->mChildList.begin(); + iter != objectp->mChildList.end(); ++iter) { - LLViewerObject* child_objectp = objectp->mChildList[i]; - + LLViewerObject* child_objectp = *iter; + if (!canSelectObject(child_objectp)) { continue; } - rect_select_node = new LLSelectNode(objectp->mChildList[i], TRUE); + LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE); rect_select_node->selectAllTEs(TRUE); - mHighlightedObjects->addNode(rect_select_node); + mHighlightedObjects->addNodeAtEnd(rect_select_node); } } + + // Add the root last, to preserve order for link operations. + mHighlightedObjects->addNodeAtEnd(rect_select_root_node); } num_sils_genned = 0; @@ -4794,8 +4592,10 @@ void LLSelectMgr::updateSilhouettes() //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); for (S32 pass = 0; pass < 2; pass++) { - for (node = mHighlightedObjects->getFirstNode(); node; node = mHighlightedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); + iter != mHighlightedObjects->end(); iter++) { + LLSelectNode* node = *iter; LLViewerObject* objectp = node->getObject(); // do roots first, then children so that root flags are cleared ASAP @@ -4813,7 +4613,7 @@ void LLSelectMgr::updateSilhouettes() if (num_sils_genned++ < MAX_SILS_PER_FRAME) { generateSilhouette(node, gCamera->getOrigin()); - changed_objects.put(objectp); + changed_objects.push_back(objectp); } else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull()) { @@ -4846,10 +4646,12 @@ void LLSelectMgr::updateSilhouettes() mHighlightedObjects->deleteAllNodes(); } - for (S32 i = 0; i < changed_objects.count(); i++) + for (std::vector::iterator iter = changed_objects.begin(); + iter != changed_objects.end(); ++iter) { // clear flags after traversing node list (as child objects need to refer to parent flags, etc) - changed_objects[i]->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE); + LLViewerObject* objectp = *iter; + objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE); } //glAlphaFunc(GL_GREATER, 0.01f); @@ -4862,8 +4664,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) return; } - LLSelectNode *node; - LLViewerImage::bindTexture(gSelectMgr->mSilhouetteImagep); + LLViewerImage::bindTexture(mSilhouetteImagep); LLGLSPipelineSelection gls_select; glAlphaFunc(GL_GREATER, 0.0f); LLGLEnable blend(GL_BLEND); @@ -4895,8 +4696,10 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); for (S32 pass = 0; pass < 2; pass++) { - for (node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++) { + LLSelectNode* node = *iter; LLViewerObject* objectp = node->getObject(); if (objectp->isHUDAttachment() != for_hud) { @@ -4931,8 +4734,10 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); for (S32 pass = 0; pass < 2; pass++) { - for (node = mHighlightedObjects->getFirstNode(); node; node = mHighlightedObjects->getNextNode() ) + for (LLObjectSelection::iterator iter = mHighlightedObjects->begin(); + iter != mHighlightedObjects->end(); iter++) { + LLSelectNode* node = *iter; LLViewerObject* objectp = node->getObject(); if (objectp->isHUDAttachment() != for_hud) { @@ -4962,7 +4767,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) stop_glerror(); } - gSelectMgr->mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D); + mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D); glAlphaFunc(GL_GREATER, 0.01f); } @@ -5091,7 +4896,7 @@ S32 LLSelectNode::getLastSelectedTE() return mLastTESelected; } -LLViewerObject *LLSelectNode::getObject() +LLViewerObject* LLSelectNode::getObject() { if (!mObject) { @@ -5104,6 +4909,11 @@ LLViewerObject *LLSelectNode::getObject() return mObject; } +void LLSelectNode::setObject(LLViewerObject* object) +{ + mObject = object; +} + void LLSelectNode::saveColors() { if (mObject.notNull()) @@ -5123,8 +4933,8 @@ void LLSelectNode::saveTextures(const std::vector& textures) { mSavedTextures.clear(); - std::vector::const_iterator texture_it; - for (texture_it = textures.begin(); texture_it != textures.end(); ++texture_it) + for (std::vector::const_iterator texture_it = textures.begin(); + texture_it != textures.end(); ++texture_it) { mSavedTextures.push_back(*texture_it); } @@ -5144,7 +4954,7 @@ void LLSelectNode::saveTextureScaleRatios() U32 s_axis = 0; U32 t_axis = 0; - gSelectMgr->getTESTAxes(mObject, i, &s_axis, &t_axis); + LLPrimitive::getTESTAxes(i, &s_axis, &t_axis); LLVector3 v; LLVector3 scale = mObject->getScale(); @@ -5440,9 +5250,10 @@ S32 get_family_count(LLViewerObject *parent) llwarns << "Trying to get_family_count on null parent!" << llendl; } S32 count = 1; // for this object - for (U32 i = 0; i < parent->mChildList.size(); i++) + for (LLViewerObject::child_list_t::iterator iter = parent->mChildList.begin(); + iter != parent->mChildList.end(); ++iter) { - LLViewerObject* child = parent->mChildList[i]; + LLViewerObject* child = *iter; if (!child) { @@ -5473,7 +5284,7 @@ void LLSelectMgr::updateSelectionCenter() //override any object updates received //for selected objects - gSelectMgr->overrideObjectUpdates(); + overrideObjectUpdates(); LLViewerObject* object = mSelectedObjects->getFirstObject(); if (!object) @@ -5484,11 +5295,8 @@ void LLSelectMgr::updateSelectionCenter() mShowSelection = FALSE; mSelectionBBox = LLBBox(); mPauseRequest = NULL; - if (gAgent.getAvatarObject()) - { - gAgent.getAvatarObject()->mHUDTargetZoom = 1.f; - gAgent.getAvatarObject()->mHUDCurZoom = 1.f; - } + resetAgentHUDZoom(); + } else { @@ -5517,10 +5325,13 @@ void LLSelectMgr::updateSelectionCenter() LLVector3d select_center; // keep a list of jointed objects for showing the joint HUDEffects - LLDynamicArray < LLViewerObject *> jointed_objects; + std::vector < LLViewerObject *> jointed_objects; - for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) + for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); + iter != mSelectedObjects->end(); iter++) { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); LLViewerObject *myAvatar = gAgent.getAvatarObject(); LLViewerObject *root = object->getRootEdit(); if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment @@ -5534,9 +5345,9 @@ void LLSelectMgr::updateSelectionCenter() if (object->isJointChild()) { - jointed_objects.put(object); + jointed_objects.push_back(object); } - } // end for + } LLVector3 bbox_center_agent = bbox.getCenterAgent(); mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent); @@ -5666,6 +5477,7 @@ void LLSelectMgr::redo() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canDoDelete() { + // Note: Can only delete root objects (see getFirstDeleteableObject() for more info) return mSelectedObjects->getFirstDeleteableObject() != NULL; } @@ -5730,14 +5542,18 @@ ESelectType LLSelectMgr::getSelectTypeForObject(LLViewerObject* object) void LLSelectMgr::validateSelection() { - LLViewerObject* objectp; - for (objectp = mSelectedObjects->getFirstObject(); objectp; objectp = mSelectedObjects->getNextObject()) + struct f : public LLSelectedObjectFunctor { - if (!canSelectObject(objectp)) + virtual bool apply(LLViewerObject* object) { - deselectObjectOnly(objectp); + if (!gSelectMgr->canSelectObject(object)) + { + gSelectMgr->deselectObjectOnly(object); + } + return true; } - } + } func; + getSelection()->applyToObjects(&func); } BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) @@ -5752,445 +5568,140 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) { // only select my own objects return FALSE; - } - - // Can't select dead objects - if (object->isDead()) return FALSE; - - // Can't select orphans - if (object->isOrphaned()) return FALSE; - - // Can't select avatars - if (object->isAvatar()) return FALSE; - - // Can't select land - if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE; - - ESelectType selection_type = getSelectTypeForObject(object); - if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE; - - return TRUE; -} - -BOOL LLSelectMgr::setForceSelection(BOOL force) -{ - std::swap(mForceSelection,force); - return force; -} - -LLObjectSelection::LLObjectSelection() : - std::list(), - LLRefCount(), - mCurrentNode(end()), - mCurrentTE(-1), - mSelectType(SELECT_TYPE_WORLD) -{ -} - -LLObjectSelection::~LLObjectSelection() -{ - std::for_each(begin(), end(), DeletePointer()); -} - -void LLObjectSelection::updateEffects() -{ -} - -S32 LLObjectSelection::getNumNodes() -{ - return size(); -} - -void LLObjectSelection::addNode(LLSelectNode *nodep) -{ - push_front(nodep); - mSelectNodeMap[nodep->getObject()] = nodep; -} - -void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep) -{ - push_back(nodep); - mSelectNodeMap[nodep->getObject()] = nodep; -} - -void LLObjectSelection::removeNode(LLSelectNode *nodep) -{ - std::list::iterator iter = begin(); - while(iter != end()) - { - if ((*iter) == nodep) - { - mSelectNodeMap.erase(nodep->getObject()); - iter = erase(iter); - } - else - { - ++iter; - } - } -} - -void LLObjectSelection::deleteAllNodes() -{ - std::for_each(begin(), end(), DeletePointer()); - clear(); - mSelectNodeMap.clear(); -} - -LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp) -{ - std::map, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp); - if (found_it != mSelectNodeMap.end()) - { - return found_it->second; - } - return NULL; -} - -//----------------------------------------------------------------------------- -// getFirstNode() -//----------------------------------------------------------------------------- -LLSelectNode *LLObjectSelection::getFirstNode() -{ - mCurrentNode = begin();//getFirstData(); - - while (mCurrentNode != end() && !(*mCurrentNode)->getObject()) - { - // The object on this was killed at some point, delete it. - erase(mCurrentNode++); - } - - if (mCurrentNode != end()) - { - return *mCurrentNode; - } - - return NULL; -} - -//----------------------------------------------------------------------------- -// getCurrentNode() -//----------------------------------------------------------------------------- -LLSelectNode *LLObjectSelection::getCurrentNode() -{ - while (mCurrentNode != end() && !(*mCurrentNode)->getObject()) - { - // The object on this was killed at some point, delete it. - erase(mCurrentNode++); - } - - if (mCurrentNode != end()) - { - return *mCurrentNode; - } - return NULL; -} - -//----------------------------------------------------------------------------- -// getNextNode() -//----------------------------------------------------------------------------- -LLSelectNode *LLObjectSelection::getNextNode() -{ - ++mCurrentNode; - - while (mCurrentNode != end() && !(*mCurrentNode)->getObject()) - { - // The object on this was killed at some point, delete it. - erase(mCurrentNode++); - } - - if (mCurrentNode != end()) - { - return *mCurrentNode; - } - return NULL; -} - - - -//----------------------------------------------------------------------------- -// getFirstObject() -//----------------------------------------------------------------------------- -LLViewerObject* LLObjectSelection::getFirstObject() -{ - mCurrentNode = begin(); - - while (mCurrentNode != end() && !(*mCurrentNode)->getObject()) - { - // The object on this was killed at some point, delete it. - erase(mCurrentNode++); - } - - if (mCurrentNode != end()) - { - return (*mCurrentNode)->getObject(); - } - - return NULL; -} - - -//----------------------------------------------------------------------------- -// getNextObject() -//----------------------------------------------------------------------------- -LLViewerObject* LLObjectSelection::getNextObject() -{ - ++mCurrentNode;// = getNextData(); - - while (mCurrentNode != end() && !(*mCurrentNode)->getObject()) - { - // The object on this was killed at some point, delete it. - erase(mCurrentNode++); - } - - if (mCurrentNode != end()) - { - return (*mCurrentNode)->getObject(); - } - - return NULL; -} - - - -//----------------------------------------------------------------------------- -// getPrimaryTE() -//----------------------------------------------------------------------------- -void LLObjectSelection::getPrimaryTE(LLViewerObject* *object, S32 *te) -{ - // initialize object and te - *te = 0; - *object = NULL; - - BOOL searching_roots = TRUE; - - // try for root node first, then first child node - LLSelectNode *primary_node = getFirstNode(); //getFirstRootNode(); - if (!primary_node) - { - primary_node = getFirstNode(); - searching_roots = FALSE; - } - - while (primary_node) - { - S32 last_selected_te = primary_node->getLastSelectedTE(); - if (last_selected_te >= 0) - { - *object = primary_node->getObject(); - *te = last_selected_te; - return; - } - for(S32 cur_te = 0; cur_te < primary_node->getObject()->getNumTEs(); cur_te++) - { - // if face selected - if (primary_node->isTESelected(cur_te)) - { - // return this object and face - *object = primary_node->getObject(); - *te = cur_te; - return; - } - } - if (searching_roots) - { - primary_node = getNextRootNode(); - if (!primary_node) - { - primary_node = getFirstNode(); - searching_roots = FALSE; - } - } - else - { - primary_node = getNextNode(); - } - } -} - -//----------------------------------------------------------------------------- -// getFirstTE() -//----------------------------------------------------------------------------- -void LLObjectSelection::getFirstTE(LLViewerObject* *object, S32 *te) -{ - // start with first face - mCurrentTE = 0; - - LLSelectNode *cur_node = getFirstNode(); - - // repeat over all selection nodes - while (cur_node) - { - // skip objects with no faces - if (cur_node->getObject()->getNumTEs() == 0) - { - mCurrentTE = 0; - cur_node = getNextNode(); - continue; - } - - // repeat over all faces for this object - while (mCurrentTE < cur_node->getObject()->getNumTEs()) - { - // if face selected - if (cur_node->isTESelected(mCurrentTE)) - { - // return this object and face - *object = cur_node->getObject(); - *te = mCurrentTE; - return; - } + } - mCurrentTE++; - } + // Can't select dead objects + if (object->isDead()) return FALSE; + + // Can't select orphans + if (object->isOrphaned()) return FALSE; + + // Can't select avatars + if (object->isAvatar()) return FALSE; - // Couldn't find a selected face. - // This can happen if an object's volume parameters are changed in such a way - // that texture entries are eliminated. - // - // TODO: Consider selecting all faces in this case? Subscribe the selection - // list to the volume changing code? + // Can't select land + if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE; - mCurrentTE = 0; - cur_node = getNextNode(); - } + ESelectType selection_type = getSelectTypeForObject(object); + if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE; - // The list doesn't contain any nodes. Return NULL. - *object = NULL; - *te = -1; - return; + return TRUE; } +BOOL LLSelectMgr::setForceSelection(BOOL force) +{ + std::swap(mForceSelection,force); + return force; +} -//----------------------------------------------------------------------------- -// getNextFace() -//----------------------------------------------------------------------------- -void LLObjectSelection::getNextTE(LLViewerObject* *object, S32 *te) +void LLSelectMgr::resetAgentHUDZoom() { - // try next face - mCurrentTE++; - - LLSelectNode *cur_node = getCurrentNode(); - // repeat over remaining selection nodes - while ( cur_node ) + if (gAgent.getAvatarObject()) { - // skip objects with no faces - if (cur_node->getObject()->getNumTEs() == 0) - { - mCurrentTE = 0; - cur_node = getNextNode(); - continue; - } - - // repeat over all faces for this object - // CRO: getNumTEs() no longer equals mFaces.count(), so use mFaces.count() instead - while ( mCurrentTE < cur_node->getObject()->getNumTEs() ) - { - // if face selected - if (cur_node->isTESelected(mCurrentTE)) - { - // return this object and face - *object = cur_node->getObject(); - *te = mCurrentTE; - return; - } - - mCurrentTE++; - } - - mCurrentTE = 0; - cur_node = getNextNode(); + gAgent.getAvatarObject()->mHUDTargetZoom = 1.f; + gAgent.getAvatarObject()->mHUDCurZoom = 1.f; } - - // The list doesn't contain any nodes. Return NULL. - *object = NULL; - *te = -1; - return; } -void LLObjectSelection::getCurrentTE(LLViewerObject* *object, S32 *te) +void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const { - if (mCurrentNode != end()) - { - *object = (*mCurrentNode)->getObject(); - *te = mCurrentTE; - } - else + if (gAgent.getAvatarObject()) { - *object = NULL; - *te = -1; + target_zoom = gAgent.getAvatarObject()->mHUDTargetZoom; + current_zoom = gAgent.getAvatarObject()->mHUDCurZoom; } } -//----------------------------------------------------------------------------- -// getFirstRootNode() -//----------------------------------------------------------------------------- -LLSelectNode *LLObjectSelection::getFirstRootNode() -{ - LLSelectNode *cur_node = getFirstNode(); - // scan through child objects and roots set to ignore - while (cur_node && - (!(cur_node->getObject()->isRootEdit() || cur_node->getObject()->isJointChild()) || - cur_node->mIndividualSelection)) +void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom) +{ + if (gAgent.getAvatarObject()) { - cur_node = getNextNode(); + gAgent.getAvatarObject()->mHUDTargetZoom = target_zoom; + gAgent.getAvatarObject()->mHUDCurZoom = current_zoom; } - - return cur_node; } +LLObjectSelection::LLObjectSelection() : + LLRefCount(), + mSelectType(SELECT_TYPE_WORLD) +{ +} -//----------------------------------------------------------------------------- -// getNextRootNode() -//----------------------------------------------------------------------------- -LLSelectNode *LLObjectSelection::getNextRootNode() +LLObjectSelection::~LLObjectSelection() { - LLSelectNode *cur_node = getNextNode(); + deleteAllNodes(); +} - while (cur_node && - (!(cur_node->getObject()->isRootEdit() || cur_node->getObject()->isJointChild()) || - cur_node->mIndividualSelection)) +void LLObjectSelection::cleanupNodes() +{ + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ) { - cur_node = getNextNode(); + list_t::iterator curiter = iter++; + LLSelectNode* node = *curiter; + if (node->getObject() == NULL || node->getObject()->isDead()) + { + mList.erase(curiter); + delete node; + } } - - return cur_node; } +void LLObjectSelection::updateEffects() +{ +} -//----------------------------------------------------------------------------- -// getFirstRootObject() -//----------------------------------------------------------------------------- -LLViewerObject *LLObjectSelection::getFirstRootObject() +S32 LLObjectSelection::getNumNodes() { - LLSelectNode *node = getFirstRootNode(); + return mList.size(); +} - if (node) - { - return node->getObject(); - } - else - { - return NULL; - } +void LLObjectSelection::addNode(LLSelectNode *nodep) +{ + llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + mList.push_front(nodep); + mSelectNodeMap[nodep->getObject()] = nodep; } +void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep) +{ + llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + mList.push_back(nodep); + mSelectNodeMap[nodep->getObject()] = nodep; +} -//----------------------------------------------------------------------------- -// getNextRootObject() -//----------------------------------------------------------------------------- -LLViewerObject *LLObjectSelection::getNextRootObject() +void LLObjectSelection::moveNodeToFront(LLSelectNode *nodep) { - LLSelectNode *node = getNextRootNode(); + mList.remove(nodep); + mList.push_front(nodep); +} - if (node) +void LLObjectSelection::removeNode(LLSelectNode *nodep) +{ + mSelectNodeMap.erase(nodep->getObject()); + if (nodep->getObject() == mPrimaryObject) { - return node->getObject(); + mPrimaryObject = NULL; } - else + nodep->setObject(NULL); // Will get erased in cleanupNodes() + mList.remove(nodep); +} + +void LLObjectSelection::deleteAllNodes() +{ + std::for_each(mList.begin(), mList.end(), DeletePointer()); + mList.clear(); + mSelectNodeMap.clear(); + mPrimaryObject = NULL; +} + +LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp) +{ + std::map, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp); + if (found_it != mSelectNodeMap.end()) { - return NULL; + return found_it->second; } + return NULL; } //----------------------------------------------------------------------------- @@ -6198,7 +5709,7 @@ LLViewerObject *LLObjectSelection::getNextRootObject() //----------------------------------------------------------------------------- BOOL LLObjectSelection::isEmpty() { - return (size() == 0); + return (mList.size() == 0); } //----------------------------------------------------------------------------- @@ -6206,24 +5717,20 @@ BOOL LLObjectSelection::isEmpty() //----------------------------------------------------------------------------- BOOL LLObjectSelection::getOwnershipCost(S32 &cost) { - S32 count = 0; - for( LLSelectNode* nodep = getFirstNode(); nodep; nodep = getNextNode() ) - { - count++; - } - + S32 count = getObjectCount(); cost = count * OWNERSHIP_COST_PER_OBJECT; - return (count > 0); } //----------------------------------------------------------------------------- -// getObjectCount() +// getObjectCount() - returns number of non null objects //----------------------------------------------------------------------------- S32 LLObjectSelection::getObjectCount() { - return getNumNodes(); + cleanupNodes(); + S32 count = mList.size(); + return count; } @@ -6233,23 +5740,19 @@ S32 LLObjectSelection::getObjectCount() S32 LLObjectSelection::getTECount() { S32 count = 0; - - LLSelectNode* nodep; - for (nodep = getFirstNode(); nodep; nodep = getNextNode() ) + for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++) { - if (nodep->getObject()) + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + S32 num_tes = object->getNumTEs(); + for (S32 te = 0; te < num_tes; te++) { - S32 num_tes = nodep->getObject()->getNumTEs(); - for (S32 te = 0; te < num_tes; te++) + if (node->isTESelected(te)) { - if (nodep->isTESelected(te)) - { - count++; - } + ++count; } } } - return count; } @@ -6258,47 +5761,97 @@ S32 LLObjectSelection::getTECount() //----------------------------------------------------------------------------- S32 LLObjectSelection::getRootObjectCount() { - LLSelectNode *nodep; - S32 count = 0; - for(nodep = getFirstRootNode(); nodep; nodep = getNextRootNode()) + for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++) { ++count; } return count; } -bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func) +bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func, bool firstonly) { - bool result = true; - LLViewerObject* object; - for (object = getFirstObject(); object != NULL; object = getNextObject()) + bool result = firstonly ? false : true; + for (iterator iter = begin(); iter != end(); ) { - result = result && func->apply(object); + iterator nextiter = iter++; + LLViewerObject* object = (*nextiter)->getObject(); + bool r = func->apply(object); + if (firstonly && r) + return true; + else + result = result && r; } return result; } -bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func) +bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly) { - bool result = true; - LLViewerObject* object; - for (object = getFirstRootObject(); - object != NULL; - object = getNextRootObject()) + bool result = firstonly ? false : true; + for (root_iterator iter = root_begin(); iter != root_end(); ) { - result = result && func->apply(object); + root_iterator nextiter = iter++; + LLViewerObject* object = (*nextiter)->getObject(); + bool r = func->apply(object); + if (firstonly && r) + return true; + else + result = result && r; } return result; } -bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func) +bool LLObjectSelection::applyToTEs(LLSelectedTEFunctor* func, bool firstonly) { - bool result = true; - LLSelectNode* node; - for (node = getFirstNode(); node != NULL; node = getNextNode()) + bool result = firstonly ? false : true; + for (iterator iter = begin(); iter != end(); ) + { + iterator nextiter = iter++; + LLSelectNode* node = *nextiter; + LLViewerObject* object = (*nextiter)->getObject(); + for (S32 te = 0; te < object->getNumTEs(); ++te) + { + if (node->isTESelected(te)) + { + bool r = func->apply(object, te); + if (firstonly && r) + return true; + else + result = result && r; + } + } + } + return result; +} + +bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func, bool firstonly) +{ + bool result = firstonly ? false : true; + for (iterator iter = begin(); iter != end(); ) { - result = result && func->apply(node); + iterator nextiter = iter++; + LLSelectNode* node = *nextiter; + bool r = func->apply(node); + if (firstonly && r) + return true; + else + result = result && r; + } + return result; +} + +bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool firstonly) +{ + bool result = firstonly ? false : true; + for (root_iterator iter = root_begin(); iter != root_end(); ) + { + root_iterator nextiter = iter++; + LLSelectNode* node = *nextiter; + bool r = func->apply(node); + if (firstonly && r) + return true; + else + result = result && r; } return result; } @@ -6317,12 +5870,13 @@ BOOL LLObjectSelection::contains(LLViewerObject* object) //----------------------------------------------------------------------------- BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te) { - LLSelectNode *nodep; if (te == SELECT_ALL_TES) { // ...all faces - for (nodep = getFirstNode(); nodep; nodep = getNextNode() ) + for (LLObjectSelection::iterator iter = begin(); + iter != end(); iter++) { + LLSelectNode* nodep = *iter; if (nodep->getObject() == object) { BOOL all_selected = TRUE; @@ -6338,8 +5892,9 @@ BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te) else { // ...one face - for (nodep = getFirstNode(); nodep; nodep = getNextNode() ) + for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++) { + LLSelectNode* nodep = *iter; if (nodep->getObject() == object && nodep->isTESelected(te)) { return TRUE; @@ -6356,203 +5911,193 @@ BOOL LLObjectSelection::isAttachment() } //----------------------------------------------------------------------------- -// getFirstMoveableNode() +// getSelectedParentObject() //----------------------------------------------------------------------------- -LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root) +LLViewerObject* getSelectedParentObject(LLViewerObject *object) { - LLSelectNode* selectNode = NULL; - - if (get_root) + LLViewerObject *parent; + while (object && (parent = (LLViewerObject*)object->getParent())) { - for(selectNode = getFirstRootNode(); selectNode; selectNode = getNextRootNode()) + if (parent->isSelected()) { - if( selectNode->getObject()->permMove() ) - { - return selectNode; - break; - } + object = parent; } - } - for(selectNode = getFirstNode(); selectNode; selectNode = getNextNode()) - { - if( selectNode->getObject()->permMove() ) + else { - return selectNode; break; } } - - return NULL; + return object; } //----------------------------------------------------------------------------- -// getFirstCopyableObject() +// getFirstNode //----------------------------------------------------------------------------- -LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_root) +LLSelectNode* LLObjectSelection::getFirstNode(LLSelectedNodeFunctor* func) { - LLViewerObject* object = NULL; - for(LLViewerObject* cur = getFirstObject(); cur; cur = getNextObject()) + for (iterator iter = begin(); iter != end(); ++iter) { - if( cur->permCopy() && !cur->isAttachment()) + LLSelectNode* node = *iter; + if (func == NULL || func->apply(node)) { - object = cur; - break; + return node; } - } + } + return NULL; +} - if (get_root && object) +LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, BOOL non_root_ok) +{ + for (root_iterator iter = root_begin(); iter != root_end(); ++iter) { - LLViewerObject *parent; - while ((parent = (LLViewerObject*)object->getParent())) + LLSelectNode* node = *iter; + if (func == NULL || func->apply(node)) { - if (parent->isSelected()) - { - object = parent; - } - else - { - break; - } + return node; } } + if (non_root_ok) + { + // Get non root + return getFirstNode(func); + } + return NULL; +} - return object; + +//----------------------------------------------------------------------------- +// getFirstSelectedObject +//----------------------------------------------------------------------------- +LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent) +{ + LLSelectNode* res = getFirstNode(func); + if (res && get_parent) + { + return getSelectedParentObject(res->getObject()); + } + else if (res) + { + return res->getObject(); + } + return NULL; } +//----------------------------------------------------------------------------- +// getFirstObject() +//----------------------------------------------------------------------------- +LLViewerObject* LLObjectSelection::getFirstObject() +{ + LLSelectNode* res = getFirstNode(NULL); + return res ? res->getObject() : NULL; +} //----------------------------------------------------------------------------- -// getFirstDeleteableObject() +// getFirstRootObject() //----------------------------------------------------------------------------- -LLViewerObject* LLObjectSelection::getFirstDeleteableObject(BOOL get_root) +LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok) { - //RN: don't currently support deletion of child objects, as that requires separating them first - // then derezzing to trash - get_root = TRUE; + LLSelectNode* res = getFirstRootNode(NULL, non_root_ok); + return res ? res->getObject() : NULL; +} - LLViewerObject* object = NULL; - if (get_root) +//----------------------------------------------------------------------------- +// getFirstMoveableNode() +//----------------------------------------------------------------------------- +LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first) +{ + struct f : public LLSelectedNodeFunctor { - for(LLViewerObject* current = getFirstRootObject(); - current != NULL; - current = getNextRootObject()) + bool apply(LLSelectNode* node) { - // you can delete an object if permissions allow it, you are - // the owner, you are an officer in the group that owns the - // object, or you are not the owner but it is on land you own - // or land owned by your group. (whew!) - if( (current->permModify()) - || (current->permYouOwner()) - || (!current->permAnyOwner()) // public - || (current->isOverAgentOwnedLand()) - || (current->isOverGroupOwnedLand()) - ) - { + LLViewerObject* obj = node->getObject(); + return obj->permMove(); + } + } func; + LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func); + return res; +} - if( !current->isAttachment() ) - { - object = current; - break; - } - } - } - } - else +//----------------------------------------------------------------------------- +// getFirstCopyableObject() +//----------------------------------------------------------------------------- +LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent) +{ + struct f : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* node) + { + LLViewerObject* obj = node->getObject(); + return obj->permCopy() && !obj->isAttachment(); + } + } func; + return getFirstSelectedObject(&func, get_parent); +} + +//----------------------------------------------------------------------------- +// getFirstDeleteableObject() +//----------------------------------------------------------------------------- +LLViewerObject* LLObjectSelection::getFirstDeleteableObject() +{ + //RN: don't currently support deletion of child objects, as that requires separating them first + // then derezzing to trash + + struct f : public LLSelectedNodeFunctor { - // We've avoided this path for a while. It may not work. - llwarns << "!get_root code path may have bitrotted." << llendl; - for(LLViewerObject* current = getFirstObject(); - current != NULL; - current = getNextObject()) + bool apply(LLSelectNode* node) { + LLViewerObject* obj = node->getObject(); // you can delete an object if permissions allow it, you are // the owner, you are an officer in the group that owns the // object, or you are not the owner but it is on land you own // or land owned by your group. (whew!) - if( (current->permModify()) - || (current->permYouOwner()) - || (!current->permAnyOwner()) // public - || (current->isOverAgentOwnedLand()) - || (current->isOverGroupOwnedLand()) - ) + if( (obj->permModify()) + || (obj->permYouOwner()) + || (!obj->permAnyOwner()) // public + || (obj->isOverAgentOwnedLand()) + || (obj->isOverGroupOwnedLand()) + ) { - if( !current->isAttachment() ) + if( !obj->isAttachment() ) { - object = current; - break; + return TRUE; } } - } - } - - return object; + return true; + } + } func; + LLSelectNode* node = getFirstNode(&func); + return node ? node->getObject() : NULL; } - //----------------------------------------------------------------------------- // getFirstEditableObject() //----------------------------------------------------------------------------- -LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_root) +LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent) { - LLViewerObject* object = NULL; - for(LLViewerObject* cur = getFirstObject(); cur; cur = getNextObject()) - { - if( cur->permModify() ) - { - object = cur; - break; - } - } - - if (get_root && object) + struct f : public LLSelectedNodeFunctor { - LLViewerObject *parent; - while ((parent = (LLViewerObject*)object->getParent())) + bool apply(LLSelectNode* node) { - if (parent->isSelected()) - { - object = parent; - } - else - { - break; - } + LLViewerObject* obj = node->getObject(); + return obj->permModify(); } - } - - return object; + } func; + return getFirstSelectedObject(&func, get_parent); } //----------------------------------------------------------------------------- // getFirstMoveableObject() //----------------------------------------------------------------------------- -LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_root) +LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent) { - LLViewerObject* object = NULL; - for(LLViewerObject* cur = getFirstObject(); cur; cur = getNextObject()) - { - if( cur->permMove() ) - { - object = cur; - break; - } - } - - if (get_root && object && !object->isJointChild()) + struct f : public LLSelectedNodeFunctor { - LLViewerObject *parent; - while ((parent = (LLViewerObject*)object->getParent())) + bool apply(LLSelectNode* node) { - if (parent->isSelected()) - { - object = parent; - } - else - { - break; - } + LLViewerObject* obj = node->getObject(); + return obj->permMove(); } - } - - return object; + } func; + return getFirstSelectedObject(&func, get_parent); } -- cgit v1.1