aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llselectmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llselectmgr.cpp')
-rw-r--r--linden/indra/newview/llselectmgr.cpp3211
1 files changed, 1378 insertions, 1833 deletions
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 @@
2 * @file llselectmgr.cpp 2 * @file llselectmgr.cpp
3 * @brief A manager for selected objects and faces. 3 * @brief A manager for selected objects and faces.
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 7 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 8 *
7 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
@@ -24,6 +26,7 @@
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE. 28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
27 */ 30 */
28 31
29#include "llviewerprecompiledheaders.h" 32#include "llviewerprecompiledheaders.h"
@@ -210,6 +213,11 @@ LLSelectMgr::LLSelectMgr()
210//----------------------------------------------------------------------------- 213//-----------------------------------------------------------------------------
211LLSelectMgr::~LLSelectMgr() 214LLSelectMgr::~LLSelectMgr()
212{ 215{
216 clearSelections();
217}
218
219void LLSelectMgr::clearSelections()
220{
213 mHoverObjects->deleteAllNodes(); 221 mHoverObjects->deleteAllNodes();
214 mSelectedObjects->deleteAllNodes(); 222 mSelectedObjects->deleteAllNodes();
215 mHighlightedObjects->deleteAllNodes(); 223 mHighlightedObjects->deleteAllNodes();
@@ -217,21 +225,27 @@ LLSelectMgr::~LLSelectMgr()
217 mGridObjects.deleteAllNodes(); 225 mGridObjects.deleteAllNodes();
218} 226}
219 227
220void LLSelectMgr::updateEffects() 228void LLSelectMgr::update()
221{ 229{
230 mSelectedObjects->cleanupNodes();
231}
222 232
233void LLSelectMgr::updateEffects()
234{
223 //keep reference grid objects active 235 //keep reference grid objects active
224 for (LLSelectNode* grid_nodep = mGridObjects.getFirstNode(); 236 struct f : public LLSelectedObjectFunctor
225 grid_nodep;
226 grid_nodep = mGridObjects.getNextNode())
227 { 237 {
228 LLViewerObject* grid_object = grid_nodep->getObject(); 238 virtual bool apply(LLViewerObject* object)
229 LLDrawable* drawable = grid_object->mDrawable;
230 if (drawable)
231 { 239 {
232 gPipeline.markMoved(drawable); 240 LLDrawable* drawable = object->mDrawable;
241 if (drawable)
242 {
243 gPipeline.markMoved(drawable);
244 }
245 return true;
233 } 246 }
234 } 247 } func;
248 mGridObjects.applyToObjects(&func);
235 249
236 if (mEffectsTimer.getElapsedTimeF32() > 1.f) 250 if (mEffectsTimer.getElapsedTimeF32() > 1.f)
237 { 251 {
@@ -243,29 +257,30 @@ void LLSelectMgr::updateEffects()
243void LLSelectMgr::overrideObjectUpdates() 257void LLSelectMgr::overrideObjectUpdates()
244{ 258{
245 //override any position updates from simulator on objects being edited 259 //override any position updates from simulator on objects being edited
246 LLSelectNode* selectNode; 260 struct f : public LLSelectedNodeFunctor
247 for (selectNode = gSelectMgr->getSelection()->getFirstNode();
248 selectNode != NULL;
249 selectNode = gSelectMgr->getSelection()->getNextNode())
250 { 261 {
251 LLViewerObject* object = selectNode->getObject(); 262 virtual bool apply(LLSelectNode* selectNode)
252
253 if (object->permMove())
254 { 263 {
255 if (!selectNode->mLastPositionLocal.isExactlyZero()) 264 LLViewerObject* object = selectNode->getObject();
256 { 265 if (object->permMove())
257 object->setPosition(selectNode->mLastPositionLocal);
258 }
259 if (selectNode->mLastRotation != LLQuaternion())
260 { 266 {
261 object->setRotation(selectNode->mLastRotation); 267 if (!selectNode->mLastPositionLocal.isExactlyZero())
262 } 268 {
263 if (!selectNode->mLastScale.isExactlyZero()) 269 object->setPosition(selectNode->mLastPositionLocal);
264 { 270 }
265 object->setScale(selectNode->mLastScale); 271 if (selectNode->mLastRotation != LLQuaternion())
272 {
273 object->setRotation(selectNode->mLastRotation);
274 }
275 if (!selectNode->mLastScale.isExactlyZero())
276 {
277 object->setScale(selectNode->mLastScale);
278 }
266 } 279 }
280 return true;
267 } 281 }
268 } 282 } func;
283 getSelection()->applyToNodes(&func);
269} 284}
270 285
271//----------------------------------------------------------------------------- 286//-----------------------------------------------------------------------------
@@ -414,24 +429,26 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj,
414//----------------------------------------------------------------------------- 429//-----------------------------------------------------------------------------
415// Select the object, parents and children. 430// Select the object, parents and children.
416//----------------------------------------------------------------------------- 431//-----------------------------------------------------------------------------
417LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const LLDynamicArray<LLViewerObject*>& object_list, 432LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list,
418 BOOL send_to_sim) 433 BOOL send_to_sim)
419{ 434{
420 // Collect all of the objects, children included 435 // Collect all of the objects, children included
421 LLDynamicArray<LLViewerObject*> objects; 436 LLDynamicArray<LLViewerObject*> objects;
422 LLViewerObject *object;
423 S32 i;
424 437
425 //clear primary object (no primary object) 438 //clear primary object (no primary object)
426 mSelectedObjects->mPrimaryObject = NULL; 439 mSelectedObjects->mPrimaryObject = NULL;
427 440
428 if (object_list.count() < 1) return NULL; 441 if (object_list.size() < 1)
429 442 {
443 return NULL;
444 }
445
430 // NOTE -- we add the objects in REVERSE ORDER 446 // NOTE -- we add the objects in REVERSE ORDER
431 // to preserve the order in the mSelectedObjects list 447 // to preserve the order in the mSelectedObjects list
432 for (i = object_list.count() - 1; i >= 0; i--) 448 for (std::vector<LLViewerObject*>::const_reverse_iterator riter = object_list.rbegin();
449 riter != object_list.rend(); ++riter)
433 { 450 {
434 object = object_list.get(i); 451 LLViewerObject *object = *riter;
435 452
436 llassert( object ); 453 llassert( object );
437 454
@@ -503,44 +520,30 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
503 // Iterate through selected objects list and kill the object 520 // Iterate through selected objects list and kill the object
504 if( !object_found ) 521 if( !object_found )
505 { 522 {
506 LLViewerObject* prevobjp = NULL; 523 for (LLObjectSelection::iterator iter = getSelection()->begin();
507 for( LLViewerObject* tobjp = mSelectedObjects->getFirstObject(); tobjp != NULL; tobjp = mSelectedObjects->getNextObject() ) 524 iter != getSelection()->end(); )
508 { 525 {
509 if (tobjp == prevobjp) 526 LLObjectSelection::iterator curiter = iter++;
527 LLViewerObject* object = (*curiter)->getObject();
528 if (object->mID == id)
510 { 529 {
511 // Somehow we got stuck in an infinite loop... (DaveP) 530 if (tool)
512 // this logic is kind of twisted, not sure how this is happening, so...
513 llwarns << "Detected infinite loop #1 in LLSelectMgr::removeObjectFromSelections:|" << llendl;
514 //MikeS. adding warning and comment...
515 //These infinite loops happen because the LLSelectMgr iteration routines are non-reentrant.
516 //deselectObjectAndFamily uses getFirstObject and getNextObject to mess with the array,
517 //resetting the arrays internal iterator state. This needs fixing BAD.
518 continue;
519 }
520 // It's possible the item being removed has an avatar sitting on it
521 // So remove the avatar that is sitting on the object.
522 if (tobjp->mID == id || tobjp->isAvatar())
523 {
524 if (!gNoRender)
525 { 531 {
526 tool->stopEditing(); 532 tool->stopEditing();
527 } 533 }
528 534
529 // lose the selection, don't tell simulator, it knows 535 // lose the selection, don't tell simulator, it knows
530 deselectObjectAndFamily(tobjp, FALSE); 536 deselectObjectAndFamily(object, FALSE);
531 537 object_found = TRUE;
532 if (tobjp->mID == id) 538 break; // must break here, may have removed multiple objects from list
533 { 539 }
534 if(object_found == TRUE){ 540 else if (object->isAvatar())
535 //MikeS. adding warning... This happens when removing a linked attachment while sitting on an object.. 541 {
536 //I think the selection manager needs to be rewritten. BAD. 542 // It's possible the item being removed has an avatar sitting on it
537 llwarns << "Detected infinite loop #2 in LLSelectMgr::removeObjectFromSelections:|" << llendl; 543 // So remove the avatar that is sitting on the object.
538 break; 544 deselectObjectAndFamily(object, FALSE);
539 } 545 break; // must break here, may have removed multiple objects from list
540 object_found = TRUE;
541 }
542 } 546 }
543 prevobjp = tobjp;
544 } 547 }
545 } 548 }
546 549
@@ -593,7 +596,7 @@ void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_s
593 S32 select_count = 0; 596 S32 select_count = 0;
594 597
595 LLMessageSystem* msg = gMessageSystem; 598 LLMessageSystem* msg = gMessageSystem;
596 for (S32 i = 0; i < objects.count(); i++) 599 for (U32 i = 0; i < objects.size(); i++)
597 { 600 {
598 if (start_new_message) 601 if (start_new_message)
599 { 602 {
@@ -656,15 +659,12 @@ void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim)
656// addAsFamily 659// addAsFamily
657//----------------------------------------------------------------------------- 660//-----------------------------------------------------------------------------
658 661
659void LLSelectMgr::addAsFamily(LLDynamicArray<LLViewerObject*>& objects, BOOL add_to_end) 662void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end)
660{ 663{
661 S32 count = objects.count(); 664 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
662 LLViewerObject *objectp = NULL; 665 iter != objects.end(); ++iter)
663
664 LLSelectNode *nodep = NULL;
665 for (S32 i = 0; i < count; i++)
666 { 666 {
667 objectp = objects.get(i); 667 LLViewerObject* objectp = *iter;
668 668
669 // Can't select yourself 669 // Can't select yourself
670 if (objectp->mID == gAgentID 670 if (objectp->mID == gAgentID
@@ -675,7 +675,7 @@ void LLSelectMgr::addAsFamily(LLDynamicArray<LLViewerObject*>& objects, BOOL add
675 675
676 if (!objectp->isSelected()) 676 if (!objectp->isSelected())
677 { 677 {
678 nodep = new LLSelectNode(objectp, TRUE); 678 LLSelectNode *nodep = new LLSelectNode(objectp, TRUE);
679 if (add_to_end) 679 if (add_to_end)
680 { 680 {
681 mSelectedObjects->addNodeAtEnd(nodep); 681 mSelectedObjects->addNodeAtEnd(nodep);
@@ -722,14 +722,14 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
722 { 722 {
723 nodep = new LLSelectNode(objectp, TRUE); 723 nodep = new LLSelectNode(objectp, TRUE);
724 mSelectedObjects->addNode(nodep); 724 mSelectedObjects->addNode(nodep);
725 llassert_always(nodep->getObject());
725 } 726 }
726 else 727 else
727 { 728 {
728 // make this a full-fledged selection 729 // make this a full-fledged selection
729 nodep->setTransient(FALSE); 730 nodep->setTransient(FALSE);
730 // Move it to the front of the list 731 // Move it to the front of the list
731 mSelectedObjects->removeNode(nodep); 732 mSelectedObjects->moveNodeToFront(nodep);
732 mSelectedObjects->addNode(nodep);
733 } 733 }
734 734
735 // Make sure the object is tagged as selected 735 // Make sure the object is tagged as selected
@@ -790,14 +790,11 @@ LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp)
790 objectp = objectp->getRootEdit(); 790 objectp = objectp->getRootEdit();
791 objectp->addThisAndNonJointChildren(objects); 791 objectp->addThisAndNonJointChildren(objects);
792 792
793 793 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
794 S32 count = objects.count(); 794 iter != objects.end(); ++iter)
795 LLViewerObject* cur_objectp = NULL;
796 LLSelectNode* nodep = NULL;
797 for(S32 i = 0; i < count; i++)
798 { 795 {
799 cur_objectp = objects[i]; 796 LLViewerObject* cur_objectp = *iter;
800 nodep = new LLSelectNode(cur_objectp, FALSE); 797 LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
801 mHoverObjects->addNodeAtEnd(nodep); 798 mHoverObjects->addNodeAtEnd(nodep);
802 } 799 }
803 800
@@ -850,28 +847,30 @@ void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp)
850} 847}
851 848
852// Note that this ignores the "select owned only" flag 849// Note that this ignores the "select owned only" flag
853// It's also more efficient than calling the single-object version over and 850// It's also more efficient than calling the single-object version over and over.
854// over. 851void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& objects)
855void LLSelectMgr::highlightObjectAndFamily(const LLDynamicArray<LLViewerObject*>& list)
856{ 852{
857 S32 i; 853 for (std::vector<LLViewerObject*>::const_iterator iter1 = objects.begin();
858 S32 count = list.count(); 854 iter1 != objects.end(); ++iter1)
859
860 for (i = 0; i < count; i++)
861 { 855 {
862 LLViewerObject* object = list.get(i); 856 LLViewerObject* object = *iter1;
863 857
864 if (!object) continue; 858 if (!object)
865 if (object->getPCode() != LL_PCODE_VOLUME) continue; 859 {
860 continue;
861 }
862 if (object->getPCode() != LL_PCODE_VOLUME)
863 {
864 continue;
865 }
866 866
867 LLViewerObject* root = (LLViewerObject*)object->getRoot(); 867 LLViewerObject* root = (LLViewerObject*)object->getRoot();
868 mRectSelectedObjects.insert(root); 868 mRectSelectedObjects.insert(root);
869 869
870 S32 j; 870 for (LLViewerObject::child_list_t::const_iterator iter2 = root->mChildList.begin();
871 S32 child_count = root->mChildList.size(); 871 iter2 != root->mChildList.end(); ++iter2)
872 for (j = 0; j < child_count; j++)
873 { 872 {
874 LLViewerObject* child = root->mChildList[j]; 873 LLViewerObject* child = *iter2;
875 mRectSelectedObjects.insert(child); 874 mRectSelectedObjects.insert(child);
876 } 875 }
877 } 876 }
@@ -898,9 +897,11 @@ void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp)
898 897
899 unhighlightObjectOnly(root_obj); 898 unhighlightObjectOnly(root_obj);
900 899
901 for(U32 i = 0; i < root_obj->mChildList.size(); i++) 900 for (LLViewerObject::child_list_t::iterator iter2 = root_obj->mChildList.begin();
901 iter2 != root_obj->mChildList.end(); ++iter2)
902 { 902 {
903 unhighlightObjectOnly(root_obj->mChildList[i]); 903 LLViewerObject* child = *iter2;
904 unhighlightObjectOnly(child);
904 } 905 }
905} 906}
906 907
@@ -921,11 +922,12 @@ LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
921 //clear primary object 922 //clear primary object
922 mSelectedObjects->mPrimaryObject = NULL; 923 mSelectedObjects->mPrimaryObject = NULL;
923 924
924 LLSelectNode *nodep; 925 for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin();
925 for (nodep = mHighlightedObjects->getFirstNode(); 926 iter != getHighlightedObjects()->end(); )
926 nodep;
927 nodep = mHighlightedObjects->getNextNode())
928 { 927 {
928 LLObjectSelection::iterator curiter = iter++;
929
930 LLSelectNode *nodep = *curiter;
929 LLViewerObject* objectp = nodep->getObject(); 931 LLViewerObject* objectp = nodep->getObject();
930 932
931 if (!canSelectObject(objectp)) 933 if (!canSelectObject(objectp))
@@ -997,9 +999,12 @@ void LLSelectMgr::addGridObject(LLViewerObject* objectp)
997{ 999{
998 LLSelectNode* nodep = new LLSelectNode(objectp, FALSE); 1000 LLSelectNode* nodep = new LLSelectNode(objectp, FALSE);
999 mGridObjects.addNodeAtEnd(nodep); 1001 mGridObjects.addNodeAtEnd(nodep);
1000 for (U32 i = 0; i < objectp->mChildList.size(); i++) 1002
1003 for (LLViewerObject::child_list_t::iterator iter2 = objectp->mChildList.begin();
1004 iter2 != objectp->mChildList.end(); ++iter2)
1001 { 1005 {
1002 nodep = new LLSelectNode(objectp->mChildList[i], FALSE); 1006 LLViewerObject* child = *iter2;
1007 nodep = new LLSelectNode(child, FALSE);
1003 mGridObjects.addNodeAtEnd(nodep); 1008 mGridObjects.addNodeAtEnd(nodep);
1004 } 1009 }
1005} 1010}
@@ -1019,14 +1024,9 @@ void LLSelectMgr::setGridMode(EGridMode mode)
1019 1024
1020void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale) 1025void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale)
1021{ 1026{
1022 LLSelectNode* grid_node = mGridObjects.getFirstNode(); 1027 mGridObjects.cleanupNodes();
1023 LLViewerObject* grid_object = mGridObjects.getFirstObject(); 1028
1024 // *TODO: get to work with multiple grid objects 1029 LLViewerObject* first_grid_object = mGridObjects.getFirstObject();
1025 if (grid_node && grid_node->getObject()->isDead())
1026 {
1027 mGridObjects.removeNode(grid_node);
1028 grid_object = NULL;
1029 }
1030 1030
1031 if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount()) 1031 if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
1032 { 1032 {
@@ -1035,47 +1035,42 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
1035 mGridRotation = mSavedSelectionBBox.getRotation(); 1035 mGridRotation = mSavedSelectionBBox.getRotation();
1036 mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; 1036 mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
1037 } 1037 }
1038 else if (mGridMode == GRID_MODE_REF_OBJECT && grid_object && grid_object->mDrawable.notNull()) 1038 else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
1039 { 1039 {
1040 mGridRotation = grid_object->getRenderRotation(); 1040 mGridRotation = first_grid_object->getRenderRotation();
1041 LLVector3 first_grid_obj_pos = grid_object->getRenderPosition(); 1041 LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
1042 1042
1043 LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX); 1043 LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX);
1044 LLVector3 max_extents(-min_extents); 1044 LLVector3 max_extents(-F32_MAX, -F32_MAX, -F32_MAX);
1045 BOOL grid_changed = FALSE; 1045 BOOL grid_changed = FALSE;
1046 LLSelectNode* grid_nodep; 1046 for (LLObjectSelection::iterator iter = mGridObjects.begin();
1047 for (grid_nodep = mGridObjects.getFirstNode(); 1047 iter != mGridObjects.end(); ++iter)
1048 grid_nodep; 1048 {
1049 grid_nodep = mGridObjects.getNextNode()) 1049 LLViewerObject* object = (*iter)->getObject();
1050 LLDrawable* drawable = object->mDrawable;
1051 if (drawable)
1050 { 1052 {
1051 grid_object = grid_nodep->getObject(); 1053 const LLVector3* ext = drawable->getSpatialExtents();
1052 LLDrawable* drawable = grid_object->mDrawable; 1054 update_min_max(min_extents, max_extents, ext[0]);
1053 if (drawable) 1055 update_min_max(min_extents, max_extents, ext[1]);
1054 { 1056 grid_changed = TRUE;
1055 const LLVector3* ext = drawable->getSpatialExtents();
1056 update_min_max(min_extents, max_extents, ext[0]);
1057 update_min_max(min_extents, max_extents, ext[1]);
1058 grid_changed = TRUE;
1059 }
1060 } 1057 }
1058 }
1061 if (grid_changed) 1059 if (grid_changed)
1062 { 1060 {
1063 mGridOrigin = lerp(min_extents, max_extents, 0.5f); 1061 mGridOrigin = lerp(min_extents, max_extents, 0.5f);
1064 LLDrawable* drawable = grid_object->mDrawable; 1062 LLDrawable* drawable = first_grid_object->mDrawable;
1065 if (drawable && drawable->isActive()) 1063 if (drawable && drawable->isActive())
1066 { 1064 {
1067 mGridOrigin = mGridOrigin * grid_object->getRenderMatrix(); 1065 mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix();
1068 } 1066 }
1069 mGridScale = (max_extents - min_extents) * 0.5f; 1067 mGridScale = (max_extents - min_extents) * 0.5f;
1070 } 1068 }
1071 } 1069 }
1072 else // GRID_MODE_WORLD or just plain default 1070 else // GRID_MODE_WORLD or just plain default
1073 { 1071 {
1074 LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(); 1072 const BOOL non_root_ok = TRUE;
1075 if (!first_object) 1073 LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok);
1076 {
1077 first_object = mSelectedObjects->getFirstObject();
1078 }
1079 1074
1080 mGridOrigin.clearVec(); 1075 mGridOrigin.clearVec();
1081 mGridRotation.loadIdentity(); 1076 mGridRotation.loadIdentity();
@@ -1115,26 +1110,20 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
1115// remove() - an array of objects 1110// remove() - an array of objects
1116//----------------------------------------------------------------------------- 1111//-----------------------------------------------------------------------------
1117 1112
1118void LLSelectMgr::remove(LLDynamicArray<LLViewerObject*>& objects) 1113void LLSelectMgr::remove(std::vector<LLViewerObject*>& objects)
1119{ 1114{
1120 S32 count = objects.count(); 1115 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
1121 LLViewerObject *objectp = NULL; 1116 iter != objects.end(); ++iter)
1122 LLSelectNode *nodep = NULL;
1123 for(S32 i = 0; i < count; i++)
1124 { 1117 {
1125 objectp = objects.get(i); 1118 LLViewerObject* objectp = *iter;
1126 for(nodep = mSelectedObjects->getFirstNode(); 1119 LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
1127 nodep != NULL; 1120 if (nodep)
1128 nodep = mSelectedObjects->getNextNode())
1129 { 1121 {
1130 if(nodep->getObject() == objectp) 1122 objectp->setSelected(FALSE);
1131 { 1123 mSelectedObjects->removeNode(nodep);
1132 objectp->setSelected(FALSE); 1124 nodep = NULL;
1133 mSelectedObjects->removeNode(nodep);
1134 break;
1135 }
1136 } 1125 }
1137 } 1126 }
1138 updateSelectionCenter(); 1127 updateSelectionCenter();
1139 dialog_refresh_all(); 1128 dialog_refresh_all();
1140} 1129}
@@ -1145,26 +1134,19 @@ void LLSelectMgr::remove(LLDynamicArray<LLViewerObject*>& objects)
1145//----------------------------------------------------------------------------- 1134//-----------------------------------------------------------------------------
1146void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) 1135void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
1147{ 1136{
1148 // check if object already in list 1137 // get object node (and verify it is in the selected list)
1149 // *FIX: can we just check isSelected()?
1150 LLSelectNode *nodep = mSelectedObjects->findNode(objectp); 1138 LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
1151
1152 if (!nodep) 1139 if (!nodep)
1153 { 1140 {
1154 return; 1141 return;
1155 } 1142 }
1156 1143
1157
1158 // if face = all, remove object from list 1144 // if face = all, remove object from list
1159 if (objectp->getNumTEs() <= 0) 1145 if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES))
1160 {
1161 // object doesn't have faces, so blow it away
1162 mSelectedObjects->removeNode(nodep);
1163 objectp->setSelected( FALSE );
1164 }
1165 else if (te == SELECT_ALL_TES)
1166 { 1146 {
1147 // Remove all faces (or the object doesn't have faces) so remove the node
1167 mSelectedObjects->removeNode(nodep); 1148 mSelectedObjects->removeNode(nodep);
1149 nodep = NULL;
1168 objectp->setSelected( FALSE ); 1150 objectp->setSelected( FALSE );
1169 } 1151 }
1170 else if (0 <= te && te < SELECT_MAX_TES) 1152 else if (0 <= te && te < SELECT_MAX_TES)
@@ -1191,9 +1173,9 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
1191 if (!found) 1173 if (!found)
1192 { 1174 {
1193 mSelectedObjects->removeNode(nodep); 1175 mSelectedObjects->removeNode(nodep);
1176 nodep = NULL;
1194 objectp->setSelected( FALSE ); 1177 objectp->setSelected( FALSE );
1195 1178 // *FIXME: Doesn't update simulator that object is no longer selected
1196 // BUG: Doesn't update simulator that object is gone.
1197 } 1179 }
1198 } 1180 }
1199 else 1181 else
@@ -1212,14 +1194,15 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
1212//----------------------------------------------------------------------------- 1194//-----------------------------------------------------------------------------
1213void LLSelectMgr::removeAll() 1195void LLSelectMgr::removeAll()
1214{ 1196{
1215 LLViewerObject *objectp; 1197 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
1216 for (objectp = mSelectedObjects->getFirstObject(); objectp; objectp = mSelectedObjects->getNextObject() ) 1198 iter != mSelectedObjects->end(); iter++ )
1217 { 1199 {
1200 LLViewerObject *objectp = (*iter)->getObject();
1218 objectp->setSelected( FALSE ); 1201 objectp->setSelected( FALSE );
1219 } 1202 }
1220 1203
1221 mSelectedObjects->deleteAllNodes(); 1204 mSelectedObjects->deleteAllNodes();
1222 1205
1223 updateSelectionCenter(); 1206 updateSelectionCenter();
1224 dialog_refresh_all(); 1207 dialog_refresh_all();
1225} 1208}
@@ -1233,19 +1216,19 @@ void LLSelectMgr::promoteSelectionToRoot()
1233 1216
1234 BOOL selection_changed = FALSE; 1217 BOOL selection_changed = FALSE;
1235 1218
1236 LLSelectNode* nodep; 1219 for (LLObjectSelection::iterator iter = getSelection()->begin();
1237 LLViewerObject *objectp; 1220 iter != getSelection()->end(); )
1238 for (nodep = mSelectedObjects->getFirstNode();
1239 nodep;
1240 nodep = mSelectedObjects->getNextNode() )
1241 { 1221 {
1222 LLObjectSelection::iterator curiter = iter++;
1223 LLSelectNode* nodep = *curiter;
1224 LLViewerObject* object = nodep->getObject();
1225
1242 if (nodep->mIndividualSelection) 1226 if (nodep->mIndividualSelection)
1243 { 1227 {
1244 selection_changed = TRUE; 1228 selection_changed = TRUE;
1245 } 1229 }
1246 1230
1247 objectp = nodep->getObject(); 1231 LLViewerObject* parentp = object;
1248 LLViewerObject* parentp = objectp;
1249 while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild())) 1232 while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild()))
1250 { 1233 {
1251 parentp = (LLViewerObject*)parentp->getParent(); 1234 parentp = (LLViewerObject*)parentp->getParent();
@@ -1273,19 +1256,21 @@ void LLSelectMgr::demoteSelectionToIndividuals()
1273{ 1256{
1274 LLDynamicArray<LLViewerObject*> objects; 1257 LLDynamicArray<LLViewerObject*> objects;
1275 1258
1276 for (LLViewerObject* root_objectp = mSelectedObjects->getFirstRootObject(); 1259 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
1277 root_objectp; 1260 iter != getSelection()->root_end(); iter++)
1278 root_objectp = mSelectedObjects->getNextRootObject())
1279 { 1261 {
1280 root_objectp->addThisAndNonJointChildren(objects); 1262 LLViewerObject* object = (*iter)->getObject();
1263 object->addThisAndNonJointChildren(objects);
1281 } 1264 }
1282 1265
1283 if (objects.getLength()) 1266 if (objects.getLength())
1284 { 1267 {
1285 deselectAll(); 1268 deselectAll();
1286 for(S32 i = 0; i < objects.count(); i++) 1269 for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
1270 iter != objects.end(); ++iter)
1287 { 1271 {
1288 selectObjectOnly(objects[i]); 1272 LLViewerObject* objectp = *iter;
1273 selectObjectOnly(objectp);
1289 } 1274 }
1290 } 1275 }
1291} 1276}
@@ -1299,14 +1284,12 @@ void LLSelectMgr::dump()
1299 1284
1300 llinfos << "TE mode " << mTEMode << llendl; 1285 llinfos << "TE mode " << mTEMode << llendl;
1301 1286
1302 S32 i = 0; 1287 S32 count = 0;
1303 1288 for (LLObjectSelection::iterator iter = getSelection()->begin();
1304 LLViewerObject *objectp; 1289 iter != getSelection()->end(); iter++ )
1305 for (objectp = mSelectedObjects->getFirstObject();
1306 objectp;
1307 objectp = mSelectedObjects->getNextObject())
1308 { 1290 {
1309 llinfos << "Object " << i << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl; 1291 LLViewerObject* objectp = (*iter)->getObject();
1292 llinfos << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl;
1310 llinfos << " hasLSL " << objectp->flagScripted() << llendl; 1293 llinfos << " hasLSL " << objectp->flagScripted() << llendl;
1311 llinfos << " hasTouch " << objectp->flagHandleTouch() << llendl; 1294 llinfos << " hasTouch " << objectp->flagHandleTouch() << llendl;
1312 llinfos << " hasMoney " << objectp->flagTakesMoney() << llendl; 1295 llinfos << " hasMoney " << objectp->flagTakesMoney() << llendl;
@@ -1317,16 +1300,22 @@ void LLSelectMgr::dump()
1317 LLDrawable* drawablep = objectp->mDrawable; 1300 LLDrawable* drawablep = objectp->mDrawable;
1318 llinfos << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << llendl; 1301 llinfos << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << llendl;
1319 llinfos << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << llendl; 1302 llinfos << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << llendl;
1320 i++; 1303 count++;
1321 } 1304 }
1322 1305
1323 // Face iterator 1306 // Face iterator
1324 S32 te; 1307 for (LLObjectSelection::iterator iter = getSelection()->begin();
1325 for (mSelectedObjects->getFirstTE(&objectp, &te); 1308 iter != getSelection()->end(); iter++ )
1326 objectp;
1327 mSelectedObjects->getNextTE(&objectp, &te))
1328 { 1309 {
1329 llinfos << "Object " << objectp << " te " << te << llendl; 1310 LLSelectNode* node = *iter;
1311 LLViewerObject* objectp = node->getObject();
1312 for (S32 te = 0; te < objectp->getNumTEs(); ++te )
1313 {
1314 if (node->isTESelected(te))
1315 {
1316 llinfos << "Object " << objectp << " te " << te << llendl;
1317 }
1318 }
1330 } 1319 }
1331 1320
1332 llinfos << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << llendl; 1321 llinfos << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << llendl;
@@ -1347,6 +1336,18 @@ void LLSelectMgr::cleanup()
1347// Manipulate properties of selected objects 1336// Manipulate properties of selected objects
1348//--------------------------------------------------------------------------- 1337//---------------------------------------------------------------------------
1349 1338
1339struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
1340{
1341 virtual bool apply(LLViewerObject* object)
1342 {
1343 if (object->permModify())
1344 {
1345 object->sendTEUpdate();
1346 }
1347 return true;
1348 }
1349};
1350
1350//----------------------------------------------------------------------------- 1351//-----------------------------------------------------------------------------
1351// selectionSetImage() 1352// selectionSetImage()
1352//----------------------------------------------------------------------------- 1353//-----------------------------------------------------------------------------
@@ -1355,7 +1356,6 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
1355{ 1356{
1356 // First for (no copy) textures and multiple object selection 1357 // First for (no copy) textures and multiple object selection
1357 LLViewerInventoryItem* item = gInventory.getItem(imageid); 1358 LLViewerInventoryItem* item = gInventory.getItem(imageid);
1358
1359 if(item 1359 if(item
1360 && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) 1360 && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
1361 && (mSelectedObjects->getNumNodes() > 1) ) 1361 && (mSelectedObjects->getNumNodes() > 1) )
@@ -1365,54 +1365,63 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
1365 return; 1365 return;
1366 } 1366 }
1367 1367
1368 LLViewerObject* objectp; 1368 struct f : public LLSelectedTEFunctor
1369 S32 te;
1370
1371 for (mSelectedObjects->getFirstTE(&objectp, &te); objectp; mSelectedObjects->getNextTE(&objectp, &te))
1372 { 1369 {
1373 if (item) 1370 LLViewerInventoryItem* mItem;
1371 LLUUID mImageID;
1372 f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
1373 bool apply(LLViewerObject* objectp, S32 te)
1374 { 1374 {
1375 if (te == -1) // all faces 1375 if (mItem)
1376 { 1376 {
1377 LLToolDragAndDrop::dropTextureAllFaces(objectp, 1377 if (te == -1) // all faces
1378 item, 1378 {
1379 LLToolDragAndDrop::SOURCE_AGENT, 1379 LLToolDragAndDrop::dropTextureAllFaces(objectp,
1380 LLUUID::null); 1380 mItem,
1381 LLToolDragAndDrop::SOURCE_AGENT,
1382 LLUUID::null);
1383 }
1384 else // one face
1385 {
1386 LLToolDragAndDrop::dropTextureOneFace(objectp,
1387 te,
1388 mItem,
1389 LLToolDragAndDrop::SOURCE_AGENT,
1390 LLUUID::null);
1391 }
1381 } 1392 }
1382 else // one face 1393 else // not an inventory item
1383 { 1394 {
1384 LLToolDragAndDrop::dropTextureOneFace(objectp, 1395 // Texture picker defaults aren't inventory items
1385 te, 1396 // * Don't need to worry about permissions for them
1386 item, 1397 // * Can just apply the texture and be done with it.
1387 LLToolDragAndDrop::SOURCE_AGENT, 1398 objectp->setTEImage(te, gImageList.getImage(mImageID, TRUE, FALSE));
1388 LLUUID::null);
1389 } 1399 }
1400 return true;
1390 } 1401 }
1391 1402 } setfunc(item, imageid);
1392 else // not an inventory item 1403 getSelection()->applyToTEs(&setfunc);
1393 {
1394 // Texture picker defaults aren't inventory items
1395 // * Don't need to worry about permissions for them
1396 // * Can just apply the texture and be done with it.
1397 objectp->setTEImage(te, gImageList.getImage(imageid));
1398 1404
1399 objectp->sendTEUpdate(); 1405 struct g : public LLSelectedObjectFunctor
1400 }
1401 }
1402
1403
1404 // 1 particle effect per object
1405 if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
1406 { 1406 {
1407 for (objectp = mSelectedObjects->getFirstObject(); objectp; objectp = mSelectedObjects->getNextObject()) 1407 LLViewerInventoryItem* mItem;
1408 g(LLViewerInventoryItem* item) : mItem(item) {}
1409 virtual bool apply(LLViewerObject* object)
1408 { 1410 {
1409 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); 1411 if (!mItem)
1410 effectp->setSourceObject(gAgent.getAvatarObject()); 1412 {
1411 effectp->setTargetObject(objectp); 1413 object->sendTEUpdate();
1412 effectp->setDuration(LL_HUD_DUR_SHORT); 1414 // 1 particle effect per object
1413 effectp->setColor(LLColor4U(gAgent.getEffectColor())); 1415 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
1416 effectp->setSourceObject(gAgent.getAvatarObject());
1417 effectp->setTargetObject(object);
1418 effectp->setDuration(LL_HUD_DUR_SHORT);
1419 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
1420 }
1421 return true;
1414 } 1422 }
1415 } 1423 } sendfunc(item);
1424 getSelection()->applyToObjects(&sendfunc);
1416} 1425}
1417 1426
1418//----------------------------------------------------------------------------- 1427//-----------------------------------------------------------------------------
@@ -1420,24 +1429,23 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
1420//----------------------------------------------------------------------------- 1429//-----------------------------------------------------------------------------
1421void LLSelectMgr::selectionSetColor(const LLColor4 &color) 1430void LLSelectMgr::selectionSetColor(const LLColor4 &color)
1422{ 1431{
1423 LLViewerObject* object; 1432 struct f : public LLSelectedTEFunctor
1424 S32 te;
1425 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1426 {
1427 if (object->permModify())
1428 {
1429 // update viewer side color in anticipation of update from simulator
1430 object->setTEColor(te, color);
1431 }
1432 }
1433
1434 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
1435 { 1433 {
1436 if (object->permModify()) 1434 LLColor4 mColor;
1435 f(const LLColor4& c) : mColor(c) {}
1436 bool apply(LLViewerObject* object, S32 te)
1437 { 1437 {
1438 object->sendTEUpdate(); 1438 if (object->permModify())
1439 {
1440 object->setTEColor(te, mColor);
1441 }
1442 return true;
1439 } 1443 }
1440 } 1444 } setfunc(color);
1445 getSelection()->applyToTEs(&setfunc);
1446
1447 LLSelectMgrSendFunctor sendfunc;
1448 getSelection()->applyToObjects(&sendfunc);
1441} 1449}
1442 1450
1443//----------------------------------------------------------------------------- 1451//-----------------------------------------------------------------------------
@@ -1445,27 +1453,26 @@ void LLSelectMgr::selectionSetColor(const LLColor4 &color)
1445//----------------------------------------------------------------------------- 1453//-----------------------------------------------------------------------------
1446void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color) 1454void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color)
1447{ 1455{
1448 LLViewerObject* object; 1456 struct f : public LLSelectedTEFunctor
1449 LLColor4 new_color = color;
1450 S32 te;
1451 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1452 { 1457 {
1453 if (object->permModify()) 1458 LLColor4 mColor;
1459 f(const LLColor4& c) : mColor(c) {}
1460 bool apply(LLViewerObject* object, S32 te)
1454 { 1461 {
1455 LLColor4 prev_color = object->getTE(te)->getColor(); 1462 if (object->permModify())
1456 new_color.mV[VALPHA] = prev_color.mV[VALPHA]; 1463 {
1457 // update viewer side color in anticipation of update from simulator 1464 LLColor4 prev_color = object->getTE(te)->getColor();
1458 object->setTEColor(te, new_color); 1465 mColor.mV[VALPHA] = prev_color.mV[VALPHA];
1459 } 1466 // update viewer side color in anticipation of update from simulator
1460 } 1467 object->setTEColor(te, mColor);
1461 1468 }
1462 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1469 return true;
1463 {
1464 if (object->permModify())
1465 {
1466 object->sendTEUpdate();
1467 } 1470 }
1468 } 1471 } setfunc(color);
1472 getSelection()->applyToTEs(&setfunc);
1473
1474 LLSelectMgrSendFunctor sendfunc;
1475 getSelection()->applyToObjects(&sendfunc);
1469} 1476}
1470 1477
1471//----------------------------------------------------------------------------- 1478//-----------------------------------------------------------------------------
@@ -1473,227 +1480,246 @@ void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color)
1473//----------------------------------------------------------------------------- 1480//-----------------------------------------------------------------------------
1474void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha) 1481void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha)
1475{ 1482{
1476 LLViewerObject* object; 1483 struct f : public LLSelectedTEFunctor
1477 S32 te;
1478 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1479 { 1484 {
1480 if (object->permModify()) 1485 F32 mAlpha;
1481 { 1486 f(const F32& a) : mAlpha(a) {}
1482 LLColor4 prev_color = object->getTE(te)->getColor(); 1487 bool apply(LLViewerObject* object, S32 te)
1483 prev_color.mV[VALPHA] = alpha;
1484 // update viewer side color in anticipation of update from simulator
1485 object->setTEColor(te, prev_color);
1486 }
1487 }
1488
1489 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
1490 {
1491 if (object->permModify())
1492 { 1488 {
1493 object->sendTEUpdate(); 1489 if (object->permModify())
1490 {
1491 LLColor4 prev_color = object->getTE(te)->getColor();
1492 prev_color.mV[VALPHA] = mAlpha;
1493 // update viewer side color in anticipation of update from simulator
1494 object->setTEColor(te, prev_color);
1495 }
1496 return true;
1494 } 1497 }
1495 } 1498 } setfunc(alpha);
1499 getSelection()->applyToTEs(&setfunc);
1500
1501 LLSelectMgrSendFunctor sendfunc;
1502 getSelection()->applyToObjects(&sendfunc);
1496} 1503}
1497 1504
1498void LLSelectMgr::selectionRevertColors() 1505void LLSelectMgr::selectionRevertColors()
1499{ 1506{
1500 LLViewerObject* object; 1507 struct f : public LLSelectedTEFunctor
1501 S32 te;
1502
1503 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1504 { 1508 {
1505 if (object->permModify()) 1509 LLObjectSelectionHandle mSelectedObjects;
1510 f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
1511 bool apply(LLViewerObject* object, S32 te)
1506 { 1512 {
1507 LLSelectNode* nodep = mSelectedObjects->findNode(object); 1513 if (object->permModify())
1508 if (nodep && te < (S32)nodep->mSavedColors.size())
1509 { 1514 {
1510 LLColor4 color = nodep->mSavedColors[te]; 1515 LLSelectNode* nodep = mSelectedObjects->findNode(object);
1511 // update viewer side color in anticipation of update from simulator 1516 if (nodep && te < (S32)nodep->mSavedColors.size())
1512 object->setTEColor(te, color); 1517 {
1518 LLColor4 color = nodep->mSavedColors[te];
1519 // update viewer side color in anticipation of update from simulator
1520 object->setTEColor(te, color);
1521 }
1513 } 1522 }
1523 return true;
1514 } 1524 }
1515 } 1525 } setfunc(mSelectedObjects);
1516 1526 getSelection()->applyToTEs(&setfunc);
1517 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1527
1518 { 1528 LLSelectMgrSendFunctor sendfunc;
1519 if (object->permModify()) 1529 getSelection()->applyToObjects(&sendfunc);
1520 {
1521 object->sendTEUpdate();
1522 }
1523 }
1524} 1530}
1525 1531
1526BOOL LLSelectMgr::selectionRevertTextures() 1532BOOL LLSelectMgr::selectionRevertTextures()
1527{ 1533{
1528 LLViewerObject* object; 1534 struct f : public LLSelectedTEFunctor
1529 S32 te;
1530
1531 BOOL revert_successful = TRUE;
1532 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1533 { 1535 {
1534 if (object->permModify()) 1536 LLObjectSelectionHandle mSelectedObjects;
1537 f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
1538 bool apply(LLViewerObject* object, S32 te)
1535 { 1539 {
1536 LLSelectNode* nodep = mSelectedObjects->findNode(object); 1540 if (object->permModify())
1537 if (nodep && te < (S32)nodep->mSavedTextures.size())
1538 { 1541 {
1539 LLUUID id = nodep->mSavedTextures[te]; 1542 LLSelectNode* nodep = mSelectedObjects->findNode(object);
1540 // update textures on viewer side 1543 if (nodep && te < (S32)nodep->mSavedTextures.size())
1541 if (id.isNull())
1542 { 1544 {
1543 // this was probably a no-copy texture, leave image as-is 1545 LLUUID id = nodep->mSavedTextures[te];
1544 revert_successful = FALSE; 1546 // update textures on viewer side
1545 } 1547 if (id.isNull())
1546 else 1548 {
1547 { 1549 // this was probably a no-copy texture, leave image as-is
1548 object->setTEImage(te, gImageList.getImage(id)); 1550 return FALSE;
1551 }
1552 else
1553 {
1554 object->setTEImage(te, gImageList.getImage(id));
1555 }
1549 } 1556 }
1550 } 1557 }
1558 return true;
1551 } 1559 }
1552 } 1560 } setfunc(mSelectedObjects);
1553 1561 BOOL revert_successful = getSelection()->applyToTEs(&setfunc);
1554 // propagate texture changes to server 1562
1555 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1563 LLSelectMgrSendFunctor sendfunc;
1556 { 1564 getSelection()->applyToObjects(&sendfunc);
1557 if (object->permModify())
1558 {
1559 object->sendTEUpdate();
1560 }
1561 }
1562 1565
1563 return revert_successful; 1566 return revert_successful;
1564} 1567}
1565 1568
1566void LLSelectMgr::selectionSetBumpmap(U8 bumpmap) 1569void LLSelectMgr::selectionSetBumpmap(U8 bumpmap)
1567{ 1570{
1568 LLViewerObject* object; 1571 struct f : public LLSelectedTEFunctor
1569 S32 te;
1570 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1571 {
1572 if (object->permModify())
1573 {
1574 // update viewer side color in anticipation of update from simulator
1575 object->setTEBumpmap(te, bumpmap);
1576 }
1577 }
1578
1579 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
1580 { 1572 {
1581 if (object->permModify()) 1573 U8 mBump;
1574 f(const U8& b) : mBump(b) {}
1575 bool apply(LLViewerObject* object, S32 te)
1582 { 1576 {
1583 object->sendTEUpdate(); 1577 if (object->permModify())
1578 {
1579 // update viewer side color in anticipation of update from simulator
1580 object->setTEBumpmap(te, mBump);
1581 }
1582 return true;
1584 } 1583 }
1585 } 1584 } setfunc(bumpmap);
1585 getSelection()->applyToTEs(&setfunc);
1586
1587 LLSelectMgrSendFunctor sendfunc;
1588 getSelection()->applyToObjects(&sendfunc);
1586} 1589}
1587 1590
1588void LLSelectMgr::selectionSetTexGen(U8 texgen) 1591void LLSelectMgr::selectionSetTexGen(U8 texgen)
1589{ 1592{
1590 LLViewerObject* object; 1593 struct f : public LLSelectedTEFunctor
1591 S32 te;
1592 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1593 { 1594 {
1594 if (object->permModify()) 1595 U8 mTexgen;
1596 f(const U8& t) : mTexgen(t) {}
1597 bool apply(LLViewerObject* object, S32 te)
1595 { 1598 {
1596 // update viewer side color in anticipation of update from simulator 1599 if (object->permModify())
1597 object->setTETexGen(te, texgen); 1600 {
1601 // update viewer side color in anticipation of update from simulator
1602 object->setTETexGen(te, mTexgen);
1603 }
1604 return true;
1598 } 1605 }
1599 } 1606 } setfunc(texgen);
1607 getSelection()->applyToTEs(&setfunc);
1600 1608
1601 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1609 LLSelectMgrSendFunctor sendfunc;
1602 { 1610 getSelection()->applyToObjects(&sendfunc);
1603 if (object->permModify())
1604 {
1605 object->sendTEUpdate();
1606 }
1607 }
1608} 1611}
1609 1612
1610 1613
1611void LLSelectMgr::selectionSetShiny(U8 shiny) 1614void LLSelectMgr::selectionSetShiny(U8 shiny)
1612{ 1615{
1613 LLViewerObject* object; 1616 struct f : public LLSelectedTEFunctor
1614 S32 te;
1615 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1616 { 1617 {
1617 if (object->permModify()) 1618 U8 mShiny;
1619 f(const U8& t) : mShiny(t) {}
1620 bool apply(LLViewerObject* object, S32 te)
1618 { 1621 {
1619 // update viewer side color in anticipation of update from simulator 1622 if (object->permModify())
1620 object->setTEShiny(te, shiny); 1623 {
1624 // update viewer side color in anticipation of update from simulator
1625 object->setTEShiny(te, mShiny);
1626 }
1627 return true;
1621 } 1628 }
1622 } 1629 } setfunc(shiny);
1630 getSelection()->applyToTEs(&setfunc);
1623 1631
1624 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1632 LLSelectMgrSendFunctor sendfunc;
1625 { 1633 getSelection()->applyToObjects(&sendfunc);
1626 if (object->permModify())
1627 {
1628 object->sendTEUpdate();
1629 }
1630 }
1631} 1634}
1632 1635
1633void LLSelectMgr::selectionSetFullbright(U8 fullbright) 1636void LLSelectMgr::selectionSetFullbright(U8 fullbright)
1634{ 1637{
1635 LLViewerObject* object; 1638 struct f : public LLSelectedTEFunctor
1636 S32 te;
1637 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) )
1638 { 1639 {
1639 if (object->permModify()) 1640 U8 mFullbright;
1641 f(const U8& t) : mFullbright(t) {}
1642 bool apply(LLViewerObject* object, S32 te)
1640 { 1643 {
1641 // update viewer side color in anticipation of update from simulator 1644 if (object->permModify())
1642 object->setTEFullbright(te, fullbright); 1645 {
1646 // update viewer side color in anticipation of update from simulator
1647 object->setTEFullbright(te, mFullbright);
1648 }
1649 return true;
1643 } 1650 }
1644 } 1651 } setfunc(fullbright);
1652 getSelection()->applyToTEs(&setfunc);
1645 1653
1646 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1654 struct g : public LLSelectedObjectFunctor
1647 { 1655 {
1648 if (object->permModify()) 1656 U8 mFullbright;
1657 g(const U8& t) : mFullbright(t) {}
1658 virtual bool apply(LLViewerObject* object)
1649 { 1659 {
1650 object->sendTEUpdate(); 1660 if (object->permModify())
1651 if (fullbright)
1652 { 1661 {
1653 U8 material = object->getMaterial(); 1662 object->sendTEUpdate();
1654 U8 mcode = material & LL_MCODE_MASK; 1663 if (mFullbright)
1655 if (mcode == LL_MCODE_LIGHT)
1656 { 1664 {
1657 mcode = LL_MCODE_GLASS; 1665 U8 material = object->getMaterial();
1658 material = (material & ~LL_MCODE_MASK) | mcode; 1666 U8 mcode = material & LL_MCODE_MASK;
1659 object->setMaterial(material); 1667 if (mcode == LL_MCODE_LIGHT)
1660 object->sendMaterialUpdate(); 1668 {
1669 mcode = LL_MCODE_GLASS;
1670 material = (material & ~LL_MCODE_MASK) | mcode;
1671 object->setMaterial(material);
1672 object->sendMaterialUpdate();
1673 }
1661 } 1674 }
1662 } 1675 }
1676 return true;
1663 } 1677 }
1664 } 1678 } sendfunc(fullbright);
1679 getSelection()->applyToObjects(&sendfunc);
1665} 1680}
1666 1681
1667void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url) 1682void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url)
1668{ 1683{
1669 LLViewerObject* object;
1670 S32 te;
1671 U8 media_flags = LLTextureEntry::MF_NONE; 1684 U8 media_flags = LLTextureEntry::MF_NONE;
1672 if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE) 1685 if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE)
1673 { 1686 {
1674 media_flags = LLTextureEntry::MF_WEB_PAGE; 1687 media_flags = LLTextureEntry::MF_WEB_PAGE;
1675 } 1688 }
1676 1689
1677 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te) ) 1690 struct f : public LLSelectedTEFunctor
1678 { 1691 {
1679 if (object->permModify()) 1692 U8 mMediaFlags;
1693 f(const U8& t) : mMediaFlags(t) {}
1694 bool apply(LLViewerObject* object, S32 te)
1680 { 1695 {
1681 // update viewer side color in anticipation of update from simulator 1696 if (object->permModify())
1682 object->setTEMediaFlags(te, media_flags); 1697 {
1698 // update viewer side color in anticipation of update from simulator
1699 object->setTEMediaFlags(te, mMediaFlags);
1700 }
1701 return true;
1683 } 1702 }
1684 } 1703 } setfunc(media_flags);
1704 getSelection()->applyToTEs(&setfunc);
1685 1705
1686 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 1706 struct g : public LLSelectedObjectFunctor
1687 { 1707 {
1688 if (object->permModify()) 1708 U8 media_type;
1709 const std::string& media_url ;
1710 g(U8 a, const std::string& b) : media_type(a), media_url(b) {}
1711 virtual bool apply(LLViewerObject* object)
1689 { 1712 {
1690 // JAMESDEBUG TODO set object media type 1713 if (object->permModify())
1691 object->setMediaType(media_type); 1714 {
1692 object->setMediaURL(media_url); 1715 object->sendTEUpdate();
1693 1716 object->setMediaType(media_type);
1694 object->sendTEUpdate(); 1717 object->setMediaURL(media_url);
1718 }
1719 return true;
1695 } 1720 }
1696 } 1721 } sendfunc(media_type, media_url);
1722 getSelection()->applyToObjects(&sendfunc);
1697} 1723}
1698 1724
1699 1725
@@ -1703,11 +1729,11 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string&
1703//----------------------------------------------------------------------------- 1729//-----------------------------------------------------------------------------
1704LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object) 1730LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
1705{ 1731{
1706 LLSelectNode* nodep; 1732 for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
1707 1733 iter != getSelection()->valid_end(); iter++ )
1708 for (nodep = mSelectedObjects->getFirstNode(); nodep; nodep = mSelectedObjects->getNextNode() )
1709 { 1734 {
1710 if((nodep->getObject() == object) && nodep->mValid) 1735 LLSelectNode* nodep = *iter;
1736 if (nodep->getObject() == object)
1711 { 1737 {
1712 return nodep->mPermissions; 1738 return nodep->mPermissions;
1713 } 1739 }
@@ -1718,339 +1744,138 @@ LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
1718 1744
1719 1745
1720//----------------------------------------------------------------------------- 1746//-----------------------------------------------------------------------------
1721// selectionGetTexUUID() 1747// selectionSetMaterial()
1722//-----------------------------------------------------------------------------
1723BOOL LLSelectMgr::selectionGetTexUUID(LLUUID& id)
1724{
1725 LLViewerObject* first_objectp;
1726 S32 first_te;
1727 mSelectedObjects->getPrimaryTE(&first_objectp, &first_te);
1728
1729 // nothing selected
1730 if (!first_objectp)
1731 {
1732 return FALSE;
1733 }
1734
1735 LLViewerImage* first_imagep = first_objectp->getTEImage(first_te);
1736
1737 if (!first_imagep)
1738 {
1739 return FALSE;
1740 }
1741
1742 BOOL identical = TRUE;
1743 LLViewerObject *objectp;
1744 S32 te;
1745 for (mSelectedObjects->getFirstTE(&objectp, &te); objectp; mSelectedObjects->getNextTE(&objectp, &te) )
1746 {
1747 if (objectp->getTEImage(te) != first_imagep)
1748 {
1749 identical = FALSE;
1750 break;
1751 }
1752 }
1753
1754 id = first_imagep->getID();
1755 return identical;
1756}
1757
1758//-----------------------------------------------------------------------------
1759// selectionGetColor()
1760//-----------------------------------------------------------------------------
1761BOOL LLSelectMgr::selectionGetColor(LLColor4 &color)
1762{
1763 LLViewerObject* first_object;
1764 S32 first_te;
1765 mSelectedObjects->getPrimaryTE(&first_object, &first_te);
1766
1767 // nothing selected
1768 if (!first_object)
1769 {
1770 return FALSE;
1771 }
1772
1773 LLColor4 first_color;
1774 if (!first_object->getTE(first_te))
1775 {
1776 return FALSE;
1777 }
1778 else
1779 {
1780 first_color = first_object->getTE(first_te)->getColor();
1781 }
1782
1783 BOOL identical = TRUE;
1784 LLViewerObject* object;
1785 S32 te;
1786 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te))
1787 {
1788 if (!object->getTE(te) || (object->getTE(te)->getColor() != first_color))
1789 {
1790 identical = FALSE;
1791 break;
1792 }
1793 }
1794
1795 color = first_color;
1796 return identical;
1797}
1798
1799
1800//-----------------------------------------------------------------------------
1801// selectionGetBumpmap()
1802//----------------------------------------------------------------------------- 1748//-----------------------------------------------------------------------------
1803BOOL LLSelectMgr::selectionGetBumpmap(U8 *bumpmap) 1749void LLSelectMgr::selectionSetMaterial(U8 material)
1804{ 1750{
1805 LLViewerObject* first_object; 1751 struct f : public LLSelectedObjectFunctor
1806 S32 first_te;
1807 mSelectedObjects->getPrimaryTE(&first_object, &first_te);
1808
1809 // nothing selected
1810 if (!first_object)
1811 {
1812 return FALSE;
1813 }
1814
1815 U8 first_value;
1816 if (!first_object->getTE(first_te))
1817 {
1818 return FALSE;
1819 }
1820 else
1821 {
1822 first_value = first_object->getTE(first_te)->getBumpmap();
1823 }
1824
1825 BOOL identical = TRUE;
1826 LLViewerObject* object;
1827 S32 te;
1828 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te))
1829 { 1752 {
1830 if (!object->getTE(te) || (object->getTE(te)->getBumpmap() != first_value)) 1753 U8 mMaterial;
1754 f(const U8& t) : mMaterial(t) {}
1755 virtual bool apply(LLViewerObject* object)
1831 { 1756 {
1832 identical = FALSE; 1757 if (object->permModify())
1833 break; 1758 {
1759 U8 cur_material = object->getMaterial();
1760 U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK);
1761 object->setMaterial(material);
1762 object->sendMaterialUpdate();
1763 }
1764 return true;
1834 } 1765 }
1835 } 1766 } sendfunc(material);
1836 1767 getSelection()->applyToObjects(&sendfunc);
1837 *bumpmap = first_value;
1838 return identical;
1839} 1768}
1840 1769
1841//----------------------------------------------------------------------------- 1770// TRUE if all selected objects have this PCode
1842// selectionGetShiny() 1771BOOL LLSelectMgr::selectionAllPCode(LLPCode code)
1843//-----------------------------------------------------------------------------
1844BOOL LLSelectMgr::selectionGetShiny(U8 *shiny)
1845{ 1772{
1846 LLViewerObject* first_object; 1773 struct f : public LLSelectedObjectFunctor
1847 S32 first_te;
1848 mSelectedObjects->getPrimaryTE(&first_object, &first_te);
1849
1850 // nothing selected
1851 if (!first_object)
1852 { 1774 {
1853 return FALSE; 1775 LLPCode mCode;
1854 } 1776 f(const LLPCode& t) : mCode(t) {}
1855 1777 virtual bool apply(LLViewerObject* object)
1856 U8 first_value;
1857 if (!first_object->getTE(first_te))
1858 {
1859 return FALSE;
1860 }
1861 else
1862 {
1863 first_value = first_object->getTE(first_te)->getShiny();
1864 }
1865
1866 BOOL identical = TRUE;
1867 LLViewerObject* object;
1868 S32 te;
1869 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te))
1870 {
1871 if (!object->getTE(te) || (object->getTE(te)->getShiny() != first_value))
1872 { 1778 {
1873 identical = FALSE; 1779 if (object->getPCode() != mCode)
1874 break; 1780 {
1781 return FALSE;
1782 }
1783 return true;
1875 } 1784 }
1876 } 1785 } func(code);
1877 1786 BOOL res = getSelection()->applyToObjects(&func);
1878 *shiny = first_value; 1787 return res;
1879 return identical;
1880} 1788}
1881 1789
1882//----------------------------------------------------------------------------- 1790bool LLSelectMgr::selectionGetIncludeInSearch(bool* include_in_search_out)
1883// selectionGetFullbright()
1884//-----------------------------------------------------------------------------
1885BOOL LLSelectMgr::selectionGetFullbright(U8 *fullbright)
1886{ 1791{
1887 LLViewerObject* first_object; 1792 LLViewerObject *object = mSelectedObjects->getFirstRootObject();
1888 S32 first_te; 1793 if (!object) return FALSE;
1889 mSelectedObjects->getPrimaryTE(&first_object, &first_te);
1890
1891 // nothing selected
1892 if (!first_object)
1893 {
1894 return FALSE;
1895 }
1896
1897 U8 first_value;
1898 if (!first_object->getTE(first_te))
1899 {
1900 return FALSE;
1901 }
1902 else
1903 {
1904 first_value = first_object->getTE(first_te)->getFullbright();
1905 }
1906
1907 BOOL identical = TRUE;
1908 LLViewerObject* object;
1909 S32 te;
1910 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te))
1911 {
1912 if (!object->getTE(te) || (object->getTE(te)->getFullbright() != first_value))
1913 {
1914 identical = FALSE;
1915 break;
1916 }
1917 }
1918 1794
1919 *fullbright = first_value; 1795 bool include_in_search = object->getIncludeInSearch();
1920 return identical;
1921}
1922 1796
1923// JAMESDEBUG TODO make this return mediatype off viewer object 1797 bool identical = true;
1924bool LLSelectMgr::selectionGetMediaType(U8 *media_type)
1925{
1926 LLViewerObject* first_object;
1927 S32 first_te;
1928 mSelectedObjects->getPrimaryTE(&first_object, &first_te);
1929
1930 // nothing selected
1931 if (!first_object)
1932 {
1933 return false;
1934 }
1935 1798
1936 U8 first_value; 1799 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
1937 if (!first_object->getTE(first_te)) 1800 iter != getSelection()->root_end(); iter++)
1938 {
1939 return false;
1940 }
1941 else
1942 { 1801 {
1943 first_value = first_object->getTE(first_te)->getMediaFlags(); 1802 LLViewerObject* object = (*iter)->getObject();
1944 }
1945 1803
1946 bool identical = true; 1804 if ( include_in_search != object->getIncludeInSearch())
1947 LLViewerObject* object;
1948 S32 te;
1949 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te))
1950 {
1951 if (!object->getTE(te) || (object->getTE(te)->getMediaFlags() != first_value))
1952 { 1805 {
1953 identical = false; 1806 identical = false;
1954 break; 1807 break;
1955 } 1808 }
1956 } 1809 }
1957 1810
1958 *media_type = first_value; 1811 *include_in_search_out = include_in_search;
1959 return identical; 1812 return identical;
1960} 1813}
1961 1814
1962 1815void LLSelectMgr::selectionSetIncludeInSearch(bool include_in_search)
1963
1964//-----------------------------------------------------------------------------
1965// selectionSetMaterial()
1966//-----------------------------------------------------------------------------
1967void LLSelectMgr::selectionSetMaterial(U8 material)
1968{ 1816{
1969 LLViewerObject* object; 1817 LLViewerObject* object = NULL;
1970 for (object = mSelectedObjects->getFirstObject(); object != NULL; object = mSelectedObjects->getNextObject() ) 1818 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
1971 { 1819 iter != getSelection()->root_end(); iter++)
1972 if (object->permModify())
1973 {
1974 U8 cur_material = object->getMaterial();
1975 material |= (cur_material & ~LL_MCODE_MASK);
1976 object->setMaterial(material);
1977 object->sendMaterialUpdate();
1978 }
1979 }
1980}
1981
1982// True if all selected objects have this PCode
1983BOOL LLSelectMgr::selectionAllPCode(LLPCode code)
1984{
1985 LLViewerObject *object;
1986 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
1987 { 1820 {
1988 if (object->getPCode() != code) 1821 object = (*iter)->getObject();
1989 { 1822 object->setIncludeInSearch(include_in_search);
1990 return FALSE;
1991 }
1992 } 1823 }
1993 return TRUE; 1824 sendListToRegions(
1825 "ObjectIncludeInSearch",
1826 packAgentAndSessionID,
1827 packObjectIncludeInSearch,
1828 &include_in_search,
1829 SEND_ONLY_ROOTS);
1994} 1830}
1995 1831
1996//----------------------------------------------------------------------------- 1832BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action)
1997// selectionGetMaterial()
1998//-----------------------------------------------------------------------------
1999BOOL LLSelectMgr::selectionGetMaterial(U8 *out_material)
2000{ 1833{
2001 LLViewerObject *object = mSelectedObjects->getFirstObject(); 1834 LLViewerObject *object = mSelectedObjects->getFirstObject();
2002 if (!object) return FALSE; 1835 if (!object)
2003
2004 U8 material = object->getMaterial();
2005
2006 BOOL identical = TRUE;
2007 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
2008 { 1836 {
2009 if ( material != object->getMaterial()) 1837 return FALSE;
2010 {
2011 identical = FALSE;
2012 break;
2013 }
2014 } 1838 }
2015 1839
2016 *out_material = material;
2017 return identical;
2018}
2019
2020BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action)
2021{
2022 LLViewerObject *object = mSelectedObjects->getFirstObject();
2023 if (!object) return FALSE;
2024
2025 U8 action = object->getClickAction(); 1840 U8 action = object->getClickAction();
1841 *out_action = action;
2026 1842
2027 BOOL identical = TRUE; 1843 struct f : public LLSelectedObjectFunctor
2028 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
2029 { 1844 {
2030 if ( action != object->getClickAction()) 1845 U8 mAction;
1846 f(const U8& t) : mAction(t) {}
1847 virtual bool apply(LLViewerObject* object)
2031 { 1848 {
2032 identical = FALSE; 1849 if ( mAction != object->getClickAction())
2033 break; 1850 {
1851 return false;
1852 }
1853 return true;
2034 } 1854 }
2035 } 1855 } func(action);
2036 1856 BOOL res = getSelection()->applyToObjects(&func);
2037 *out_action = action; 1857 return res;
2038 return identical;
2039} 1858}
2040 1859
2041void LLSelectMgr::selectionSetClickAction(U8 action) 1860void LLSelectMgr::selectionSetClickAction(U8 action)
2042{ 1861{
2043 LLViewerObject* object = NULL; 1862 struct f : public LLSelectedObjectFunctor
2044 for ( object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
2045 { 1863 {
2046 object->setClickAction(action); 1864 U8 mAction;
2047 } 1865 f(const U8& t) : mAction(t) {}
2048 sendListToRegions( 1866 virtual bool apply(LLViewerObject* object)
2049 "ObjectClickAction", 1867 {
2050 packAgentAndSessionID, 1868 object->setClickAction(mAction);
2051 packObjectClickAction, 1869 return true;
2052 &action, 1870 }
2053 SEND_INDIVIDUALS); 1871 } func(action);
1872 getSelection()->applyToObjects(&func);
1873
1874 sendListToRegions("ObjectClickAction",
1875 packAgentAndSessionID,
1876 packObjectClickAction,
1877 &action,
1878 SEND_INDIVIDUALS);
2054} 1879}
2055 1880
2056 1881
@@ -2125,34 +1950,42 @@ void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *)
2125//----------------------------------------------------------------------------- 1950//-----------------------------------------------------------------------------
2126void LLSelectMgr::selectionResetRotation() 1951void LLSelectMgr::selectionResetRotation()
2127{ 1952{
2128 LLQuaternion identity(0.f, 0.f, 0.f, 1.f); 1953 struct f : public LLSelectedObjectFunctor
2129
2130 LLViewerObject* object;
2131 for (object = mSelectedObjects->getFirstRootObject(); object; object = mSelectedObjects->getNextRootObject() )
2132 { 1954 {
2133 object->setRotation(identity); 1955 virtual bool apply(LLViewerObject* object)
2134 if (object->mDrawable.notNull())
2135 { 1956 {
2136 gPipeline.markMoved(object->mDrawable, TRUE); 1957 LLQuaternion identity(0.f, 0.f, 0.f, 1.f);
1958 object->setRotation(identity);
1959 if (object->mDrawable.notNull())
1960 {
1961 gPipeline.markMoved(object->mDrawable, TRUE);
1962 }
1963 object->sendRotationUpdate();
1964 return true;
2137 } 1965 }
2138 object->sendRotationUpdate(); 1966 } func;
2139 } 1967 getSelection()->applyToRootObjects(&func);
2140} 1968}
2141 1969
2142void LLSelectMgr::selectionRotateAroundZ(F32 degrees) 1970void LLSelectMgr::selectionRotateAroundZ(F32 degrees)
2143{ 1971{
2144 LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) ); 1972 LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) );
2145 1973 struct f : public LLSelectedObjectFunctor
2146 LLViewerObject* object;
2147 for (object = mSelectedObjects->getFirstRootObject(); object; object = mSelectedObjects->getNextRootObject() )
2148 { 1974 {
2149 object->setRotation( object->getRotationEdit() * rot ); 1975 LLQuaternion mRot;
2150 if (object->mDrawable.notNull()) 1976 f(const LLQuaternion& rot) : mRot(rot) {}
1977 virtual bool apply(LLViewerObject* object)
2151 { 1978 {
2152 gPipeline.markMoved(object->mDrawable, TRUE); 1979 object->setRotation( object->getRotationEdit() * mRot );
1980 if (object->mDrawable.notNull())
1981 {
1982 gPipeline.markMoved(object->mDrawable, TRUE);
1983 }
1984 object->sendRotationUpdate();
1985 return true;
2153 } 1986 }
2154 object->sendRotationUpdate(); 1987 } func(rot);
2155 } 1988 getSelection()->applyToRootObjects(&func);
2156} 1989}
2157 1990
2158 1991
@@ -2161,86 +1994,37 @@ void LLSelectMgr::selectionRotateAroundZ(F32 degrees)
2161//----------------------------------------------------------------------------- 1994//-----------------------------------------------------------------------------
2162void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter) 1995void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter)
2163{ 1996{
2164 LLViewerObject* object; 1997 struct f : public LLSelectedTEFunctor
2165 S32 te;
2166 for (mSelectedObjects->getFirstTE(&object, &te); object; mSelectedObjects->getNextTE(&object, &te))
2167 { 1998 {
2168 if (!object->permModify()) 1999 F32 mRepeatsPerMeter;
2000 f(const F32& t) : mRepeatsPerMeter(t) {}
2001 bool apply(LLViewerObject* object, S32 te)
2169 { 2002 {
2170 continue; 2003
2171 } 2004 if (object->permModify())
2005 {
2006 // Compute S,T to axis mapping
2007 U32 s_axis, t_axis;
2008 if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis))
2009 {
2010 return TRUE;
2011 }
2172 2012
2173 if (object->getNumTEs() == 0) 2013 F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter;
2174 { 2014 F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter;
2175 continue;
2176 }
2177 2015
2178 // Compute S,T to axis mapping 2016 object->setTEScale(te, new_s, new_t);
2179 U32 s_axis, t_axis; 2017 }
2180 if (!getTESTAxes(object, te, &s_axis, &t_axis)) 2018 return true;
2181 {
2182 continue;
2183 } 2019 }
2020 } setfunc(repeats_per_meter);
2021 getSelection()->applyToTEs(&setfunc);
2184 2022
2185 F32 new_s = object->getScale().mV[s_axis] * repeats_per_meter; 2023 LLSelectMgrSendFunctor sendfunc;
2186 F32 new_t = object->getScale().mV[t_axis] * repeats_per_meter; 2024 getSelection()->applyToObjects(&sendfunc);
2187
2188 object->setTEScale(te, new_s, new_t);
2189 }
2190
2191 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject())
2192 {
2193 if (object->permModify())
2194 {
2195 object->sendTEUpdate();
2196 }
2197 }
2198} 2025}
2199 2026
2200 2027
2201// BUG: Only works for boxes.
2202// Face numbering for flex boxes as of 1.14.2002
2203//-----------------------------------------------------------------------------
2204// getFaceSTAxes()
2205//-----------------------------------------------------------------------------
2206BOOL LLSelectMgr::getTESTAxes(const LLViewerObject* object, const U8 face, U32* s_axis, U32* t_axis)
2207{
2208 if (face == 0)
2209 {
2210 *s_axis = VX; *t_axis = VY;
2211 return TRUE;
2212 }
2213 else if (face == 1)
2214 {
2215 *s_axis = VX; *t_axis = VZ;
2216 return TRUE;
2217 }
2218 else if (face == 2)
2219 {
2220 *s_axis = VY; *t_axis = VZ;
2221 return TRUE;
2222 }
2223 else if (face == 3)
2224 {
2225 *s_axis = VX; *t_axis = VZ;
2226 return TRUE;
2227 }
2228 else if (face == 4)
2229 {
2230 *s_axis = VY; *t_axis = VZ;
2231 return TRUE;
2232 }
2233 else if (face == 5)
2234 {
2235 *s_axis = VX; *t_axis = VY;
2236 return TRUE;
2237 }
2238 else
2239 {
2240 // unknown face
2241 return FALSE;
2242 }
2243}
2244 2028
2245// Called at the end of a scale operation, this adjusts the textures to attempt to 2029// Called at the end of a scale operation, this adjusts the textures to attempt to
2246// maintain a constant repeats per meter. 2030// maintain a constant repeats per meter.
@@ -2250,14 +2034,12 @@ BOOL LLSelectMgr::getTESTAxes(const LLViewerObject* object, const U8 face, U32*
2250//----------------------------------------------------------------------------- 2034//-----------------------------------------------------------------------------
2251void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch) 2035void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
2252{ 2036{
2253 LLViewerObject* object; 2037 for (LLObjectSelection::iterator iter = getSelection()->begin();
2254 LLSelectNode* selectNode; 2038 iter != getSelection()->end(); iter++)
2255
2256 BOOL send = FALSE;
2257
2258 for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode())
2259 { 2039 {
2260 object = selectNode->getObject(); 2040 LLSelectNode* selectNode = *iter;
2041 LLViewerObject* object = selectNode->getObject();
2042
2261 if (!object->permModify()) 2043 if (!object->permModify())
2262 { 2044 {
2263 continue; 2045 continue;
@@ -2268,6 +2050,8 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
2268 continue; 2050 continue;
2269 } 2051 }
2270 2052
2053 BOOL send = FALSE;
2054
2271 for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++) 2055 for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++)
2272 { 2056 {
2273 const LLTextureEntry* tep = object->getTE(te_num); 2057 const LLTextureEntry* tep = object->getTE(te_num);
@@ -2277,8 +2061,11 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
2277 { 2061 {
2278 // Figure out how S,T changed with scale operation 2062 // Figure out how S,T changed with scale operation
2279 U32 s_axis, t_axis; 2063 U32 s_axis, t_axis;
2280 if (!getTESTAxes(object, te_num, &s_axis, &t_axis)) continue; 2064 if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis))
2281 2065 {
2066 continue;
2067 }
2068
2282 LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num]; 2069 LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];
2283 LLVector3 object_scale = object->getScale(); 2070 LLVector3 object_scale = object->getScale();
2284 2071
@@ -2301,70 +2088,23 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
2301 { 2088 {
2302 object->sendTEUpdate(); 2089 object->sendTEUpdate();
2303 } 2090 }
2304 } 2091 }
2305}
2306
2307
2308//-----------------------------------------------------------------------------
2309// selectionResetTexInfo()
2310//-----------------------------------------------------------------------------
2311void LLSelectMgr::selectionResetTexInfo(S32 selected_face)
2312{
2313 S32 start_face, end_face;
2314
2315 LLViewerObject* object;
2316 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject())
2317 {
2318 if (!object->permModify())
2319 {
2320 continue;
2321 }
2322 if (object->getNumTEs() == 0)
2323 {
2324 continue;
2325 }
2326
2327 if (selected_face == -1)
2328 {
2329 start_face = 0;
2330 end_face = object->getNumTEs() - 1;
2331 }
2332 else
2333 {
2334 start_face = selected_face;
2335 end_face = selected_face;
2336 }
2337
2338 for (S32 face = start_face; face <= end_face; face++)
2339 {
2340 // Actually, each object should reset to its appropriate value.
2341 object->setTEScale(face, 1.f, 1.f);
2342 object->setTEOffset(face, 0.f, 0.f);
2343 object->setTERotation(face, 0.f);
2344 }
2345
2346 object->sendTEUpdate();
2347 }
2348} 2092}
2349 2093
2350//----------------------------------------------------------------------------- 2094//-----------------------------------------------------------------------------
2351// selectGetAllRootsValid() 2095// selectGetAllRootsValid()
2352// Returns true if the viewer has information on all selected objects 2096// Returns TRUE if the viewer has information on all selected objects
2353//----------------------------------------------------------------------------- 2097//-----------------------------------------------------------------------------
2354BOOL LLSelectMgr::selectGetAllRootsValid() 2098BOOL LLSelectMgr::selectGetAllRootsValid()
2355{ 2099{
2356 for( LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2100 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2101 iter != getSelection()->root_end(); ++iter )
2357 { 2102 {
2358 2103 LLSelectNode* node = *iter;
2359 if( !node->mValid ) 2104 if( !node->mValid )
2360 { 2105 {
2361 return FALSE; 2106 return FALSE;
2362 } 2107 }
2363
2364 if( !node->getObject() )
2365 {
2366 return FALSE;
2367 }
2368 } 2108 }
2369 return TRUE; 2109 return TRUE;
2370} 2110}
@@ -2372,63 +2112,62 @@ BOOL LLSelectMgr::selectGetAllRootsValid()
2372 2112
2373//----------------------------------------------------------------------------- 2113//-----------------------------------------------------------------------------
2374// selectGetAllValid() 2114// selectGetAllValid()
2375// Returns true if the viewer has information on all selected objects 2115// Returns TRUE if the viewer has information on all selected objects
2376//----------------------------------------------------------------------------- 2116//-----------------------------------------------------------------------------
2377BOOL LLSelectMgr::selectGetAllValid() 2117BOOL LLSelectMgr::selectGetAllValid()
2378{ 2118{
2379 for( LLSelectNode* node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) 2119 for (LLObjectSelection::iterator iter = getSelection()->begin();
2120 iter != getSelection()->end(); ++iter )
2380 { 2121 {
2381 2122 LLSelectNode* node = *iter;
2382 if( !node->mValid ) 2123 if( !node->mValid )
2383 { 2124 {
2384 return FALSE; 2125 return FALSE;
2385 } 2126 }
2386
2387 if( !node->getObject() )
2388 {
2389 return FALSE;
2390 }
2391 } 2127 }
2392 return TRUE; 2128 return TRUE;
2393} 2129}
2394 2130
2395 2131
2396//----------------------------------------------------------------------------- 2132//-----------------------------------------------------------------------------
2397// selectGetModify() - return true if current agent can modify all 2133// selectGetModify() - return TRUE if current agent can modify all
2398// selected objects. 2134// selected objects.
2399//----------------------------------------------------------------------------- 2135//-----------------------------------------------------------------------------
2400BOOL LLSelectMgr::selectGetModify() 2136BOOL LLSelectMgr::selectGetModify()
2401{ 2137{
2402 for( LLSelectNode* node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) 2138 for (LLObjectSelection::iterator iter = getSelection()->begin();
2139 iter != getSelection()->end(); iter++ )
2403 { 2140 {
2141 LLSelectNode* node = *iter;
2142 LLViewerObject* object = node->getObject();
2404 if( !node->mValid ) 2143 if( !node->mValid )
2405 { 2144 {
2406 return FALSE; 2145 return FALSE;
2407 } 2146 }
2408 LLViewerObject* object = node->getObject(); 2147 if( !object->permModify() )
2409 if( !object || !object->permModify() )
2410 { 2148 {
2411 return FALSE; 2149 return FALSE;
2412 } 2150 }
2413 } 2151 }
2414
2415 return TRUE; 2152 return TRUE;
2416} 2153}
2417 2154
2418//----------------------------------------------------------------------------- 2155//-----------------------------------------------------------------------------
2419// selectGetRootsModify() - return true if current agent can modify all 2156// selectGetRootsModify() - return TRUE if current agent can modify all
2420// selected root objects. 2157// selected root objects.
2421//----------------------------------------------------------------------------- 2158//-----------------------------------------------------------------------------
2422BOOL LLSelectMgr::selectGetRootsModify() 2159BOOL LLSelectMgr::selectGetRootsModify()
2423{ 2160{
2424 for( LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2161 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2162 iter != getSelection()->root_end(); iter++ )
2425 { 2163 {
2164 LLSelectNode* node = *iter;
2165 LLViewerObject* object = node->getObject();
2426 if( !node->mValid ) 2166 if( !node->mValid )
2427 { 2167 {
2428 return FALSE; 2168 return FALSE;
2429 } 2169 }
2430 LLViewerObject* object = node->getObject(); 2170 if( !object->permModify() )
2431 if( !object || !object->permModify() )
2432 { 2171 {
2433 return FALSE; 2172 return FALSE;
2434 } 2173 }
@@ -2439,19 +2178,21 @@ BOOL LLSelectMgr::selectGetRootsModify()
2439 2178
2440 2179
2441//----------------------------------------------------------------------------- 2180//-----------------------------------------------------------------------------
2442// selectGetRootsTransfer() - return true if current agent can transfer all 2181// selectGetRootsTransfer() - return TRUE if current agent can transfer all
2443// selected root objects. 2182// selected root objects.
2444//----------------------------------------------------------------------------- 2183//-----------------------------------------------------------------------------
2445BOOL LLSelectMgr::selectGetRootsTransfer() 2184BOOL LLSelectMgr::selectGetRootsTransfer()
2446{ 2185{
2447 for(LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) 2186 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2187 iter != getSelection()->root_end(); iter++ )
2448 { 2188 {
2449 if(!node->mValid) 2189 LLSelectNode* node = *iter;
2190 LLViewerObject* object = node->getObject();
2191 if( !node->mValid )
2450 { 2192 {
2451 return FALSE; 2193 return FALSE;
2452 } 2194 }
2453 LLViewerObject* object = node->getObject(); 2195 if(!object->permTransfer())
2454 if(!object || !object->permTransfer())
2455 { 2196 {
2456 return FALSE; 2197 return FALSE;
2457 } 2198 }
@@ -2460,19 +2201,21 @@ BOOL LLSelectMgr::selectGetRootsTransfer()
2460} 2201}
2461 2202
2462//----------------------------------------------------------------------------- 2203//-----------------------------------------------------------------------------
2463// selectGetRootsCopy() - return true if current agent can copy all 2204// selectGetRootsCopy() - return TRUE if current agent can copy all
2464// selected root objects. 2205// selected root objects.
2465//----------------------------------------------------------------------------- 2206//-----------------------------------------------------------------------------
2466BOOL LLSelectMgr::selectGetRootsCopy() 2207BOOL LLSelectMgr::selectGetRootsCopy()
2467{ 2208{
2468 for(LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) 2209 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2210 iter != getSelection()->root_end(); iter++ )
2469 { 2211 {
2470 if(!node->mValid) 2212 LLSelectNode* node = *iter;
2213 LLViewerObject* object = node->getObject();
2214 if( !node->mValid )
2471 { 2215 {
2472 return FALSE; 2216 return FALSE;
2473 } 2217 }
2474 LLViewerObject* object = node->getObject(); 2218 if(!object->permCopy())
2475 if(!object || !object->permCopy())
2476 { 2219 {
2477 return FALSE; 2220 return FALSE;
2478 } 2221 }
@@ -2484,39 +2227,42 @@ BOOL LLSelectMgr::selectGetRootsCopy()
2484// selectGetCreator() 2227// selectGetCreator()
2485// Creator information only applies to root objects. 2228// Creator information only applies to root objects.
2486//----------------------------------------------------------------------------- 2229//-----------------------------------------------------------------------------
2487BOOL LLSelectMgr::selectGetCreator(LLUUID& id, LLString& name) 2230BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, LLString& name)
2488{ 2231{
2489 LLSelectNode* node = mSelectedObjects->getFirstRootNode();
2490 if(!node) node = mSelectedObjects->getFirstNode();
2491 if(!node) return FALSE;
2492 if(!node->mValid) return FALSE;
2493 LLViewerObject* obj = node->getObject();
2494 if(!obj) return FALSE;
2495 if(!(obj->isRoot() || obj->isJointChild())) return FALSE;
2496
2497 id = node->mPermissions->getCreator();
2498
2499 BOOL identical = TRUE; 2232 BOOL identical = TRUE;
2500 for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2233 BOOL first = TRUE;
2234 LLUUID first_id;
2235 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2236 iter != getSelection()->root_end(); iter++ )
2501 { 2237 {
2238 LLSelectNode* node = *iter;
2502 if (!node->mValid) 2239 if (!node->mValid)
2503 { 2240 {
2504 identical = FALSE; 2241 return FALSE;
2505 break;
2506 } 2242 }
2507 2243
2508 if ( !(id == node->mPermissions->getCreator() ) ) 2244 if (first)
2509 { 2245 {
2510 identical = FALSE; 2246 first_id = node->mPermissions->getCreator();
2511 break; 2247 first = FALSE;
2248 }
2249 else
2250 {
2251 if ( !(first_id == node->mPermissions->getCreator() ) )
2252 {
2253 identical = FALSE;
2254 break;
2255 }
2512 } 2256 }
2513 } 2257 }
2514 2258
2259 result_id = first_id;
2260
2515 if (identical) 2261 if (identical)
2516 { 2262 {
2517 char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ 2263 char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */
2518 char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ 2264 char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */
2519 gCacheName->getName(id, firstname, lastname); 2265 gCacheName->getName(first_id, firstname, lastname);
2520 name.assign( firstname ); 2266 name.assign( firstname );
2521 name.append( " " ); 2267 name.append( " " );
2522 name.append( lastname ); 2268 name.append( lastname );
@@ -2534,44 +2280,45 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& id, LLString& name)
2534// selectGetOwner() 2280// selectGetOwner()
2535// Owner information only applies to roots. 2281// Owner information only applies to roots.
2536//----------------------------------------------------------------------------- 2282//-----------------------------------------------------------------------------
2537BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name) 2283BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, LLString& name)
2538{ 2284{
2539 LLSelectNode* node = mSelectedObjects->getFirstRootNode();
2540 if(!node) node = mSelectedObjects->getFirstNode();
2541 if(!node) return FALSE;
2542 if(!node->mValid) return FALSE;
2543 LLViewerObject* obj = node->getObject();
2544 if(!obj) return FALSE;
2545 if(!(obj->isRootEdit() || obj->isRoot() || obj->isJointChild())) return FALSE;
2546
2547 BOOL group_owner = FALSE;
2548 id.setNull();
2549 node->mPermissions->getOwnership(id, group_owner);
2550
2551 BOOL identical = TRUE; 2285 BOOL identical = TRUE;
2552 for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2286 BOOL first = TRUE;
2287 BOOL first_group_owned = FALSE;
2288 LLUUID first_id;
2289 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2290 iter != getSelection()->root_end(); iter++ )
2553 { 2291 {
2292 LLSelectNode* node = *iter;
2554 if (!node->mValid) 2293 if (!node->mValid)
2555 { 2294 {
2556 identical = FALSE; 2295 return FALSE;
2557 break;
2558 } 2296 }
2559 2297
2560 LLUUID owner_id; 2298 if (first)
2561 BOOL is_group_owned = FALSE;
2562 if (!(node->mPermissions->getOwnership(owner_id, is_group_owned))
2563 || owner_id != id )
2564 { 2299 {
2565 identical = FALSE; 2300 node->mPermissions->getOwnership(first_id, first_group_owned);
2566 break; 2301 first = FALSE;
2302 }
2303 else
2304 {
2305 LLUUID owner_id;
2306 BOOL is_group_owned = FALSE;
2307 if (!(node->mPermissions->getOwnership(owner_id, is_group_owned))
2308 || owner_id != first_id || is_group_owned != first_group_owned)
2309 {
2310 identical = FALSE;
2311 break;
2312 }
2567 } 2313 }
2568 } 2314 }
2569 2315
2570 BOOL public_owner = (id.isNull() && !group_owner); 2316 result_id = first_id;
2571 2317
2572 if (identical) 2318 if (identical)
2573 { 2319 {
2574 if (group_owner) 2320 BOOL public_owner = (first_id.isNull() && !first_group_owned);
2321 if (first_group_owned)
2575 { 2322 {
2576 name.assign( "(Group Owned)"); 2323 name.assign( "(Group Owned)");
2577 } 2324 }
@@ -2579,7 +2326,7 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name)
2579 { 2326 {
2580 char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ 2327 char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */
2581 char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ 2328 char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */
2582 gCacheName->getName(id, firstname, lastname); 2329 gCacheName->getName(first_id, firstname, lastname);
2583 name.assign( firstname ); 2330 name.assign( firstname );
2584 name.append( " " ); 2331 name.append( " " );
2585 name.append( lastname ); 2332 name.append( lastname );
@@ -2602,43 +2349,45 @@ BOOL LLSelectMgr::selectGetOwner(LLUUID& id, LLString& name)
2602// selectGetLastOwner() 2349// selectGetLastOwner()
2603// Owner information only applies to roots. 2350// Owner information only applies to roots.
2604//----------------------------------------------------------------------------- 2351//-----------------------------------------------------------------------------
2605BOOL LLSelectMgr::selectGetLastOwner(LLUUID& id, LLString& name) 2352BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, LLString& name)
2606{ 2353{
2607 LLSelectNode* node = mSelectedObjects->getFirstRootNode();
2608 if(!node) node = mSelectedObjects->getFirstNode();
2609 if(!node) return FALSE;
2610 if(!node->mValid) return FALSE;
2611 LLViewerObject* obj = node->getObject();
2612 if(!obj) return FALSE;
2613 if(!(obj->isRoot() || obj->isJointChild())) return FALSE;
2614
2615 id = node->mPermissions->getLastOwner();
2616
2617 BOOL identical = TRUE; 2354 BOOL identical = TRUE;
2618 for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2355 BOOL first = TRUE;
2356 LLUUID first_id;
2357 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2358 iter != getSelection()->root_end(); iter++ )
2619 { 2359 {
2360 LLSelectNode* node = *iter;
2620 if (!node->mValid) 2361 if (!node->mValid)
2621 { 2362 {
2622 identical = FALSE; 2363 return FALSE;
2623 break;
2624 } 2364 }
2625 2365
2626 if ( !(id == node->mPermissions->getLastOwner() ) ) 2366 if (first)
2627 { 2367 {
2628 identical = FALSE; 2368 first_id = node->mPermissions->getLastOwner();
2629 break; 2369 first = FALSE;
2370 }
2371 else
2372 {
2373 if ( !(first_id == node->mPermissions->getLastOwner() ) )
2374 {
2375 identical = FALSE;
2376 break;
2377 }
2630 } 2378 }
2631 } 2379 }
2632 2380
2633 BOOL public_owner = (id.isNull()); 2381 result_id = first_id;
2634 2382
2635 if (identical) 2383 if (identical)
2636 { 2384 {
2385 BOOL public_owner = (first_id.isNull());
2637 if(!public_owner) 2386 if(!public_owner)
2638 { 2387 {
2639 char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ 2388 char firstname[DB_FIRST_NAME_BUF_SIZE]; /* Flawfinder: ignore */
2640 char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */ 2389 char lastname[DB_LAST_NAME_BUF_SIZE]; /* Flawfinder: ignore */
2641 gCacheName->getName(id, firstname, lastname); 2390 gCacheName->getName(first_id, firstname, lastname);
2642 name.assign( firstname ); 2391 name.assign( firstname );
2643 name.append( " " ); 2392 name.append( " " );
2644 name.append( lastname ); 2393 name.append( lastname );
@@ -2661,33 +2410,36 @@ BOOL LLSelectMgr::selectGetLastOwner(LLUUID& id, LLString& name)
2661// selectGetGroup() 2410// selectGetGroup()
2662// Group information only applies to roots. 2411// Group information only applies to roots.
2663//----------------------------------------------------------------------------- 2412//-----------------------------------------------------------------------------
2664BOOL LLSelectMgr::selectGetGroup(LLUUID& id) 2413BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)
2665{ 2414{
2666 LLSelectNode* node = mSelectedObjects->getFirstRootNode();
2667 if(!node) node = mSelectedObjects->getFirstNode();
2668 if(!node) return FALSE;
2669 if(!node->mValid) return FALSE;
2670 LLViewerObject* obj = node->getObject();
2671 if(!obj) return FALSE;
2672 if(!(obj->isRoot() || obj->isJointChild())) return FALSE;
2673
2674 id = node->mPermissions->getGroup();
2675
2676 BOOL identical = TRUE; 2415 BOOL identical = TRUE;
2677 for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2416 BOOL first = TRUE;
2417 LLUUID first_id;
2418 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2419 iter != getSelection()->root_end(); iter++ )
2678 { 2420 {
2421 LLSelectNode* node = *iter;
2679 if (!node->mValid) 2422 if (!node->mValid)
2680 { 2423 {
2681 identical = FALSE; 2424 return FALSE;
2682 break;
2683 } 2425 }
2684 2426
2685 if ( !(id == node->mPermissions->getGroup() ) ) 2427 if (first)
2686 { 2428 {
2687 identical = FALSE; 2429 first_id = node->mPermissions->getGroup();
2688 break; 2430 first = FALSE;
2431 }
2432 else
2433 {
2434 if ( !(first_id == node->mPermissions->getGroup() ) )
2435 {
2436 identical = FALSE;
2437 break;
2438 }
2689 } 2439 }
2690 } 2440 }
2441
2442 result_id = first_id;
2691 2443
2692 return identical; 2444 return identical;
2693} 2445}
@@ -2699,64 +2451,53 @@ BOOL LLSelectMgr::selectGetGroup(LLUUID& id)
2699//----------------------------------------------------------------------------- 2451//-----------------------------------------------------------------------------
2700BOOL LLSelectMgr::selectIsGroupOwned() 2452BOOL LLSelectMgr::selectIsGroupOwned()
2701{ 2453{
2702 LLSelectNode* node = mSelectedObjects->getFirstRootNode(); 2454 BOOL found_one = FALSE;
2703 if(!node) node = mSelectedObjects->getFirstNode(); 2455 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2704 if(!node) return FALSE; 2456 iter != getSelection()->root_end(); iter++ )
2705 if(!node->mValid) return FALSE;
2706 LLViewerObject* obj = node->getObject();
2707 if(!obj) return FALSE;
2708 if(!(obj->isRoot() || obj->isJointChild())) return FALSE;
2709
2710 BOOL is_group_owned = node->mPermissions->isGroupOwned();
2711
2712 if(is_group_owned)
2713 { 2457 {
2714 for ( node = mSelectedObjects->getNextRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2458 LLSelectNode* node = *iter;
2459 if (!node->mValid)
2715 { 2460 {
2716 if (!node->mValid) 2461 return FALSE;
2717 {
2718 is_group_owned = FALSE;
2719 break;
2720 }
2721
2722 if ( !( node->mPermissions->isGroupOwned() ) )
2723 {
2724 is_group_owned = FALSE;
2725 break;
2726 }
2727 } 2462 }
2728 } 2463 found_one = TRUE;
2729 return is_group_owned; 2464 if (!node->mPermissions->isGroupOwned())
2465 {
2466 return FALSE;
2467 }
2468 }
2469 return found_one ? TRUE : FALSE;
2730} 2470}
2731 2471
2732//----------------------------------------------------------------------------- 2472//-----------------------------------------------------------------------------
2733// selectGetPerm() 2473// selectGetPerm()
2734// Only operates on root nodes. 2474// Only operates on root nodes.
2735// Returns TRUE if all have valid data. 2475// Returns TRUE if all have valid data.
2736// mask_on has bits set to true where all permissions are true 2476// mask_on has bits set to TRUE where all permissions are TRUE
2737// mask_off has bits set to true where all permissions are false 2477// mask_off has bits set to TRUE where all permissions are FALSE
2738// if a bit is off both in mask_on and mask_off, the values differ within 2478// if a bit is off both in mask_on and mask_off, the values differ within
2739// the selection. 2479// the selection.
2740//----------------------------------------------------------------------------- 2480//-----------------------------------------------------------------------------
2741BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off) 2481BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off)
2742{ 2482{
2743 LLSelectNode* node = mSelectedObjects->getFirstRootNode();
2744 if (!node) return FALSE;
2745 if (!node->mValid) return FALSE;
2746
2747 U32 mask; 2483 U32 mask;
2748 U32 mask_and = 0xffffffff; 2484 U32 mask_and = 0xffffffff;
2749 U32 mask_or = 0x00000000; 2485 U32 mask_or = 0x00000000;
2750 BOOL all_valid = TRUE; 2486 BOOL all_valid = FALSE;
2751 2487
2752 for ( node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2488 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2489 iter != getSelection()->root_end(); iter++)
2753 { 2490 {
2491 LLSelectNode* node = *iter;
2492
2754 if (!node->mValid) 2493 if (!node->mValid)
2755 { 2494 {
2756 all_valid = FALSE; 2495 all_valid = FALSE;
2757 break; 2496 break;
2758 } 2497 }
2759 2498
2499 all_valid = TRUE;
2500
2760 switch( which_perm ) 2501 switch( which_perm )
2761 { 2502 {
2762 case PERM_BASE: 2503 case PERM_BASE:
@@ -2784,10 +2525,10 @@ BOOL LLSelectMgr::selectGetPerm(U8 which_perm, U32* mask_on, U32* mask_off)
2784 2525
2785 if (all_valid) 2526 if (all_valid)
2786 { 2527 {
2787 // ...true through all ANDs means all true 2528 // ...TRUE through all ANDs means all TRUE
2788 *mask_on = mask_and; 2529 *mask_on = mask_and;
2789 2530
2790 // ...false through all ORs means all false 2531 // ...FALSE through all ORs means all FALSE
2791 *mask_off = ~mask_or; 2532 *mask_off = ~mask_or;
2792 return TRUE; 2533 return TRUE;
2793 } 2534 }
@@ -2806,23 +2547,33 @@ BOOL LLSelectMgr::selectGetOwnershipCost(S32* out_cost)
2806 return mSelectedObjects->getOwnershipCost(*out_cost); 2547 return mSelectedObjects->getOwnershipCost(*out_cost);
2807} 2548}
2808 2549
2809BOOL LLSelectMgr::selectGetPermissions(LLPermissions& perm) 2550BOOL LLSelectMgr::selectGetPermissions(LLPermissions& result_perm)
2810{ 2551{
2811 LLSelectNode* node = mSelectedObjects->getFirstRootNode(); 2552 BOOL first = TRUE;
2812 if (!node) return FALSE; 2553 LLPermissions perm;
2813 if (!node->mValid) return FALSE; 2554 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2814 BOOL valid = TRUE; 2555 iter != getSelection()->root_end(); iter++ )
2815 perm = *(node->mPermissions);
2816 for(node = mSelectedObjects->getNextRootNode(); node != NULL; node = mSelectedObjects->getNextRootNode())
2817 { 2556 {
2818 if(!node->mValid) 2557 LLSelectNode* node = *iter;
2558 if (!node->mValid)
2819 { 2559 {
2820 valid = FALSE; 2560 return FALSE;
2821 break; 2561 }
2562
2563 if (first)
2564 {
2565 perm = *(node->mPermissions);
2566 first = FALSE;
2567 }
2568 else
2569 {
2570 perm.accumulate(*(node->mPermissions));
2822 } 2571 }
2823 perm.accumulate(*(node->mPermissions));
2824 } 2572 }
2825 return valid; 2573
2574 result_perm = perm;
2575
2576 return TRUE;
2826} 2577}
2827 2578
2828 2579
@@ -2833,10 +2584,12 @@ void LLSelectMgr::selectDelete()
2833 BOOL locked_but_deleteable_object = FALSE; 2584 BOOL locked_but_deleteable_object = FALSE;
2834 BOOL no_copy_but_deleteable_object = FALSE; 2585 BOOL no_copy_but_deleteable_object = FALSE;
2835 BOOL all_owned_by_you = TRUE; 2586 BOOL all_owned_by_you = TRUE;
2836 for(LLViewerObject* obj = mSelectedObjects->getFirstObject(); 2587
2837 obj != NULL; 2588 for (LLObjectSelection::iterator iter = getSelection()->begin();
2838 obj = mSelectedObjects->getNextObject()) 2589 iter != getSelection()->end(); iter++)
2839 { 2590 {
2591 LLViewerObject* obj = (*iter)->getObject();
2592
2840 if( obj->isAttachment() ) 2593 if( obj->isAttachment() )
2841 { 2594 {
2842 continue; 2595 continue;
@@ -2958,10 +2711,10 @@ void LLSelectMgr::confirmDelete(S32 option, void* data)
2958 // attempt to derez into the trash. 2711 // attempt to derez into the trash.
2959 LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id); 2712 LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id);
2960 gSelectMgr->sendListToRegions("DeRezObject", 2713 gSelectMgr->sendListToRegions("DeRezObject",
2961 packDeRezHeader, 2714 packDeRezHeader,
2962 packObjectLocalID, 2715 packObjectLocalID,
2963 (void*)info, 2716 (void*)info,
2964 SEND_ONLY_ROOTS); 2717 SEND_ONLY_ROOTS);
2965 // VEFFECT: Delete Object - one effect for all deletes 2718 // VEFFECT: Delete Object - one effect for all deletes
2966 if (gSelectMgr->mSelectedObjects->mSelectType != SELECT_TYPE_HUD) 2719 if (gSelectMgr->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
2967 { 2720 {
@@ -3006,9 +2759,10 @@ BOOL LLSelectMgr::selectIsForSale(S32& price)
3006 BOOL any_for_sale = FALSE; 2759 BOOL any_for_sale = FALSE;
3007 price = 0; 2760 price = 0;
3008 2761
3009 LLSelectNode *node; 2762 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
3010 for (node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode() ) 2763 iter != getSelection()->root_end(); iter++)
3011 { 2764 {
2765 LLSelectNode* node = *iter;
3012 if (node->mSaleInfo.isForSale()) 2766 if (node->mSaleInfo.isForSale())
3013 { 2767 {
3014 price += node->mSaleInfo.getSalePrice(); 2768 price += node->mSaleInfo.getSalePrice();
@@ -3022,61 +2776,92 @@ BOOL LLSelectMgr::selectIsForSale(S32& price)
3022 2776
3023// returns TRUE if all nodes are valid. method also stores an 2777// returns TRUE if all nodes are valid. method also stores an
3024// accumulated sale info. 2778// accumulated sale info.
3025BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& sale_info) 2779BOOL LLSelectMgr::selectGetSaleInfo(LLSaleInfo& result_sale_info)
3026{ 2780{
3027 LLSelectNode* node = mSelectedObjects->getFirstRootNode(); 2781 BOOL first = TRUE;
3028 if (!node) return FALSE; 2782 LLSaleInfo sale_info;
3029 if (!node->mValid) return FALSE; 2783 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
3030 BOOL valid = TRUE; 2784 iter != getSelection()->root_end(); iter++ )
3031 sale_info = node->mSaleInfo;
3032 for(node = mSelectedObjects->getNextRootNode(); node != NULL; node = mSelectedObjects->getNextRootNode())
3033 { 2785 {
3034 if(!node->mValid) 2786 LLSelectNode* node = *iter;
2787 if (!node->mValid)
3035 { 2788 {
3036 valid = FALSE; 2789 return FALSE;
3037 break; 2790 }
2791
2792 if (first)
2793 {
2794 sale_info = node->mSaleInfo;
2795 first = FALSE;
2796 }
2797 else
2798 {
2799 sale_info.accumulate(node->mSaleInfo);
3038 } 2800 }
3039 sale_info.accumulate(node->mSaleInfo);
3040 } 2801 }
3041 return valid; 2802
2803 result_sale_info = sale_info;
2804
2805 return TRUE;
3042} 2806}
3043 2807
3044BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& ag_perm) 2808BOOL LLSelectMgr::selectGetAggregatePermissions(LLAggregatePermissions& result_perm)
3045{ 2809{
3046 LLSelectNode* node = mSelectedObjects->getFirstNode(); 2810 BOOL first = TRUE;
3047 if (!node) return FALSE; 2811 LLAggregatePermissions perm;
3048 if (!node->mValid) return FALSE; 2812 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
3049 BOOL valid = TRUE; 2813 iter != getSelection()->root_end(); iter++ )
3050 ag_perm = node->mAggregatePerm;
3051 for(node = mSelectedObjects->getNextNode(); node != NULL; node = mSelectedObjects->getNextNode())
3052 { 2814 {
3053 if(!node->mValid) 2815 LLSelectNode* node = *iter;
2816 if (!node->mValid)
3054 { 2817 {
3055 valid = FALSE; 2818 return FALSE;
3056 break; 2819 }
2820
2821 if (first)
2822 {
2823 perm = node->mAggregatePerm;
2824 first = FALSE;
2825 }
2826 else
2827 {
2828 perm.aggregate(node->mAggregatePerm);
3057 } 2829 }
3058 ag_perm.aggregate(node->mAggregatePerm);
3059 } 2830 }
3060 return valid; 2831
2832 result_perm = perm;
2833
2834 return TRUE;
3061} 2835}
3062 2836
3063BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm) 2837BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& result_perm)
3064{ 2838{
3065 LLSelectNode* node = mSelectedObjects->getFirstNode(); 2839 BOOL first = TRUE;
3066 if (!node) return FALSE; 2840 LLAggregatePermissions perm;
3067 if (!node->mValid) return FALSE; 2841 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
3068 BOOL valid = TRUE; 2842 iter != getSelection()->root_end(); iter++ )
3069 ag_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm;
3070 for(node = mSelectedObjects->getNextNode(); node != NULL; node = mSelectedObjects->getNextNode())
3071 { 2843 {
3072 if(!node->mValid) 2844 LLSelectNode* node = *iter;
2845 if (!node->mValid)
3073 { 2846 {
3074 valid = FALSE; 2847 return FALSE;
3075 break; 2848 }
2849
2850 LLAggregatePermissions t_perm = node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm;
2851 if (first)
2852 {
2853 perm = t_perm;
2854 first = FALSE;
2855 }
2856 else
2857 {
2858 perm.aggregate(t_perm);
3076 } 2859 }
3077 ag_perm.aggregate(node->getObject()->permYouOwner() ? node->mAggregateTexturePermOwner : node->mAggregateTexturePerm);
3078 } 2860 }
3079 return valid; 2861
2862 result_perm = perm;
2863
2864 return TRUE;
3080} 2865}
3081 2866
3082 2867
@@ -3115,8 +2900,10 @@ void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy)
3115 } 2900 }
3116 else 2901 else
3117 { 2902 {
3118 for (LLSelectNode* node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) 2903 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2904 iter != getSelection()->root_end(); iter++ )
3119 { 2905 {
2906 LLSelectNode* node = *iter;
3120 node->mDuplicated = TRUE; 2907 node->mDuplicated = TRUE;
3121 node->mDuplicatePos = node->getObject()->getPositionGlobal(); 2908 node->mDuplicatePos = node->getObject()->getPositionGlobal();
3122 node->mDuplicateRot = node->getObject()->getRotation(); 2909 node->mDuplicateRot = node->getObject()->getRotation();
@@ -3133,21 +2920,24 @@ void LLSelectMgr::repeatDuplicate()
3133 return; 2920 return;
3134 } 2921 }
3135 2922
3136 LLSelectNode* node; 2923 std::vector<LLViewerObject*> non_duplicated_objects;
3137 LLDynamicArray<LLViewerObject*> non_duplicated_objects;
3138 2924
3139 for (node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) 2925 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2926 iter != getSelection()->root_end(); iter++ )
3140 { 2927 {
2928 LLSelectNode* node = *iter;
3141 if (!node->mDuplicated) 2929 if (!node->mDuplicated)
3142 { 2930 {
3143 non_duplicated_objects.put(node->getObject()); 2931 non_duplicated_objects.push_back(node->getObject());
3144 } 2932 }
3145 } 2933 }
3146 2934
3147 // make sure only previously duplicated objects are selected 2935 // make sure only previously duplicated objects are selected
3148 for (S32 i = 0; i < non_duplicated_objects.count(); i++) 2936 for (std::vector<LLViewerObject*>::iterator iter = non_duplicated_objects.begin();
2937 iter != non_duplicated_objects.end(); ++iter)
3149 { 2938 {
3150 deselectObjectAndFamily(non_duplicated_objects[i]); 2939 LLViewerObject* objectp = *iter;
2940 deselectObjectAndFamily(objectp);
3151 } 2941 }
3152 2942
3153 // duplicate objects in place 2943 // duplicate objects in place
@@ -3159,8 +2949,10 @@ void LLSelectMgr::repeatDuplicate()
3159 sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, &data, SEND_ONLY_ROOTS); 2949 sendListToRegions("ObjectDuplicate", packDuplicateHeader, packDuplicate, &data, SEND_ONLY_ROOTS);
3160 2950
3161 // move current selection based on delta from duplication position and update duplication position 2951 // move current selection based on delta from duplication position and update duplication position
3162 for (node = mSelectedObjects->getFirstRootNode(); node; node = mSelectedObjects->getNextRootNode()) 2952 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
2953 iter != getSelection()->root_end(); iter++ )
3163 { 2954 {
2955 LLSelectNode* node = *iter;
3164 if (node->mDuplicated) 2956 if (node->mDuplicated)
3165 { 2957 {
3166 LLQuaternion cur_rot = node->getObject()->getRotation(); 2958 LLQuaternion cur_rot = node->getObject()->getRotation();
@@ -3380,7 +3172,7 @@ void LLSelectMgr::sendGroup(const LLUUID& group_id)
3380 3172
3381struct LLBuyData 3173struct LLBuyData
3382{ 3174{
3383 LLDynamicArray<LLViewerObject*> mObjectsSent; 3175 std::vector<LLViewerObject*> mObjectsSent;
3384 LLUUID mCategoryID; 3176 LLUUID mCategoryID;
3385 LLSaleInfo mSaleInfo; 3177 LLSaleInfo mSaleInfo;
3386}; 3178};
@@ -3403,9 +3195,9 @@ void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data)
3403 LLBuyData* buy = (LLBuyData*)data; 3195 LLBuyData* buy = (LLBuyData*)data;
3404 3196
3405 LLViewerObject* object = node->getObject(); 3197 LLViewerObject* object = node->getObject();
3406 if(buy->mObjectsSent.find(object) == LLDynamicArray<LLViewerObject*>::FAIL) 3198 if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end())
3407 { 3199 {
3408 buy->mObjectsSent.put(object); 3200 buy->mObjectsSent.push_back(object);
3409 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 3201 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
3410 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() ); 3202 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
3411 gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType()); 3203 gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType());
@@ -3480,7 +3272,6 @@ void LLSelectMgr::deselectAll()
3480 mLastSentSelectionCenterGlobal.clearVec(); 3272 mLastSentSelectionCenterGlobal.clearVec();
3481 3273
3482 updatePointAt(); 3274 updatePointAt();
3483 updateSelectionCenter();
3484} 3275}
3485 3276
3486void LLSelectMgr::deselectUnused() 3277void LLSelectMgr::deselectUnused()
@@ -3494,7 +3285,6 @@ void LLSelectMgr::deselectUnused()
3494 3285
3495void LLSelectMgr::convertTransient() 3286void LLSelectMgr::convertTransient()
3496{ 3287{
3497 // use STL-style iteration to avoid recursive iteration problems
3498 LLObjectSelection::iterator node_it; 3288 LLObjectSelection::iterator node_it;
3499 for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it) 3289 for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it)
3500 { 3290 {
@@ -3772,32 +3562,42 @@ void LLSelectMgr::packHingeHead(void *user_data)
3772 3562
3773void LLSelectMgr::selectionDump() 3563void LLSelectMgr::selectionDump()
3774{ 3564{
3775 LLViewerObject *object; 3565 struct f : public LLSelectedObjectFunctor
3776
3777 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
3778 { 3566 {
3779 object->dump(); 3567 virtual bool apply(LLViewerObject* object)
3780 } 3568 {
3569 object->dump();
3570 return true;
3571 }
3572 } func;
3573 getSelection()->applyToObjects(&func);
3781} 3574}
3782 3575
3783void LLSelectMgr::saveSelectedObjectColors() 3576void LLSelectMgr::saveSelectedObjectColors()
3784{ 3577{
3785 LLSelectNode* selectNode; 3578 struct f : public LLSelectedNodeFunctor
3786 for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode() )
3787 { 3579 {
3788 selectNode->saveColors(); 3580 virtual bool apply(LLSelectNode* node)
3789 } 3581 {
3582 node->saveColors();
3583 return true;
3584 }
3585 } func;
3586 getSelection()->applyToNodes(&func);
3790} 3587}
3791 3588
3792void LLSelectMgr::saveSelectedObjectTextures() 3589void LLSelectMgr::saveSelectedObjectTextures()
3793{ 3590{
3794 LLSelectNode* selectNode;
3795
3796 // invalidate current selection so we update saved textures 3591 // invalidate current selection so we update saved textures
3797 for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode() ) 3592 struct f : public LLSelectedNodeFunctor
3798 { 3593 {
3799 selectNode->mValid = FALSE; 3594 virtual bool apply(LLSelectNode* node)
3800 } 3595 {
3596 node->mValid = FALSE;
3597 return true;
3598 }
3599 } func;
3600 getSelection()->applyToNodes(&func);
3801 3601
3802 // request object properties message to get updated permissions data 3602 // request object properties message to get updated permissions data
3803 sendSelect(); 3603 sendSelect();
@@ -3808,113 +3608,95 @@ void LLSelectMgr::saveSelectedObjectTextures()
3808// also need to know to which simulator to send update message 3608// also need to know to which simulator to send update message
3809void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type) 3609void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
3810{ 3610{
3811 LLSelectNode* selectNode;
3812
3813 if (mSelectedObjects->isEmpty()) 3611 if (mSelectedObjects->isEmpty())
3814 { 3612 {
3815 // nothing selected, so nothing to save 3613 // nothing selected, so nothing to save
3816 return; 3614 return;
3817 } 3615 }
3818 3616
3819 for (selectNode = mSelectedObjects->getFirstNode(); selectNode; selectNode = mSelectedObjects->getNextNode() ) 3617 struct f : public LLSelectedNodeFunctor
3820 { 3618 {
3821 LLViewerObject* object; 3619 EActionType mActionType;
3822 object = selectNode->getObject(); 3620 f(EActionType a) : mActionType(a) {}
3823 selectNode->mSavedPositionLocal = object->getPosition(); 3621 virtual bool apply(LLSelectNode* selectNode)
3824 if (object->isAttachment())
3825 { 3622 {
3826 if (object->isRootEdit()) 3623 LLViewerObject* object = selectNode->getObject();
3624 selectNode->mSavedPositionLocal = object->getPosition();
3625 if (object->isAttachment())
3827 { 3626 {
3828 LLXform* parent_xform = object->mDrawable->getXform()->getParent(); 3627 if (object->isRootEdit())
3829 if (parent_xform)
3830 { 3628 {
3831 selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition()); 3629 LLXform* parent_xform = object->mDrawable->getXform()->getParent();
3630 if (parent_xform)
3631 {
3632 selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition());
3633 }
3832 } 3634 }
3635 else
3636 {
3637 LLViewerObject* attachment_root = (LLViewerObject*)object->getParent();
3638 LLXform* parent_xform = attachment_root->mDrawable->getXform()->getParent();
3639 LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
3640 LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation());
3641 selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos);
3642 }
3643 selectNode->mSavedRotation = object->getRenderRotation();
3833 } 3644 }
3834 else 3645 else
3835 { 3646 {
3836 LLViewerObject* attachment_root = (LLViewerObject*)object->getParent(); 3647 selectNode->mSavedPositionGlobal = object->getPositionGlobal();
3837 LLXform* parent_xform = attachment_root->mDrawable->getXform()->getParent(); 3648 selectNode->mSavedRotation = object->getRotationRegion();
3838 LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
3839 LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation());
3840 selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos);
3841 } 3649 }
3842 selectNode->mSavedRotation = object->getRenderRotation();
3843 }
3844 else
3845 {
3846 selectNode->mSavedPositionGlobal = object->getPositionGlobal();
3847 selectNode->mSavedRotation = object->getRotationRegion();
3848 }
3849 3650
3850 selectNode->mSavedScale = object->getScale(); 3651 selectNode->mSavedScale = object->getScale();
3851 selectNode->saveTextureScaleRatios(); 3652 selectNode->saveTextureScaleRatios();
3852 3653 return true;
3853 } 3654 }
3655 } func(action_type);
3656 getSelection()->applyToNodes(&func);
3657
3854 mSavedSelectionBBox = getBBoxOfSelection(); 3658 mSavedSelectionBBox = getBBoxOfSelection();
3855} 3659}
3856 3660
3857void LLSelectMgr::selectionUpdatePhysics(BOOL physics) 3661struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor
3858{ 3662{
3859 LLViewerObject *object; 3663 LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {}
3860 3664 U32 mFlags;
3861 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 3665 BOOL mState;
3666 virtual bool apply(LLViewerObject* object)
3862 { 3667 {
3863 if ( !object->permModify() // preemptive permissions check 3668 if ( object->permModify() && // preemptive permissions check
3864 || !(object->isRoot() // don't send for child objects 3669 object->isRoot() && // don't send for child objects
3865 || object->isJointChild())) 3670 !object->isJointChild())
3866 { 3671 {
3867 continue; 3672 object->setFlags( mFlags, mState);
3868 } 3673 }
3869 object->setFlags( FLAGS_USE_PHYSICS, physics); 3674 return true;
3870 } 3675 }
3676};
3677
3678void LLSelectMgr::selectionUpdatePhysics(BOOL physics)
3679{
3680 LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics);
3681 getSelection()->applyToObjects(&func);
3871} 3682}
3872 3683
3873void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary) 3684void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary)
3874{ 3685{
3875 LLViewerObject *object; 3686 LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary);
3876 3687 getSelection()->applyToObjects(&func);
3877 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
3878 {
3879 if ( !object->permModify() // preemptive permissions check
3880 || !(object->isRoot() // don't send for child objects
3881 || object->isJointChild()))
3882 {
3883 continue;
3884 }
3885 object->setFlags( FLAGS_TEMPORARY_ON_REZ, is_temporary);
3886 }
3887} 3688}
3888 3689
3889void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom) 3690void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom)
3890{ 3691{
3891 LLViewerObject *object; 3692 LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom);
3892 3693 getSelection()->applyToObjects(&func);
3893 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
3894 {
3895 if ( !object->permModify() // preemptive permissions check
3896 || !(object->isRoot() // don't send for child objects
3897 || object->isJointChild()))
3898 {
3899 continue;
3900 }
3901 object->setFlags( FLAGS_PHANTOM, is_phantom);
3902 }
3903} 3694}
3904 3695
3905void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows) 3696void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows)
3906{ 3697{
3907 LLViewerObject *object; 3698 LLSelectMgrApplyFlags func( FLAGS_CAST_SHADOWS, cast_shadows);
3908 3699 getSelection()->applyToObjects(&func);
3909 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() )
3910 {
3911 if ( !object->permModify() // preemptive permissions check
3912 || object->isJointChild())
3913 {
3914 continue;
3915 }
3916 object->setFlags( FLAGS_CAST_SHADOWS, cast_shadows);
3917 }
3918} 3700}
3919 3701
3920 3702
@@ -4042,6 +3824,13 @@ void LLSelectMgr::packObjectClickAction(LLSelectNode* node, void *user_data)
4042 gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction()); 3824 gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction());
4043} 3825}
4044 3826
3827void LLSelectMgr::packObjectIncludeInSearch(LLSelectNode* node, void *user_data)
3828{
3829 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
3830 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
3831 gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch());
3832}
3833
4045// static 3834// static
4046void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *) 3835void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *)
4047{ 3836{
@@ -4130,82 +3919,81 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name,
4130 S32 packets_sent = 0; 3919 S32 packets_sent = 0;
4131 S32 objects_in_this_packet = 0; 3920 S32 objects_in_this_packet = 0;
4132 3921
4133
4134 //clear update override data (allow next update through) 3922 //clear update override data (allow next update through)
4135 for (node = mSelectedObjects->getFirstNode(); 3923 struct f : public LLSelectedNodeFunctor
4136 node;
4137 node = mSelectedObjects->getNextNode())
4138 { 3924 {
4139 node->mLastPositionLocal.setVec(0,0,0); 3925 virtual bool apply(LLSelectNode* node)
4140 node->mLastRotation = LLQuaternion(); 3926 {
4141 node->mLastScale.setVec(0,0,0); 3927 node->mLastPositionLocal.setVec(0,0,0);
4142 } 3928 node->mLastRotation = LLQuaternion();
3929 node->mLastScale.setVec(0,0,0);
3930 return true;
3931 }
3932 } func;
3933 getSelection()->applyToNodes(&func);
4143 3934
4144 std::queue<LLSelectNode*> nodes_to_send; 3935 std::queue<LLSelectNode*> nodes_to_send;
4145 3936
4146 switch(send_type) 3937 struct push_all : public LLSelectedNodeFunctor
4147 { 3938 {
4148 case SEND_ONLY_ROOTS: 3939 std::queue<LLSelectNode*>& nodes_to_send;
4149 node = mSelectedObjects->getFirstRootNode(); 3940 push_all(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
4150 while(node) 3941 virtual bool apply(LLSelectNode* node)
4151 {
4152 nodes_to_send.push(node);
4153 node = mSelectedObjects->getNextRootNode();
4154 }
4155 break;
4156 case SEND_INDIVIDUALS:
4157 node = mSelectedObjects->getFirstNode();
4158 while(node)
4159 { 3942 {
4160 nodes_to_send.push(node); 3943 nodes_to_send.push(node);
4161 node = mSelectedObjects->getNextNode(); 3944 return true;
4162 } 3945 }
4163 break; 3946 };
4164 case SEND_ROOTS_FIRST: 3947 struct push_some : public LLSelectedNodeFunctor
4165 // first roots... 3948 {
4166 node = mSelectedObjects->getFirstNode(); 3949 std::queue<LLSelectNode*>& nodes_to_send;
4167 while(node) 3950 bool mRoots;
3951 push_some(std::queue<LLSelectNode*>& n, bool roots) : nodes_to_send(n), mRoots(roots) {}
3952 virtual bool apply(LLSelectNode* node)
4168 { 3953 {
4169 if (node->getObject()->isRootEdit()) 3954 BOOL is_root = node->getObject()->isRootEdit();
3955 if ((mRoots && is_root) || (!mRoots && !is_root))
4170 { 3956 {
4171 nodes_to_send.push(node); 3957 nodes_to_send.push(node);
4172 } 3958 }
4173 node = mSelectedObjects->getNextNode(); 3959 return true;
4174 } 3960 }
4175 3961 };
4176 // then children... 3962 struct push_editable : public LLSelectedNodeFunctor
4177 node = mSelectedObjects->getFirstNode(); 3963 {
4178 while(node) 3964 std::queue<LLSelectNode*>& nodes_to_send;
3965 push_editable(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
3966 virtual bool apply(LLSelectNode* node)
4179 { 3967 {
4180 if (!node->getObject()->isRootEdit()) 3968
4181 { 3969 nodes_to_send.push(node);
4182 nodes_to_send.push(node); 3970 return true;
4183 }
4184 node = mSelectedObjects->getNextNode();
4185 } 3971 }
3972 };
3973 struct push_all pushall(nodes_to_send);
3974 struct push_some pushroots(nodes_to_send, TRUE);
3975 struct push_some pushnonroots(nodes_to_send, FALSE);
3976 struct push_editable pusheditable(nodes_to_send);
3977
3978 switch(send_type)
3979 {
3980 case SEND_ONLY_ROOTS:
3981 getSelection()->applyToRootNodes(&pusheditable);
4186 break; 3982 break;
4187 case SEND_CHILDREN_FIRST: 3983 case SEND_INDIVIDUALS:
3984 getSelection()->applyToNodes(&pushall);
3985 break;
3986 case SEND_ROOTS_FIRST:
3987 // first roots...
3988 getSelection()->applyToNodes(&pushroots);
3989 // then children...
3990 getSelection()->applyToNodes(&pushnonroots);
3991 break;
3992 case SEND_CHILDREN_FIRST:
4188 // first children... 3993 // first children...
4189 node = mSelectedObjects->getFirstNode(); 3994 getSelection()->applyToNodes(&pushnonroots);
4190 while(node) 3995 // then roots...
4191 { 3996 getSelection()->applyToNodes(&pushroots);
4192 if (!node->getObject()->isRootEdit())
4193 {
4194 nodes_to_send.push(node);
4195 }
4196 node = mSelectedObjects->getNextNode();
4197 }
4198
4199 // ...then roots
4200 node = mSelectedObjects->getFirstNode();
4201 while(node)
4202 {
4203 if (node->getObject()->isRootEdit())
4204 {
4205 nodes_to_send.push(node);
4206 }
4207 node = mSelectedObjects->getNextNode();
4208 }
4209 break; 3997 break;
4210 3998
4211 default: 3999 default:
@@ -4213,8 +4001,11 @@ void LLSelectMgr::sendListToRegions(const LLString& message_name,
4213 } 4001 }
4214 4002
4215 // bail if nothing selected 4003 // bail if nothing selected
4216 if (nodes_to_send.empty()) return; 4004 if (nodes_to_send.empty())
4217 4005 {
4006 return;
4007 }
4008
4218 node = nodes_to_send.front(); 4009 node = nodes_to_send.front();
4219 nodes_to_send.pop(); 4010 nodes_to_send.pop();
4220 4011
@@ -4376,27 +4167,24 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
4376 4167
4377 for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES) 4168 for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES)
4378 { 4169 {
4379 LLUUID id; 4170 LLUUID tid;
4380 memcpy(id.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */ 4171 memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */
4381 texture_ids.push_back(id); 4172 texture_ids.push_back(tid);
4382 } 4173 }
4383 } 4174 }
4384 4175
4385 4176
4386 // Iterate through nodes at end, since it can be on both the regular AND hover list 4177 // Iterate through nodes at end, since it can be on both the regular AND hover list
4387 BOOL found = FALSE; 4178 struct f : public LLSelectedNodeFunctor
4388 LLSelectNode* node;
4389 for (node = gSelectMgr->mSelectedObjects->getFirstNode();
4390 node;
4391 node = gSelectMgr->mSelectedObjects->getNextNode())
4392 { 4179 {
4393 if (node->getObject()->mID == id) 4180 LLUUID mID;
4181 f(const LLUUID& id) : mID(id) {}
4182 virtual bool apply(LLSelectNode* node)
4394 { 4183 {
4395 found = TRUE; 4184 return (node->getObject()->mID == mID);
4396 break;
4397 } 4185 }
4398 } 4186 } func(id);
4399 4187 LLSelectNode* node = gSelectMgr->getSelection()->getFirstNode(&func);
4400 4188
4401 if (node) 4189 if (node)
4402 { 4190 {
@@ -4529,23 +4317,21 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use
4529 LLString fullname(first_name); 4317 LLString fullname(first_name);
4530 fullname.append(" "); 4318 fullname.append(" ");
4531 fullname.append(last_name); 4319 fullname.append(last_name);
4532 reporterp->setPickedObjectProperties(name, fullname.c_str(), owner_id); 4320 reporterp->setPickedObjectProperties(name, fullname, owner_id);
4533 } 4321 }
4534 } 4322 }
4535 4323
4536 // Now look through all of the hovered nodes 4324 // Now look through all of the hovered nodes
4537 BOOL found = FALSE; 4325 struct f : public LLSelectedNodeFunctor
4538 LLSelectNode* node;
4539 for (node = gSelectMgr->mHoverObjects->getFirstNode();
4540 node;
4541 node = gSelectMgr->mHoverObjects->getNextNode())
4542 { 4326 {
4543 if (node->getObject()->mID == id) 4327 LLUUID mID;
4328 f(const LLUUID& id) : mID(id) {}
4329 virtual bool apply(LLSelectNode* node)
4544 { 4330 {
4545 found = TRUE; 4331 return (node->getObject()->mID == mID);
4546 break;
4547 } 4332 }
4548 } 4333 } func(id);
4334 LLSelectNode* node = gSelectMgr->getHoverObjects()->getFirstNode(&func);
4549 4335
4550 if (node) 4336 if (node)
4551 { 4337 {
@@ -4577,7 +4363,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)
4577 LLUUID full_id; 4363 LLUUID full_id;
4578 S32 local_id; 4364 S32 local_id;
4579 LLViewerObject* object; 4365 LLViewerObject* object;
4580 LLDynamicArray<LLViewerObject*> objects; 4366 std::vector<LLViewerObject*> objects;
4581 S32 i; 4367 S32 i;
4582 S32 block_count = msg->getNumberOfBlocks("Data"); 4368 S32 block_count = msg->getNumberOfBlocks("Data");
4583 4369
@@ -4592,7 +4378,7 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)
4592 object = gObjectList.findObject(full_id); 4378 object = gObjectList.findObject(full_id);
4593 if (object) 4379 if (object)
4594 { 4380 {
4595 objects.put(object); 4381 objects.push_back(object);
4596 } 4382 }
4597 } 4383 }
4598 4384
@@ -4605,7 +4391,6 @@ extern LLGLdouble gGLModelView[16];
4605 4391
4606void LLSelectMgr::updateSilhouettes() 4392void LLSelectMgr::updateSilhouettes()
4607{ 4393{
4608 LLSelectNode *node;
4609 S32 num_sils_genned = 0; 4394 S32 num_sils_genned = 0;
4610 4395
4611 LLVector3d cameraPos = gAgent.getCameraPositionGlobal(); 4396 LLVector3d cameraPos = gAgent.getCameraPositionGlobal();
@@ -4618,21 +4403,24 @@ void LLSelectMgr::updateSilhouettes()
4618 mSilhouetteImagep = gImageList.getImage(id, TRUE, TRUE); 4403 mSilhouetteImagep = gImageList.getImage(id, TRUE, TRUE);
4619 } 4404 }
4620 4405
4406 mHighlightedObjects->cleanupNodes();
4621 4407
4622 if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom) 4408 if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom)
4623 { 4409 {
4624 for (node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) 4410 struct f : public LLSelectedObjectFunctor
4625 { 4411 {
4626 if (node->getObject()) 4412 virtual bool apply(LLViewerObject* object)
4627 { 4413 {
4628 node->getObject()->setChanged(LLXform::SILHOUETTE); 4414 object->setChanged(LLXform::SILHOUETTE);
4415 return true;
4629 } 4416 }
4630 } 4417 } func;
4418 getSelection()->applyToObjects(&func);
4631 4419
4632 mLastCameraPos = gAgent.getCameraPositionGlobal(); 4420 mLastCameraPos = gAgent.getCameraPositionGlobal();
4633 } 4421 }
4634 4422
4635 LLDynamicArray<LLViewerObject*> changed_objects; 4423 std::vector<LLViewerObject*> changed_objects;
4636 4424
4637 if (mSelectedObjects->getNumNodes()) 4425 if (mSelectedObjects->getNumNodes())
4638 { 4426 {
@@ -4643,8 +4431,10 @@ void LLSelectMgr::updateSilhouettes()
4643 4431
4644 for (S32 pass = 0; pass < 2; pass++) 4432 for (S32 pass = 0; pass < 2; pass++)
4645 { 4433 {
4646 for (node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) 4434 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
4435 iter != mSelectedObjects->end(); iter++)
4647 { 4436 {
4437 LLSelectNode* node = *iter;
4648 LLViewerObject* objectp = node->getObject(); 4438 LLViewerObject* objectp = node->getObject();
4649 4439
4650 // do roots first, then children so that root flags are cleared ASAP 4440 // do roots first, then children so that root flags are cleared ASAP
@@ -4662,7 +4452,7 @@ void LLSelectMgr::updateSilhouettes()
4662 if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible()) 4452 if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible())
4663 { 4453 {
4664 generateSilhouette(node, gCamera->getOrigin()); 4454 generateSilhouette(node, gCamera->getOrigin());
4665 changed_objects.put(objectp); 4455 changed_objects.push_back(objectp);
4666 } 4456 }
4667 else if (objectp->isAttachment()) 4457 else if (objectp->isAttachment())
4668 { 4458 {
@@ -4711,20 +4501,23 @@ void LLSelectMgr::updateSilhouettes()
4711 } 4501 }
4712 4502
4713 // remove highlight nodes not in roots list 4503 // remove highlight nodes not in roots list
4714 LLDynamicArray<LLSelectNode*> remove_these_nodes; 4504 std::vector<LLSelectNode*> remove_these_nodes;
4715 LLDynamicArray<LLViewerObject*> remove_these_roots; 4505 std::vector<LLViewerObject*> remove_these_roots;
4716 for (LLSelectNode* nodep = mHighlightedObjects->getFirstNode(); nodep; nodep = mHighlightedObjects->getNextNode()) 4506
4507 for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
4508 iter != mHighlightedObjects->end(); iter++)
4717 { 4509 {
4718 LLViewerObject* objectp = nodep->getObject(); 4510 LLSelectNode* node = *iter;
4511 LLViewerObject* objectp = node->getObject();
4719 if (objectp->isRoot() || !select_linked_set) 4512 if (objectp->isRoot() || !select_linked_set)
4720 { 4513 {
4721 if (roots.count(objectp) == 0) 4514 if (roots.count(objectp) == 0)
4722 { 4515 {
4723 remove_these_nodes.put(nodep); 4516 remove_these_nodes.push_back(node);
4724 } 4517 }
4725 else 4518 else
4726 { 4519 {
4727 remove_these_roots.put(objectp); 4520 remove_these_roots.push_back(objectp);
4728 } 4521 }
4729 } 4522 }
4730 else 4523 else
@@ -4733,22 +4526,25 @@ void LLSelectMgr::updateSilhouettes()
4733 4526
4734 if (roots.count(rootp) == 0) 4527 if (roots.count(rootp) == 0)
4735 { 4528 {
4736 remove_these_nodes.put(nodep); 4529 remove_these_nodes.push_back(node);
4737 } 4530 }
4738 } 4531 }
4739 } 4532 }
4740 4533
4741 // remove all highlight nodes no longer in rectangle selection 4534 // remove all highlight nodes no longer in rectangle selection
4742 S32 i; 4535 for (std::vector<LLSelectNode*>::iterator iter = remove_these_nodes.begin();
4743 for (i = 0; i < remove_these_nodes.count(); i++) 4536 iter != remove_these_nodes.end(); ++iter)
4744 { 4537 {
4745 mHighlightedObjects->removeNode(remove_these_nodes[i]); 4538 LLSelectNode* nodep = *iter;
4539 mHighlightedObjects->removeNode(nodep);
4746 } 4540 }
4747 4541
4748 // remove all root objects already being highlighted 4542 // remove all root objects already being highlighted
4749 for (i = 0; i < remove_these_roots.count(); i++) 4543 for (std::vector<LLViewerObject*>::iterator iter = remove_these_roots.begin();
4544 iter != remove_these_roots.end(); ++iter)
4750 { 4545 {
4751 roots.erase(remove_these_roots[i]); 4546 LLViewerObject* objectp = *iter;
4547 roots.erase(objectp);
4752 } 4548 }
4753 4549
4754 // add all new objects in rectangle selection 4550 // add all new objects in rectangle selection
@@ -4756,36 +4552,38 @@ void LLSelectMgr::updateSilhouettes()
4756 iter != roots.end(); iter++) 4552 iter != roots.end(); iter++)
4757 { 4553 {
4758 LLViewerObject* objectp = *iter; 4554 LLViewerObject* objectp = *iter;
4759 LLSelectNode* rect_select_node = new LLSelectNode(objectp, TRUE); 4555 LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
4760 rect_select_node->selectAllTEs(TRUE); 4556 rect_select_root_node->selectAllTEs(TRUE);
4761 4557
4762 if (!canSelectObject(objectp)) 4558 if (!canSelectObject(objectp))
4763 { 4559 {
4764 continue; 4560 continue;
4765 } 4561 }
4766 4562
4767 mHighlightedObjects->addNode(rect_select_node);
4768
4769 if (!select_linked_set) 4563 if (!select_linked_set)
4770 { 4564 {
4771 rect_select_node->mIndividualSelection = TRUE; 4565 rect_select_root_node->mIndividualSelection = TRUE;
4772 } 4566 }
4773 else 4567 else
4774 { 4568 {
4775 for (U32 i = 0; i < objectp->mChildList.size(); i++) 4569 for (LLViewerObject::child_list_t::iterator iter = objectp->mChildList.begin();
4570 iter != objectp->mChildList.end(); ++iter)
4776 { 4571 {
4777 LLViewerObject* child_objectp = objectp->mChildList[i]; 4572 LLViewerObject* child_objectp = *iter;
4778 4573
4779 if (!canSelectObject(child_objectp)) 4574 if (!canSelectObject(child_objectp))
4780 { 4575 {
4781 continue; 4576 continue;
4782 } 4577 }
4783 4578
4784 rect_select_node = new LLSelectNode(objectp->mChildList[i], TRUE); 4579 LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE);
4785 rect_select_node->selectAllTEs(TRUE); 4580 rect_select_node->selectAllTEs(TRUE);
4786 mHighlightedObjects->addNode(rect_select_node); 4581 mHighlightedObjects->addNodeAtEnd(rect_select_node);
4787 } 4582 }
4788 } 4583 }
4584
4585 // Add the root last, to preserve order for link operations.
4586 mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
4789 } 4587 }
4790 4588
4791 num_sils_genned = 0; 4589 num_sils_genned = 0;
@@ -4794,8 +4592,10 @@ void LLSelectMgr::updateSilhouettes()
4794 //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); 4592 //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
4795 for (S32 pass = 0; pass < 2; pass++) 4593 for (S32 pass = 0; pass < 2; pass++)
4796 { 4594 {
4797 for (node = mHighlightedObjects->getFirstNode(); node; node = mHighlightedObjects->getNextNode() ) 4595 for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
4596 iter != mHighlightedObjects->end(); iter++)
4798 { 4597 {
4598 LLSelectNode* node = *iter;
4799 LLViewerObject* objectp = node->getObject(); 4599 LLViewerObject* objectp = node->getObject();
4800 4600
4801 // do roots first, then children so that root flags are cleared ASAP 4601 // do roots first, then children so that root flags are cleared ASAP
@@ -4813,7 +4613,7 @@ void LLSelectMgr::updateSilhouettes()
4813 if (num_sils_genned++ < MAX_SILS_PER_FRAME) 4613 if (num_sils_genned++ < MAX_SILS_PER_FRAME)
4814 { 4614 {
4815 generateSilhouette(node, gCamera->getOrigin()); 4615 generateSilhouette(node, gCamera->getOrigin());
4816 changed_objects.put(objectp); 4616 changed_objects.push_back(objectp);
4817 } 4617 }
4818 else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull()) 4618 else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull())
4819 { 4619 {
@@ -4846,10 +4646,12 @@ void LLSelectMgr::updateSilhouettes()
4846 mHighlightedObjects->deleteAllNodes(); 4646 mHighlightedObjects->deleteAllNodes();
4847 } 4647 }
4848 4648
4849 for (S32 i = 0; i < changed_objects.count(); i++) 4649 for (std::vector<LLViewerObject*>::iterator iter = changed_objects.begin();
4650 iter != changed_objects.end(); ++iter)
4850 { 4651 {
4851 // clear flags after traversing node list (as child objects need to refer to parent flags, etc) 4652 // clear flags after traversing node list (as child objects need to refer to parent flags, etc)
4852 changed_objects[i]->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE); 4653 LLViewerObject* objectp = *iter;
4654 objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE);
4853 } 4655 }
4854 4656
4855 //glAlphaFunc(GL_GREATER, 0.01f); 4657 //glAlphaFunc(GL_GREATER, 0.01f);
@@ -4862,8 +4664,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
4862 return; 4664 return;
4863 } 4665 }
4864 4666
4865 LLSelectNode *node; 4667 LLViewerImage::bindTexture(mSilhouetteImagep);
4866 LLViewerImage::bindTexture(gSelectMgr->mSilhouetteImagep);
4867 LLGLSPipelineSelection gls_select; 4668 LLGLSPipelineSelection gls_select;
4868 glAlphaFunc(GL_GREATER, 0.0f); 4669 glAlphaFunc(GL_GREATER, 0.0f);
4869 LLGLEnable blend(GL_BLEND); 4670 LLGLEnable blend(GL_BLEND);
@@ -4895,8 +4696,10 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
4895 LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID(); 4696 LLUUID inspect_item_id = LLFloaterInspect::getSelectedUUID();
4896 for (S32 pass = 0; pass < 2; pass++) 4697 for (S32 pass = 0; pass < 2; pass++)
4897 { 4698 {
4898 for (node = mSelectedObjects->getFirstNode(); node; node = mSelectedObjects->getNextNode() ) 4699 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
4700 iter != mSelectedObjects->end(); iter++)
4899 { 4701 {
4702 LLSelectNode* node = *iter;
4900 LLViewerObject* objectp = node->getObject(); 4703 LLViewerObject* objectp = node->getObject();
4901 if (objectp->isHUDAttachment() != for_hud) 4704 if (objectp->isHUDAttachment() != for_hud)
4902 { 4705 {
@@ -4931,8 +4734,10 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
4931 BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL); 4734 BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
4932 for (S32 pass = 0; pass < 2; pass++) 4735 for (S32 pass = 0; pass < 2; pass++)
4933 { 4736 {
4934 for (node = mHighlightedObjects->getFirstNode(); node; node = mHighlightedObjects->getNextNode() ) 4737 for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
4738 iter != mHighlightedObjects->end(); iter++)
4935 { 4739 {
4740 LLSelectNode* node = *iter;
4936 LLViewerObject* objectp = node->getObject(); 4741 LLViewerObject* objectp = node->getObject();
4937 if (objectp->isHUDAttachment() != for_hud) 4742 if (objectp->isHUDAttachment() != for_hud)
4938 { 4743 {
@@ -4962,7 +4767,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
4962 stop_glerror(); 4767 stop_glerror();
4963 } 4768 }
4964 4769
4965 gSelectMgr->mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D); 4770 mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
4966 glAlphaFunc(GL_GREATER, 0.01f); 4771 glAlphaFunc(GL_GREATER, 0.01f);
4967} 4772}
4968 4773
@@ -5091,7 +4896,7 @@ S32 LLSelectNode::getLastSelectedTE()
5091 return mLastTESelected; 4896 return mLastTESelected;
5092} 4897}
5093 4898
5094LLViewerObject *LLSelectNode::getObject() 4899LLViewerObject* LLSelectNode::getObject()
5095{ 4900{
5096 if (!mObject) 4901 if (!mObject)
5097 { 4902 {
@@ -5104,6 +4909,11 @@ LLViewerObject *LLSelectNode::getObject()
5104 return mObject; 4909 return mObject;
5105} 4910}
5106 4911
4912void LLSelectNode::setObject(LLViewerObject* object)
4913{
4914 mObject = object;
4915}
4916
5107void LLSelectNode::saveColors() 4917void LLSelectNode::saveColors()
5108{ 4918{
5109 if (mObject.notNull()) 4919 if (mObject.notNull())
@@ -5123,8 +4933,8 @@ void LLSelectNode::saveTextures(const std::vector<LLUUID>& textures)
5123 { 4933 {
5124 mSavedTextures.clear(); 4934 mSavedTextures.clear();
5125 4935
5126 std::vector<LLUUID>::const_iterator texture_it; 4936 for (std::vector<LLUUID>::const_iterator texture_it = textures.begin();
5127 for (texture_it = textures.begin(); texture_it != textures.end(); ++texture_it) 4937 texture_it != textures.end(); ++texture_it)
5128 { 4938 {
5129 mSavedTextures.push_back(*texture_it); 4939 mSavedTextures.push_back(*texture_it);
5130 } 4940 }
@@ -5144,7 +4954,7 @@ void LLSelectNode::saveTextureScaleRatios()
5144 U32 s_axis = 0; 4954 U32 s_axis = 0;
5145 U32 t_axis = 0; 4955 U32 t_axis = 0;
5146 4956
5147 gSelectMgr->getTESTAxes(mObject, i, &s_axis, &t_axis); 4957 LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
5148 4958
5149 LLVector3 v; 4959 LLVector3 v;
5150 LLVector3 scale = mObject->getScale(); 4960 LLVector3 scale = mObject->getScale();
@@ -5440,9 +5250,10 @@ S32 get_family_count(LLViewerObject *parent)
5440 llwarns << "Trying to get_family_count on null parent!" << llendl; 5250 llwarns << "Trying to get_family_count on null parent!" << llendl;
5441 } 5251 }
5442 S32 count = 1; // for this object 5252 S32 count = 1; // for this object
5443 for (U32 i = 0; i < parent->mChildList.size(); i++) 5253 for (LLViewerObject::child_list_t::iterator iter = parent->mChildList.begin();
5254 iter != parent->mChildList.end(); ++iter)
5444 { 5255 {
5445 LLViewerObject* child = parent->mChildList[i]; 5256 LLViewerObject* child = *iter;
5446 5257
5447 if (!child) 5258 if (!child)
5448 { 5259 {
@@ -5473,7 +5284,7 @@ void LLSelectMgr::updateSelectionCenter()
5473 5284
5474 //override any object updates received 5285 //override any object updates received
5475 //for selected objects 5286 //for selected objects
5476 gSelectMgr->overrideObjectUpdates(); 5287 overrideObjectUpdates();
5477 5288
5478 LLViewerObject* object = mSelectedObjects->getFirstObject(); 5289 LLViewerObject* object = mSelectedObjects->getFirstObject();
5479 if (!object) 5290 if (!object)
@@ -5484,11 +5295,8 @@ void LLSelectMgr::updateSelectionCenter()
5484 mShowSelection = FALSE; 5295 mShowSelection = FALSE;
5485 mSelectionBBox = LLBBox(); 5296 mSelectionBBox = LLBBox();
5486 mPauseRequest = NULL; 5297 mPauseRequest = NULL;
5487 if (gAgent.getAvatarObject()) 5298 resetAgentHUDZoom();
5488 { 5299
5489 gAgent.getAvatarObject()->mHUDTargetZoom = 1.f;
5490 gAgent.getAvatarObject()->mHUDCurZoom = 1.f;
5491 }
5492 } 5300 }
5493 else 5301 else
5494 { 5302 {
@@ -5517,10 +5325,13 @@ void LLSelectMgr::updateSelectionCenter()
5517 LLVector3d select_center; 5325 LLVector3d select_center;
5518 // keep a list of jointed objects for showing the joint HUDEffects 5326 // keep a list of jointed objects for showing the joint HUDEffects
5519 5327
5520 LLDynamicArray < LLViewerObject *> jointed_objects; 5328 std::vector < LLViewerObject *> jointed_objects;
5521 5329
5522 for (object = mSelectedObjects->getFirstObject(); object; object = mSelectedObjects->getNextObject() ) 5330 for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
5331 iter != mSelectedObjects->end(); iter++)
5523 { 5332 {
5333 LLSelectNode* node = *iter;
5334 LLViewerObject* object = node->getObject();
5524 LLViewerObject *myAvatar = gAgent.getAvatarObject(); 5335 LLViewerObject *myAvatar = gAgent.getAvatarObject();
5525 LLViewerObject *root = object->getRootEdit(); 5336 LLViewerObject *root = object->getRootEdit();
5526 if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment 5337 if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment
@@ -5534,9 +5345,9 @@ void LLSelectMgr::updateSelectionCenter()
5534 5345
5535 if (object->isJointChild()) 5346 if (object->isJointChild())
5536 { 5347 {
5537 jointed_objects.put(object); 5348 jointed_objects.push_back(object);
5538 } 5349 }
5539 } // end for 5350 }
5540 5351
5541 LLVector3 bbox_center_agent = bbox.getCenterAgent(); 5352 LLVector3 bbox_center_agent = bbox.getCenterAgent();
5542 mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent); 5353 mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent);
@@ -5666,6 +5477,7 @@ void LLSelectMgr::redo()
5666//----------------------------------------------------------------------------- 5477//-----------------------------------------------------------------------------
5667BOOL LLSelectMgr::canDoDelete() 5478BOOL LLSelectMgr::canDoDelete()
5668{ 5479{
5480 // Note: Can only delete root objects (see getFirstDeleteableObject() for more info)
5669 return mSelectedObjects->getFirstDeleteableObject() != NULL; 5481 return mSelectedObjects->getFirstDeleteableObject() != NULL;
5670} 5482}
5671 5483
@@ -5730,14 +5542,18 @@ ESelectType LLSelectMgr::getSelectTypeForObject(LLViewerObject* object)
5730 5542
5731void LLSelectMgr::validateSelection() 5543void LLSelectMgr::validateSelection()
5732{ 5544{
5733 LLViewerObject* objectp; 5545 struct f : public LLSelectedObjectFunctor
5734 for (objectp = mSelectedObjects->getFirstObject(); objectp; objectp = mSelectedObjects->getNextObject())
5735 { 5546 {
5736 if (!canSelectObject(objectp)) 5547 virtual bool apply(LLViewerObject* object)
5737 { 5548 {
5738 deselectObjectOnly(objectp); 5549 if (!gSelectMgr->canSelectObject(object))
5550 {
5551 gSelectMgr->deselectObjectOnly(object);
5552 }
5553 return true;
5739 } 5554 }
5740 } 5555 } func;
5556 getSelection()->applyToObjects(&func);
5741} 5557}
5742 5558
5743BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) 5559BOOL LLSelectMgr::canSelectObject(LLViewerObject* object)
@@ -5778,419 +5594,114 @@ BOOL LLSelectMgr::setForceSelection(BOOL force)
5778 return force; 5594 return force;
5779} 5595}
5780 5596
5781LLObjectSelection::LLObjectSelection() : 5597void LLSelectMgr::resetAgentHUDZoom()
5782 std::list<LLSelectNode*>(),
5783 LLRefCount(),
5784 mCurrentNode(end()),
5785 mCurrentTE(-1),
5786 mSelectType(SELECT_TYPE_WORLD)
5787{
5788}
5789
5790LLObjectSelection::~LLObjectSelection()
5791{
5792 std::for_each(begin(), end(), DeletePointer());
5793}
5794
5795void LLObjectSelection::updateEffects()
5796{
5797}
5798
5799S32 LLObjectSelection::getNumNodes()
5800{ 5598{
5801 return size(); 5599 if (gAgent.getAvatarObject())
5802}
5803
5804void LLObjectSelection::addNode(LLSelectNode *nodep)
5805{
5806 push_front(nodep);
5807 mSelectNodeMap[nodep->getObject()] = nodep;
5808}
5809
5810void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep)
5811{
5812 push_back(nodep);
5813 mSelectNodeMap[nodep->getObject()] = nodep;
5814}
5815
5816void LLObjectSelection::removeNode(LLSelectNode *nodep)
5817{
5818 std::list<LLSelectNode*>::iterator iter = begin();
5819 while(iter != end())
5820 { 5600 {
5821 if ((*iter) == nodep) 5601 gAgent.getAvatarObject()->mHUDTargetZoom = 1.f;
5822 { 5602 gAgent.getAvatarObject()->mHUDCurZoom = 1.f;
5823 mSelectNodeMap.erase(nodep->getObject());
5824 iter = erase(iter);
5825 }
5826 else
5827 {
5828 ++iter;
5829 }
5830 } 5603 }
5831} 5604}
5832 5605
5833void LLObjectSelection::deleteAllNodes() 5606void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const
5834{
5835 std::for_each(begin(), end(), DeletePointer());
5836 clear();
5837 mSelectNodeMap.clear();
5838}
5839
5840LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp)
5841{ 5607{
5842 std::map<LLPointer<LLViewerObject>, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp); 5608 if (gAgent.getAvatarObject())
5843 if (found_it != mSelectNodeMap.end())
5844 { 5609 {
5845 return found_it->second; 5610 target_zoom = gAgent.getAvatarObject()->mHUDTargetZoom;
5611 current_zoom = gAgent.getAvatarObject()->mHUDCurZoom;
5846 } 5612 }
5847 return NULL;
5848} 5613}
5849 5614
5850//----------------------------------------------------------------------------- 5615void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
5851// getFirstNode()
5852//-----------------------------------------------------------------------------
5853LLSelectNode *LLObjectSelection::getFirstNode()
5854{ 5616{
5855 mCurrentNode = begin();//getFirstData(); 5617 if (gAgent.getAvatarObject())
5856
5857 while (mCurrentNode != end() && !(*mCurrentNode)->getObject())
5858 { 5618 {
5859 // The object on this was killed at some point, delete it. 5619 gAgent.getAvatarObject()->mHUDTargetZoom = target_zoom;
5860 erase(mCurrentNode++); 5620 gAgent.getAvatarObject()->mHUDCurZoom = current_zoom;
5861 } 5621 }
5862
5863 if (mCurrentNode != end())
5864 {
5865 return *mCurrentNode;
5866 }
5867
5868 return NULL;
5869} 5622}
5870 5623
5871//----------------------------------------------------------------------------- 5624LLObjectSelection::LLObjectSelection() :
5872// getCurrentNode() 5625 LLRefCount(),
5873//----------------------------------------------------------------------------- 5626 mSelectType(SELECT_TYPE_WORLD)
5874LLSelectNode *LLObjectSelection::getCurrentNode()
5875{ 5627{
5876 while (mCurrentNode != end() && !(*mCurrentNode)->getObject())
5877 {
5878 // The object on this was killed at some point, delete it.
5879 erase(mCurrentNode++);
5880 }
5881
5882 if (mCurrentNode != end())
5883 {
5884 return *mCurrentNode;
5885 }
5886 return NULL;
5887} 5628}
5888 5629
5889//----------------------------------------------------------------------------- 5630LLObjectSelection::~LLObjectSelection()
5890// getNextNode()
5891//-----------------------------------------------------------------------------
5892LLSelectNode *LLObjectSelection::getNextNode()
5893{ 5631{
5894 ++mCurrentNode; 5632 deleteAllNodes();
5895
5896 while (mCurrentNode != end() && !(*mCurrentNode)->getObject())
5897 {
5898 // The object on this was killed at some point, delete it.
5899 erase(mCurrentNode++);
5900 }
5901
5902 if (mCurrentNode != end())
5903 {
5904 return *mCurrentNode;
5905 }
5906 return NULL;
5907} 5633}
5908 5634
5909 5635void LLObjectSelection::cleanupNodes()
5910
5911//-----------------------------------------------------------------------------
5912// getFirstObject()
5913//-----------------------------------------------------------------------------
5914LLViewerObject* LLObjectSelection::getFirstObject()
5915{ 5636{
5916 mCurrentNode = begin(); 5637 for (list_t::iterator iter = mList.begin(); iter != mList.end(); )
5917
5918 while (mCurrentNode != end() && !(*mCurrentNode)->getObject())
5919 { 5638 {
5920 // The object on this was killed at some point, delete it. 5639 list_t::iterator curiter = iter++;
5921 erase(mCurrentNode++); 5640 LLSelectNode* node = *curiter;
5922 } 5641 if (node->getObject() == NULL || node->getObject()->isDead())
5923 5642 {
5924 if (mCurrentNode != end()) 5643 mList.erase(curiter);
5925 { 5644 delete node;
5926 return (*mCurrentNode)->getObject(); 5645 }
5927 } 5646 }
5928
5929 return NULL;
5930} 5647}
5931 5648
5932 5649void LLObjectSelection::updateEffects()
5933//-----------------------------------------------------------------------------
5934// getNextObject()
5935//-----------------------------------------------------------------------------
5936LLViewerObject* LLObjectSelection::getNextObject()
5937{ 5650{
5938 ++mCurrentNode;// = getNextData();
5939
5940 while (mCurrentNode != end() && !(*mCurrentNode)->getObject())
5941 {
5942 // The object on this was killed at some point, delete it.
5943 erase(mCurrentNode++);
5944 }
5945
5946 if (mCurrentNode != end())
5947 {
5948 return (*mCurrentNode)->getObject();
5949 }
5950
5951 return NULL;
5952} 5651}
5953 5652
5954 5653S32 LLObjectSelection::getNumNodes()
5955
5956//-----------------------------------------------------------------------------
5957// getPrimaryTE()
5958//-----------------------------------------------------------------------------
5959void LLObjectSelection::getPrimaryTE(LLViewerObject* *object, S32 *te)
5960{ 5654{
5961 // initialize object and te 5655 return mList.size();
5962 *te = 0;
5963 *object = NULL;
5964
5965 BOOL searching_roots = TRUE;
5966
5967 // try for root node first, then first child node
5968 LLSelectNode *primary_node = getFirstNode(); //getFirstRootNode();
5969 if (!primary_node)
5970 {
5971 primary_node = getFirstNode();
5972 searching_roots = FALSE;
5973 }
5974
5975 while (primary_node)
5976 {
5977 S32 last_selected_te = primary_node->getLastSelectedTE();
5978 if (last_selected_te >= 0)
5979 {
5980 *object = primary_node->getObject();
5981 *te = last_selected_te;
5982 return;
5983 }
5984 for(S32 cur_te = 0; cur_te < primary_node->getObject()->getNumTEs(); cur_te++)
5985 {
5986 // if face selected
5987 if (primary_node->isTESelected(cur_te))
5988 {
5989 // return this object and face
5990 *object = primary_node->getObject();
5991 *te = cur_te;
5992 return;
5993 }
5994 }
5995 if (searching_roots)
5996 {
5997 primary_node = getNextRootNode();
5998 if (!primary_node)
5999 {
6000 primary_node = getFirstNode();
6001 searching_roots = FALSE;
6002 }
6003 }
6004 else
6005 {
6006 primary_node = getNextNode();
6007 }
6008 }
6009} 5656}
6010 5657
6011//----------------------------------------------------------------------------- 5658void LLObjectSelection::addNode(LLSelectNode *nodep)
6012// getFirstTE()
6013//-----------------------------------------------------------------------------
6014void LLObjectSelection::getFirstTE(LLViewerObject* *object, S32 *te)
6015{ 5659{
6016 // start with first face 5660 llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
6017 mCurrentTE = 0; 5661 mList.push_front(nodep);
6018 5662 mSelectNodeMap[nodep->getObject()] = nodep;
6019 LLSelectNode *cur_node = getFirstNode();
6020
6021 // repeat over all selection nodes
6022 while (cur_node)
6023 {
6024 // skip objects with no faces
6025 if (cur_node->getObject()->getNumTEs() == 0)
6026 {
6027 mCurrentTE = 0;
6028 cur_node = getNextNode();
6029 continue;
6030 }
6031
6032 // repeat over all faces for this object
6033 while (mCurrentTE < cur_node->getObject()->getNumTEs())
6034 {
6035 // if face selected
6036 if (cur_node->isTESelected(mCurrentTE))
6037 {
6038 // return this object and face
6039 *object = cur_node->getObject();
6040 *te = mCurrentTE;
6041 return;
6042 }
6043
6044 mCurrentTE++;
6045 }
6046
6047 // Couldn't find a selected face.
6048 // This can happen if an object's volume parameters are changed in such a way
6049 // that texture entries are eliminated.
6050 //
6051 // TODO: Consider selecting all faces in this case? Subscribe the selection
6052 // list to the volume changing code?
6053
6054 mCurrentTE = 0;
6055 cur_node = getNextNode();
6056 }
6057
6058 // The list doesn't contain any nodes. Return NULL.
6059 *object = NULL;
6060 *te = -1;
6061 return;
6062} 5663}
6063 5664
6064 5665void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep)
6065//-----------------------------------------------------------------------------
6066// getNextFace()
6067//-----------------------------------------------------------------------------
6068void LLObjectSelection::getNextTE(LLViewerObject* *object, S32 *te)
6069{ 5666{
6070 // try next face 5667 llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
6071 mCurrentTE++; 5668 mList.push_back(nodep);
6072 5669 mSelectNodeMap[nodep->getObject()] = nodep;
6073 LLSelectNode *cur_node = getCurrentNode();
6074 // repeat over remaining selection nodes
6075 while ( cur_node )
6076 {
6077 // skip objects with no faces
6078 if (cur_node->getObject()->getNumTEs() == 0)
6079 {
6080 mCurrentTE = 0;
6081 cur_node = getNextNode();
6082 continue;
6083 }
6084
6085 // repeat over all faces for this object
6086 // CRO: getNumTEs() no longer equals mFaces.count(), so use mFaces.count() instead
6087 while ( mCurrentTE < cur_node->getObject()->getNumTEs() )
6088 {
6089 // if face selected
6090 if (cur_node->isTESelected(mCurrentTE))
6091 {
6092 // return this object and face
6093 *object = cur_node->getObject();
6094 *te = mCurrentTE;
6095 return;
6096 }
6097
6098 mCurrentTE++;
6099 }
6100
6101 mCurrentTE = 0;
6102 cur_node = getNextNode();
6103 }
6104
6105 // The list doesn't contain any nodes. Return NULL.
6106 *object = NULL;
6107 *te = -1;
6108 return;
6109} 5670}
6110 5671
6111void LLObjectSelection::getCurrentTE(LLViewerObject* *object, S32 *te) 5672void LLObjectSelection::moveNodeToFront(LLSelectNode *nodep)
6112{ 5673{
6113 if (mCurrentNode != end()) 5674 mList.remove(nodep);
6114 { 5675 mList.push_front(nodep);
6115 *object = (*mCurrentNode)->getObject();
6116 *te = mCurrentTE;
6117 }
6118 else
6119 {
6120 *object = NULL;
6121 *te = -1;
6122 }
6123}
6124//-----------------------------------------------------------------------------
6125// getFirstRootNode()
6126//-----------------------------------------------------------------------------
6127LLSelectNode *LLObjectSelection::getFirstRootNode()
6128{
6129 LLSelectNode *cur_node = getFirstNode();
6130
6131 // scan through child objects and roots set to ignore
6132 while (cur_node &&
6133 (!(cur_node->getObject()->isRootEdit() || cur_node->getObject()->isJointChild()) ||
6134 cur_node->mIndividualSelection))
6135 {
6136 cur_node = getNextNode();
6137 }
6138
6139 return cur_node;
6140} 5676}
6141 5677
6142 5678void LLObjectSelection::removeNode(LLSelectNode *nodep)
6143//-----------------------------------------------------------------------------
6144// getNextRootNode()
6145//-----------------------------------------------------------------------------
6146LLSelectNode *LLObjectSelection::getNextRootNode()
6147{ 5679{
6148 LLSelectNode *cur_node = getNextNode(); 5680 mSelectNodeMap.erase(nodep->getObject());
6149 5681 if (nodep->getObject() == mPrimaryObject)
6150 while (cur_node &&
6151 (!(cur_node->getObject()->isRootEdit() || cur_node->getObject()->isJointChild()) ||
6152 cur_node->mIndividualSelection))
6153 { 5682 {
6154 cur_node = getNextNode(); 5683 mPrimaryObject = NULL;
6155 } 5684 }
6156 5685 nodep->setObject(NULL); // Will get erased in cleanupNodes()
6157 return cur_node; 5686 mList.remove(nodep);
6158} 5687}
6159 5688
6160 5689void LLObjectSelection::deleteAllNodes()
6161//-----------------------------------------------------------------------------
6162// getFirstRootObject()
6163//-----------------------------------------------------------------------------
6164LLViewerObject *LLObjectSelection::getFirstRootObject()
6165{ 5690{
6166 LLSelectNode *node = getFirstRootNode(); 5691 std::for_each(mList.begin(), mList.end(), DeletePointer());
6167 5692 mList.clear();
6168 if (node) 5693 mSelectNodeMap.clear();
6169 { 5694 mPrimaryObject = NULL;
6170 return node->getObject();
6171 }
6172 else
6173 {
6174 return NULL;
6175 }
6176} 5695}
6177 5696
6178 5697LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp)
6179//-----------------------------------------------------------------------------
6180// getNextRootObject()
6181//-----------------------------------------------------------------------------
6182LLViewerObject *LLObjectSelection::getNextRootObject()
6183{ 5698{
6184 LLSelectNode *node = getNextRootNode(); 5699 std::map<LLPointer<LLViewerObject>, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp);
6185 5700 if (found_it != mSelectNodeMap.end())
6186 if (node)
6187 {
6188 return node->getObject();
6189 }
6190 else
6191 { 5701 {
6192 return NULL; 5702 return found_it->second;
6193 } 5703 }
5704 return NULL;
6194} 5705}
6195 5706
6196//----------------------------------------------------------------------------- 5707//-----------------------------------------------------------------------------
@@ -6198,7 +5709,7 @@ LLViewerObject *LLObjectSelection::getNextRootObject()
6198//----------------------------------------------------------------------------- 5709//-----------------------------------------------------------------------------
6199BOOL LLObjectSelection::isEmpty() 5710BOOL LLObjectSelection::isEmpty()
6200{ 5711{
6201 return (size() == 0); 5712 return (mList.size() == 0);
6202} 5713}
6203 5714
6204//----------------------------------------------------------------------------- 5715//-----------------------------------------------------------------------------
@@ -6206,24 +5717,20 @@ BOOL LLObjectSelection::isEmpty()
6206//----------------------------------------------------------------------------- 5717//-----------------------------------------------------------------------------
6207BOOL LLObjectSelection::getOwnershipCost(S32 &cost) 5718BOOL LLObjectSelection::getOwnershipCost(S32 &cost)
6208{ 5719{
6209 S32 count = 0; 5720 S32 count = getObjectCount();
6210 for( LLSelectNode* nodep = getFirstNode(); nodep; nodep = getNextNode() )
6211 {
6212 count++;
6213 }
6214
6215 cost = count * OWNERSHIP_COST_PER_OBJECT; 5721 cost = count * OWNERSHIP_COST_PER_OBJECT;
6216
6217 return (count > 0); 5722 return (count > 0);
6218} 5723}
6219 5724
6220 5725
6221//----------------------------------------------------------------------------- 5726//-----------------------------------------------------------------------------
6222// getObjectCount() 5727// getObjectCount() - returns number of non null objects
6223//----------------------------------------------------------------------------- 5728//-----------------------------------------------------------------------------
6224S32 LLObjectSelection::getObjectCount() 5729S32 LLObjectSelection::getObjectCount()
6225{ 5730{
6226 return getNumNodes(); 5731 cleanupNodes();
5732 S32 count = mList.size();
5733 return count;
6227} 5734}
6228 5735
6229 5736
@@ -6233,23 +5740,19 @@ S32 LLObjectSelection::getObjectCount()
6233S32 LLObjectSelection::getTECount() 5740S32 LLObjectSelection::getTECount()
6234{ 5741{
6235 S32 count = 0; 5742 S32 count = 0;
6236 5743 for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
6237 LLSelectNode* nodep;
6238 for (nodep = getFirstNode(); nodep; nodep = getNextNode() )
6239 { 5744 {
6240 if (nodep->getObject()) 5745 LLSelectNode* node = *iter;
5746 LLViewerObject* object = node->getObject();
5747 S32 num_tes = object->getNumTEs();
5748 for (S32 te = 0; te < num_tes; te++)
6241 { 5749 {
6242 S32 num_tes = nodep->getObject()->getNumTEs(); 5750 if (node->isTESelected(te))
6243 for (S32 te = 0; te < num_tes; te++)
6244 { 5751 {
6245 if (nodep->isTESelected(te)) 5752 ++count;
6246 {
6247 count++;
6248 }
6249 } 5753 }
6250 } 5754 }
6251 } 5755 }
6252
6253 return count; 5756 return count;
6254} 5757}
6255 5758
@@ -6258,47 +5761,97 @@ S32 LLObjectSelection::getTECount()
6258//----------------------------------------------------------------------------- 5761//-----------------------------------------------------------------------------
6259S32 LLObjectSelection::getRootObjectCount() 5762S32 LLObjectSelection::getRootObjectCount()
6260{ 5763{
6261 LLSelectNode *nodep;
6262
6263 S32 count = 0; 5764 S32 count = 0;
6264 for(nodep = getFirstRootNode(); nodep; nodep = getNextRootNode()) 5765 for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++)
6265 { 5766 {
6266 ++count; 5767 ++count;
6267 } 5768 }
6268 return count; 5769 return count;
6269} 5770}
6270 5771
6271bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func) 5772bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func, bool firstonly)
6272{ 5773{
6273 bool result = true; 5774 bool result = firstonly ? false : true;
6274 LLViewerObject* object; 5775 for (iterator iter = begin(); iter != end(); )
6275 for (object = getFirstObject(); object != NULL; object = getNextObject())
6276 { 5776 {
6277 result = result && func->apply(object); 5777 iterator nextiter = iter++;
5778 LLViewerObject* object = (*nextiter)->getObject();
5779 bool r = func->apply(object);
5780 if (firstonly && r)
5781 return true;
5782 else
5783 result = result && r;
6278 } 5784 }
6279 return result; 5785 return result;
6280} 5786}
6281 5787
6282bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func) 5788bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly)
6283{ 5789{
6284 bool result = true; 5790 bool result = firstonly ? false : true;
6285 LLViewerObject* object; 5791 for (root_iterator iter = root_begin(); iter != root_end(); )
6286 for (object = getFirstRootObject();
6287 object != NULL;
6288 object = getNextRootObject())
6289 { 5792 {
6290 result = result && func->apply(object); 5793 root_iterator nextiter = iter++;
5794 LLViewerObject* object = (*nextiter)->getObject();
5795 bool r = func->apply(object);
5796 if (firstonly && r)
5797 return true;
5798 else
5799 result = result && r;
6291 } 5800 }
6292 return result; 5801 return result;
6293} 5802}
6294 5803
6295bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func) 5804bool LLObjectSelection::applyToTEs(LLSelectedTEFunctor* func, bool firstonly)
6296{ 5805{
6297 bool result = true; 5806 bool result = firstonly ? false : true;
6298 LLSelectNode* node; 5807 for (iterator iter = begin(); iter != end(); )
6299 for (node = getFirstNode(); node != NULL; node = getNextNode()) 5808 {
5809 iterator nextiter = iter++;
5810 LLSelectNode* node = *nextiter;
5811 LLViewerObject* object = (*nextiter)->getObject();
5812 for (S32 te = 0; te < object->getNumTEs(); ++te)
5813 {
5814 if (node->isTESelected(te))
5815 {
5816 bool r = func->apply(object, te);
5817 if (firstonly && r)
5818 return true;
5819 else
5820 result = result && r;
5821 }
5822 }
5823 }
5824 return result;
5825}
5826
5827bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func, bool firstonly)
5828{
5829 bool result = firstonly ? false : true;
5830 for (iterator iter = begin(); iter != end(); )
5831 {
5832 iterator nextiter = iter++;
5833 LLSelectNode* node = *nextiter;
5834 bool r = func->apply(node);
5835 if (firstonly && r)
5836 return true;
5837 else
5838 result = result && r;
5839 }
5840 return result;
5841}
5842
5843bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool firstonly)
5844{
5845 bool result = firstonly ? false : true;
5846 for (root_iterator iter = root_begin(); iter != root_end(); )
6300 { 5847 {
6301 result = result && func->apply(node); 5848 root_iterator nextiter = iter++;
5849 LLSelectNode* node = *nextiter;
5850 bool r = func->apply(node);
5851 if (firstonly && r)
5852 return true;
5853 else
5854 result = result && r;
6302 } 5855 }
6303 return result; 5856 return result;
6304} 5857}
@@ -6317,12 +5870,13 @@ BOOL LLObjectSelection::contains(LLViewerObject* object)
6317//----------------------------------------------------------------------------- 5870//-----------------------------------------------------------------------------
6318BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te) 5871BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te)
6319{ 5872{
6320 LLSelectNode *nodep;
6321 if (te == SELECT_ALL_TES) 5873 if (te == SELECT_ALL_TES)
6322 { 5874 {
6323 // ...all faces 5875 // ...all faces
6324 for (nodep = getFirstNode(); nodep; nodep = getNextNode() ) 5876 for (LLObjectSelection::iterator iter = begin();
5877 iter != end(); iter++)
6325 { 5878 {
5879 LLSelectNode* nodep = *iter;
6326 if (nodep->getObject() == object) 5880 if (nodep->getObject() == object)
6327 { 5881 {
6328 BOOL all_selected = TRUE; 5882 BOOL all_selected = TRUE;
@@ -6338,8 +5892,9 @@ BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te)
6338 else 5892 else
6339 { 5893 {
6340 // ...one face 5894 // ...one face
6341 for (nodep = getFirstNode(); nodep; nodep = getNextNode() ) 5895 for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
6342 { 5896 {
5897 LLSelectNode* nodep = *iter;
6343 if (nodep->getObject() == object && nodep->isTESelected(te)) 5898 if (nodep->getObject() == object && nodep->isTESelected(te))
6344 { 5899 {
6345 return TRUE; 5900 return TRUE;
@@ -6356,203 +5911,193 @@ BOOL LLObjectSelection::isAttachment()
6356} 5911}
6357 5912
6358//----------------------------------------------------------------------------- 5913//-----------------------------------------------------------------------------
6359// getFirstMoveableNode() 5914// getSelectedParentObject()
6360//----------------------------------------------------------------------------- 5915//-----------------------------------------------------------------------------
6361LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root) 5916LLViewerObject* getSelectedParentObject(LLViewerObject *object)
6362{ 5917{
6363 LLSelectNode* selectNode = NULL; 5918 LLViewerObject *parent;
6364 5919 while (object && (parent = (LLViewerObject*)object->getParent()))
6365 if (get_root)
6366 { 5920 {
6367 for(selectNode = getFirstRootNode(); selectNode; selectNode = getNextRootNode()) 5921 if (parent->isSelected())
6368 { 5922 {
6369 if( selectNode->getObject()->permMove() ) 5923 object = parent;
6370 {
6371 return selectNode;
6372 break;
6373 }
6374 } 5924 }
6375 } 5925 else
6376 for(selectNode = getFirstNode(); selectNode; selectNode = getNextNode())
6377 {
6378 if( selectNode->getObject()->permMove() )
6379 { 5926 {
6380 return selectNode;
6381 break; 5927 break;
6382 } 5928 }
6383 } 5929 }
6384 5930 return object;
6385 return NULL;
6386} 5931}
6387 5932
6388//----------------------------------------------------------------------------- 5933//-----------------------------------------------------------------------------
6389// getFirstCopyableObject() 5934// getFirstNode
6390//----------------------------------------------------------------------------- 5935//-----------------------------------------------------------------------------
6391LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_root) 5936LLSelectNode* LLObjectSelection::getFirstNode(LLSelectedNodeFunctor* func)
6392{ 5937{
6393 LLViewerObject* object = NULL; 5938 for (iterator iter = begin(); iter != end(); ++iter)
6394 for(LLViewerObject* cur = getFirstObject(); cur; cur = getNextObject())
6395 { 5939 {
6396 if( cur->permCopy() && !cur->isAttachment()) 5940 LLSelectNode* node = *iter;
5941 if (func == NULL || func->apply(node))
6397 { 5942 {
6398 object = cur; 5943 return node;
6399 break;
6400 } 5944 }
6401 } 5945 }
5946 return NULL;
5947}
6402 5948
6403 if (get_root && object) 5949LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, BOOL non_root_ok)
5950{
5951 for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
6404 { 5952 {
6405 LLViewerObject *parent; 5953 LLSelectNode* node = *iter;
6406 while ((parent = (LLViewerObject*)object->getParent())) 5954 if (func == NULL || func->apply(node))
6407 { 5955 {
6408 if (parent->isSelected()) 5956 return node;
6409 {
6410 object = parent;
6411 }
6412 else
6413 {
6414 break;
6415 }
6416 } 5957 }
6417 } 5958 }
5959 if (non_root_ok)
5960 {
5961 // Get non root
5962 return getFirstNode(func);
5963 }
5964 return NULL;
5965}
6418 5966
6419 return object; 5967
5968//-----------------------------------------------------------------------------
5969// getFirstSelectedObject
5970//-----------------------------------------------------------------------------
5971LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent)
5972{
5973 LLSelectNode* res = getFirstNode(func);
5974 if (res && get_parent)
5975 {
5976 return getSelectedParentObject(res->getObject());
5977 }
5978 else if (res)
5979 {
5980 return res->getObject();
5981 }
5982 return NULL;
6420} 5983}
6421 5984
5985//-----------------------------------------------------------------------------
5986// getFirstObject()
5987//-----------------------------------------------------------------------------
5988LLViewerObject* LLObjectSelection::getFirstObject()
5989{
5990 LLSelectNode* res = getFirstNode(NULL);
5991 return res ? res->getObject() : NULL;
5992}
6422 5993
6423//----------------------------------------------------------------------------- 5994//-----------------------------------------------------------------------------
6424// getFirstDeleteableObject() 5995// getFirstRootObject()
6425//----------------------------------------------------------------------------- 5996//-----------------------------------------------------------------------------
6426LLViewerObject* LLObjectSelection::getFirstDeleteableObject(BOOL get_root) 5997LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok)
6427{ 5998{
6428 //RN: don't currently support deletion of child objects, as that requires separating them first 5999 LLSelectNode* res = getFirstRootNode(NULL, non_root_ok);
6429 // then derezzing to trash 6000 return res ? res->getObject() : NULL;
6430 get_root = TRUE; 6001}
6431 6002
6432 LLViewerObject* object = NULL; 6003//-----------------------------------------------------------------------------
6433 if (get_root) 6004// getFirstMoveableNode()
6005//-----------------------------------------------------------------------------
6006LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first)
6007{
6008 struct f : public LLSelectedNodeFunctor
6434 { 6009 {
6435 for(LLViewerObject* current = getFirstRootObject(); 6010 bool apply(LLSelectNode* node)
6436 current != NULL;
6437 current = getNextRootObject())
6438 { 6011 {
6439 // you can delete an object if permissions allow it, you are 6012 LLViewerObject* obj = node->getObject();
6440 // the owner, you are an officer in the group that owns the 6013 return obj->permMove();
6441 // object, or you are not the owner but it is on land you own 6014 }
6442 // or land owned by your group. (whew!) 6015 } func;
6443 if( (current->permModify()) 6016 LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func);
6444 || (current->permYouOwner()) 6017 return res;
6445 || (!current->permAnyOwner()) // public 6018}
6446 || (current->isOverAgentOwnedLand())
6447 || (current->isOverGroupOwnedLand())
6448 )
6449 {
6450 6019
6451 if( !current->isAttachment() ) 6020//-----------------------------------------------------------------------------
6452 { 6021// getFirstCopyableObject()
6453 object = current; 6022//-----------------------------------------------------------------------------
6454 break; 6023LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent)
6455 } 6024{
6456 } 6025 struct f : public LLSelectedNodeFunctor
6457 } 6026 {
6458 } 6027 bool apply(LLSelectNode* node)
6459 else 6028 {
6029 LLViewerObject* obj = node->getObject();
6030 return obj->permCopy() && !obj->isAttachment();
6031 }
6032 } func;
6033 return getFirstSelectedObject(&func, get_parent);
6034}
6035
6036//-----------------------------------------------------------------------------
6037// getFirstDeleteableObject()
6038//-----------------------------------------------------------------------------
6039LLViewerObject* LLObjectSelection::getFirstDeleteableObject()
6040{
6041 //RN: don't currently support deletion of child objects, as that requires separating them first
6042 // then derezzing to trash
6043
6044 struct f : public LLSelectedNodeFunctor
6460 { 6045 {
6461 // We've avoided this path for a while. It may not work. 6046 bool apply(LLSelectNode* node)
6462 llwarns << "!get_root code path may have bitrotted." << llendl;
6463 for(LLViewerObject* current = getFirstObject();
6464 current != NULL;
6465 current = getNextObject())
6466 { 6047 {
6048 LLViewerObject* obj = node->getObject();
6467 // you can delete an object if permissions allow it, you are 6049 // you can delete an object if permissions allow it, you are
6468 // the owner, you are an officer in the group that owns the 6050 // the owner, you are an officer in the group that owns the
6469 // object, or you are not the owner but it is on land you own 6051 // object, or you are not the owner but it is on land you own
6470 // or land owned by your group. (whew!) 6052 // or land owned by your group. (whew!)
6471 if( (current->permModify()) 6053 if( (obj->permModify())
6472 || (current->permYouOwner()) 6054 || (obj->permYouOwner())
6473 || (!current->permAnyOwner()) // public 6055 || (!obj->permAnyOwner()) // public
6474 || (current->isOverAgentOwnedLand()) 6056 || (obj->isOverAgentOwnedLand())
6475 || (current->isOverGroupOwnedLand()) 6057 || (obj->isOverGroupOwnedLand())
6476 ) 6058 )
6477 { 6059 {
6478 if( !current->isAttachment() ) 6060 if( !obj->isAttachment() )
6479 { 6061 {
6480 object = current; 6062 return TRUE;
6481 break;
6482 } 6063 }
6483 } 6064 }
6484 } 6065 return true;
6485 } 6066 }
6486 6067 } func;
6487 return object; 6068 LLSelectNode* node = getFirstNode(&func);
6069 return node ? node->getObject() : NULL;
6488} 6070}
6489 6071
6490
6491//----------------------------------------------------------------------------- 6072//-----------------------------------------------------------------------------
6492// getFirstEditableObject() 6073// getFirstEditableObject()
6493//----------------------------------------------------------------------------- 6074//-----------------------------------------------------------------------------
6494LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_root) 6075LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent)
6495{ 6076{
6496 LLViewerObject* object = NULL; 6077 struct f : public LLSelectedNodeFunctor
6497 for(LLViewerObject* cur = getFirstObject(); cur; cur = getNextObject())
6498 { 6078 {
6499 if( cur->permModify() ) 6079 bool apply(LLSelectNode* node)
6500 { 6080 {
6501 object = cur; 6081 LLViewerObject* obj = node->getObject();
6502 break; 6082 return obj->permModify();
6503 } 6083 }
6504 } 6084 } func;
6505 6085 return getFirstSelectedObject(&func, get_parent);
6506 if (get_root && object)
6507 {
6508 LLViewerObject *parent;
6509 while ((parent = (LLViewerObject*)object->getParent()))
6510 {
6511 if (parent->isSelected())
6512 {
6513 object = parent;
6514 }
6515 else
6516 {
6517 break;
6518 }
6519 }
6520 }
6521
6522 return object;
6523} 6086}
6524 6087
6525//----------------------------------------------------------------------------- 6088//-----------------------------------------------------------------------------
6526// getFirstMoveableObject() 6089// getFirstMoveableObject()
6527//----------------------------------------------------------------------------- 6090//-----------------------------------------------------------------------------
6528LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_root) 6091LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent)
6529{ 6092{
6530 LLViewerObject* object = NULL; 6093 struct f : public LLSelectedNodeFunctor
6531 for(LLViewerObject* cur = getFirstObject(); cur; cur = getNextObject())
6532 {
6533 if( cur->permMove() )
6534 {
6535 object = cur;
6536 break;
6537 }
6538 }
6539
6540 if (get_root && object && !object->isJointChild())
6541 { 6094 {
6542 LLViewerObject *parent; 6095 bool apply(LLSelectNode* node)
6543 while ((parent = (LLViewerObject*)object->getParent()))
6544 { 6096 {
6545 if (parent->isSelected()) 6097 LLViewerObject* obj = node->getObject();
6546 { 6098 return obj->permMove();
6547 object = parent;
6548 }
6549 else
6550 {
6551 break;
6552 }
6553 } 6099 }
6554 } 6100 } func;
6555 6101 return getFirstSelectedObject(&func, get_parent);
6556 return object;
6557} 6102}
6558 6103