/indra/newview/llselectmgr.cpp
C++ | 2415 lines | 1817 code | 300 blank | 298 comment | 264 complexity | ca67b7068cb2644ccd7bc23e3c748406 MD5 | raw file
Possible License(s): LGPL-2.1
Large files files are truncated, but you can click here to view the full file
1/** 2 * @file llselectmgr.cpp 3 * @brief A manager for selected objects and faces. 4 * 5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 6 * Second Life Viewer Source Code 7 * Copyright (C) 2010, Linden Research, Inc. 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; 12 * version 2.1 of the License only. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 * $/LicenseInfo$ 25 */ 26 27#include "llviewerprecompiledheaders.h" 28 29// file include 30#define LLSELECTMGR_CPP 31#include "llselectmgr.h" 32 33// library includes 34#include "llcachename.h" 35#include "lldbstrings.h" 36#include "lleconomy.h" 37#include "llgl.h" 38#include "llmediaentry.h" 39#include "llrender.h" 40#include "llnotifications.h" 41#include "llpermissions.h" 42#include "llpermissionsflags.h" 43#include "lltrans.h" 44#include "llundo.h" 45#include "lluuid.h" 46#include "llvolume.h" 47#include "message.h" 48#include "object_flags.h" 49#include "llquaternion.h" 50 51// viewer includes 52#include "llagent.h" 53#include "llagentcamera.h" 54#include "llviewerwindow.h" 55#include "lldrawable.h" 56#include "llfloaterinspect.h" 57#include "llfloaterproperties.h" 58#include "llfloaterreporter.h" 59#include "llfloaterreg.h" 60#include "llfloatertools.h" 61#include "llframetimer.h" 62#include "llfocusmgr.h" 63#include "llhudeffecttrail.h" 64#include "llhudmanager.h" 65#include "llinventorymodel.h" 66#include "llmenugl.h" 67#include "llmeshrepository.h" 68#include "llmutelist.h" 69#include "llnotificationsutil.h" 70#include "llsidepaneltaskinfo.h" 71#include "llslurl.h" 72#include "llstatusbar.h" 73#include "llsurface.h" 74#include "lltool.h" 75#include "lltooldraganddrop.h" 76#include "lltoolmgr.h" 77#include "lltoolpie.h" 78#include "llui.h" 79#include "llviewercamera.h" 80#include "llviewercontrol.h" 81#include "llviewertexturelist.h" 82#include "llviewermedia.h" 83#include "llviewermediafocus.h" 84#include "llviewermenu.h" 85#include "llviewerobject.h" 86#include "llviewerobjectlist.h" 87#include "llviewerregion.h" 88#include "llviewerstats.h" 89#include "llvoavatarself.h" 90#include "llvovolume.h" 91#include "pipeline.h" 92#include "llviewershadermgr.h" 93 94#include "llglheaders.h" 95 96LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; 97// 98// Consts 99// 100 101const S32 NUM_SELECTION_UNDO_ENTRIES = 200; 102const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f; 103const S32 MAX_ACTION_QUEUE_SIZE = 20; 104const S32 MAX_SILS_PER_FRAME = 50; 105const S32 MAX_OBJECTS_PER_PACKET = 254; 106const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; 107 108// 109// Globals 110// 111 112//BOOL gDebugSelectMgr = FALSE; 113 114//BOOL gHideSelectedObjects = FALSE; 115//BOOL gAllowSelectAvatar = FALSE; 116 117BOOL LLSelectMgr::sRectSelectInclusive = TRUE; 118BOOL LLSelectMgr::sRenderHiddenSelections = TRUE; 119BOOL LLSelectMgr::sRenderLightRadius = FALSE; 120F32 LLSelectMgr::sHighlightThickness = 0.f; 121F32 LLSelectMgr::sHighlightUScale = 0.f; 122F32 LLSelectMgr::sHighlightVScale = 0.f; 123F32 LLSelectMgr::sHighlightAlpha = 0.f; 124F32 LLSelectMgr::sHighlightAlphaTest = 0.f; 125F32 LLSelectMgr::sHighlightUAnim = 0.f; 126F32 LLSelectMgr::sHighlightVAnim = 0.f; 127LLColor4 LLSelectMgr::sSilhouetteParentColor; 128LLColor4 LLSelectMgr::sSilhouetteChildColor; 129LLColor4 LLSelectMgr::sHighlightInspectColor; 130LLColor4 LLSelectMgr::sHighlightParentColor; 131LLColor4 LLSelectMgr::sHighlightChildColor; 132LLColor4 LLSelectMgr::sContextSilhouetteColor; 133 134static LLObjectSelection *get_null_object_selection(); 135template<> 136 const LLSafeHandle<LLObjectSelection>::NullFunc 137 LLSafeHandle<LLObjectSelection>::sNullFunc = get_null_object_selection; 138 139//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 140// struct LLDeRezInfo 141// 142// Used to keep track of important derez info. 143//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 144 145struct LLDeRezInfo 146{ 147 EDeRezDestination mDestination; 148 LLUUID mDestinationID; 149 LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) : 150 mDestination(dest), mDestinationID(dest_id) {} 151}; 152 153// 154// Imports 155// 156 157 158static LLPointer<LLObjectSelection> sNullSelection; 159 160// 161// Functions 162// 163 164void LLSelectMgr::cleanupGlobals() 165{ 166 sNullSelection = NULL; 167 LLSelectMgr::getInstance()->clearSelections(); 168} 169 170LLObjectSelection *get_null_object_selection() 171{ 172 if (sNullSelection.isNull()) 173 { 174 sNullSelection = new LLObjectSelection; 175 } 176 return sNullSelection; 177} 178 179// Build time optimization, generate this function once here 180template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance(); 181//----------------------------------------------------------------------------- 182// LLSelectMgr() 183//----------------------------------------------------------------------------- 184LLSelectMgr::LLSelectMgr() 185 : mHideSelectedObjects(LLCachedControl<bool>(gSavedSettings, "HideSelectedObjects", FALSE)), 186 mRenderHighlightSelections(LLCachedControl<bool>(gSavedSettings, "RenderHighlightSelections", TRUE)), 187 mAllowSelectAvatar( LLCachedControl<bool>(gSavedSettings, "AllowSelectAvatar", FALSE)), 188 mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE)) 189{ 190 mTEMode = FALSE; 191 mLastCameraPos.clearVec(); 192 193 sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness"); 194 sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale"); 195 sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale"); 196 sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha"); 197 sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest"); 198 sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim"); 199 sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim"); 200 201 sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor"); 202 sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor"); 203 sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor"); 204 sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor"); 205 sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor"); 206 sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f; 207 208 sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); 209 210 mRenderSilhouettes = TRUE; 211 212 mGridMode = GRID_MODE_WORLD; 213 gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD); 214 mGridValid = FALSE; 215 216 mSelectedObjects = new LLObjectSelection(); 217 mHoverObjects = new LLObjectSelection(); 218 mHighlightedObjects = new LLObjectSelection(); 219 220 mForceSelection = FALSE; 221 mShowSelection = FALSE; 222} 223 224 225//----------------------------------------------------------------------------- 226// ~LLSelectMgr() 227//----------------------------------------------------------------------------- 228LLSelectMgr::~LLSelectMgr() 229{ 230 clearSelections(); 231} 232 233void LLSelectMgr::clearSelections() 234{ 235 mHoverObjects->deleteAllNodes(); 236 mSelectedObjects->deleteAllNodes(); 237 mHighlightedObjects->deleteAllNodes(); 238 mRectSelectedObjects.clear(); 239 mGridObjects.deleteAllNodes(); 240} 241 242void LLSelectMgr::update() 243{ 244 mSelectedObjects->cleanupNodes(); 245} 246 247void LLSelectMgr::updateEffects() 248{ 249 //keep reference grid objects active 250 struct f : public LLSelectedObjectFunctor 251 { 252 virtual bool apply(LLViewerObject* object) 253 { 254 LLDrawable* drawable = object->mDrawable; 255 if (drawable) 256 { 257 gPipeline.markMoved(drawable); 258 } 259 return true; 260 } 261 } func; 262 mGridObjects.applyToObjects(&func); 263 264 if (mEffectsTimer.getElapsedTimeF32() > 1.f) 265 { 266 mSelectedObjects->updateEffects(); 267 mEffectsTimer.reset(); 268 } 269} 270 271void LLSelectMgr::overrideObjectUpdates() 272{ 273 //override any position updates from simulator on objects being edited 274 struct f : public LLSelectedNodeFunctor 275 { 276 virtual bool apply(LLSelectNode* selectNode) 277 { 278 LLViewerObject* object = selectNode->getObject(); 279 if (object && object->permMove()) 280 { 281 if (!selectNode->mLastPositionLocal.isExactlyZero()) 282 { 283 object->setPosition(selectNode->mLastPositionLocal); 284 } 285 if (selectNode->mLastRotation != LLQuaternion()) 286 { 287 object->setRotation(selectNode->mLastRotation); 288 } 289 if (!selectNode->mLastScale.isExactlyZero()) 290 { 291 object->setScale(selectNode->mLastScale); 292 } 293 } 294 return true; 295 } 296 } func; 297 getSelection()->applyToNodes(&func); 298} 299 300//----------------------------------------------------------------------------- 301// Select just the object, not any other group members. 302//----------------------------------------------------------------------------- 303LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S32 face) 304{ 305 llassert( object ); 306 307 //remember primary object 308 mSelectedObjects->mPrimaryObject = object; 309 310 // Don't add an object that is already in the list 311 if (object->isSelected() ) { 312 // make sure point at position is updated 313 updatePointAt(); 314 gEditMenuHandler = this; 315 return NULL; 316 } 317 318 if (!canSelectObject(object)) 319 { 320 //make_ui_sound("UISndInvalidOp"); 321 return NULL; 322 } 323 324 // llinfos << "Adding object to selected object list" << llendl; 325 326 // Place it in the list and tag it. 327 // This will refresh dialogs. 328 addAsIndividual(object, face); 329 330 // Stop the object from moving (this anticipates changes on the 331 // simulator in LLTask::userSelect) 332 // *FIX: shouldn't zero out these either 333 object->setVelocity(LLVector3::zero); 334 object->setAcceleration(LLVector3::zero); 335 //object->setAngularVelocity(LLVector3::zero); 336 object->resetRot(); 337 338 // Always send to simulator, so you get a copy of the 339 // permissions structure back. 340 gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); 341 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 342 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 343 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 344 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 345 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); 346 LLViewerRegion* regionp = object->getRegion(); 347 gMessageSystem->sendReliable( regionp->getHost()); 348 349 updatePointAt(); 350 updateSelectionCenter(); 351 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); 352 353 // have selection manager handle edit menu immediately after 354 // user selects an object 355 if (mSelectedObjects->getObjectCount()) 356 { 357 gEditMenuHandler = this; 358 } 359 360 return mSelectedObjects; 361} 362 363//----------------------------------------------------------------------------- 364// Select the object, parents and children. 365//----------------------------------------------------------------------------- 366LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, BOOL add_to_end) 367{ 368 llassert( obj ); 369 370 //remember primary object 371 mSelectedObjects->mPrimaryObject = obj; 372 373 // This may be incorrect if things weren't family selected before... - djs 07/08/02 374 // Don't add an object that is already in the list 375 if (obj->isSelected() ) 376 { 377 // make sure pointat position is updated 378 updatePointAt(); 379 gEditMenuHandler = this; 380 return NULL; 381 } 382 383 if (!canSelectObject(obj)) 384 { 385 //make_ui_sound("UISndInvalidOp"); 386 return NULL; 387 } 388 389 // Since we're selecting a family, start at the root, but 390 // don't include an avatar. 391 LLViewerObject* root = obj; 392 393 while(!root->isAvatar() && root->getParent() && !root->isJointChild()) 394 { 395 LLViewerObject* parent = (LLViewerObject*)root->getParent(); 396 if (parent->isAvatar()) 397 { 398 break; 399 } 400 root = parent; 401 } 402 403 // Collect all of the objects 404 std::vector<LLViewerObject*> objects; 405 406 root->addThisAndNonJointChildren(objects); 407 addAsFamily(objects, add_to_end); 408 409 updateSelectionCenter(); 410 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); 411 updatePointAt(); 412 413 dialog_refresh_all(); 414 415 // Always send to simulator, so you get a copy of the permissions 416 // structure back. 417 sendSelect(); 418 419 // Stop the object from moving (this anticipates changes on the 420 // simulator in LLTask::userSelect) 421 root->setVelocity(LLVector3::zero); 422 root->setAcceleration(LLVector3::zero); 423 //root->setAngularVelocity(LLVector3::zero); 424 root->resetRot(); 425 426 // leave component mode 427 if (gSavedSettings.getBOOL("EditLinkedParts")) 428 { 429 gSavedSettings.setBOOL("EditLinkedParts", FALSE); 430 promoteSelectionToRoot(); 431 } 432 433 // have selection manager handle edit menu immediately after 434 // user selects an object 435 if (mSelectedObjects->getObjectCount()) 436 { 437 gEditMenuHandler = this; 438 } 439 440 return mSelectedObjects; 441} 442 443//----------------------------------------------------------------------------- 444// Select the object, parents and children. 445//----------------------------------------------------------------------------- 446LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list, 447 BOOL send_to_sim) 448{ 449 // Collect all of the objects, children included 450 std::vector<LLViewerObject*> objects; 451 452 //clear primary object (no primary object) 453 mSelectedObjects->mPrimaryObject = NULL; 454 455 if (object_list.size() < 1) 456 { 457 return NULL; 458 } 459 460 // NOTE -- we add the objects in REVERSE ORDER 461 // to preserve the order in the mSelectedObjects list 462 for (std::vector<LLViewerObject*>::const_reverse_iterator riter = object_list.rbegin(); 463 riter != object_list.rend(); ++riter) 464 { 465 LLViewerObject *object = *riter; 466 467 llassert( object ); 468 469 if (!canSelectObject(object)) continue; 470 471 object->addThisAndNonJointChildren(objects); 472 addAsFamily(objects); 473 474 // Stop the object from moving (this anticipates changes on the 475 // simulator in LLTask::userSelect) 476 object->setVelocity(LLVector3::zero); 477 object->setAcceleration(LLVector3::zero); 478 //object->setAngularVelocity(LLVector3::zero); 479 object->resetRot(); 480 } 481 482 updateSelectionCenter(); 483 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); 484 updatePointAt(); 485 dialog_refresh_all(); 486 487 // Almost always send to simulator, so you get a copy of the permissions 488 // structure back. 489 // JC: The one case where you don't want to do this is if you're selecting 490 // all the objects on a sim. 491 if (send_to_sim) 492 { 493 sendSelect(); 494 } 495 496 // leave component mode 497 if (gSavedSettings.getBOOL("EditLinkedParts")) 498 { 499 gSavedSettings.setBOOL("EditLinkedParts", FALSE); 500 promoteSelectionToRoot(); 501 } 502 503 // have selection manager handle edit menu immediately after 504 // user selects an object 505 if (mSelectedObjects->getObjectCount()) 506 { 507 gEditMenuHandler = this; 508 } 509 510 return mSelectedObjects; 511} 512 513// Use for when the simulator kills an object. This version also 514// handles informing the current tool of the object's deletion. 515// 516// Caller needs to call dialog_refresh_all if necessary. 517BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id) 518{ 519 BOOL object_found = FALSE; 520 LLTool *tool = NULL; 521 522 tool = LLToolMgr::getInstance()->getCurrentTool(); 523 524 // It's possible that the tool is editing an object that is not selected 525 LLViewerObject* tool_editing_object = tool->getEditingObject(); 526 if( tool_editing_object && tool_editing_object->mID == id) 527 { 528 tool->stopEditing(); 529 object_found = TRUE; 530 } 531 532 // Iterate through selected objects list and kill the object 533 if( !object_found ) 534 { 535 for (LLObjectSelection::iterator iter = getSelection()->begin(); 536 iter != getSelection()->end(); ) 537 { 538 LLObjectSelection::iterator curiter = iter++; 539 LLViewerObject* object = (*curiter)->getObject(); 540 if (object->mID == id) 541 { 542 if (tool) 543 { 544 tool->stopEditing(); 545 } 546 547 // lose the selection, don't tell simulator, it knows 548 deselectObjectAndFamily(object, FALSE); 549 object_found = TRUE; 550 break; // must break here, may have removed multiple objects from list 551 } 552 else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id) 553 { 554 // It's possible the item being removed has an avatar sitting on it 555 // So remove the avatar that is sitting on the object. 556 deselectObjectAndFamily(object, FALSE); 557 break; // must break here, may have removed multiple objects from list 558 } 559 } 560 } 561 562 return object_found; 563} 564 565bool LLSelectMgr::linkObjects() 566{ 567 if (!LLSelectMgr::getInstance()->selectGetAllRootsValid()) 568 { 569 LLNotificationsUtil::add("UnableToLinkWhileDownloading"); 570 return true; 571 } 572 573 S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); 574 if (object_count > MAX_CHILDREN_PER_TASK + 1) 575 { 576 LLSD args; 577 args["COUNT"] = llformat("%d", object_count); 578 int max = MAX_CHILDREN_PER_TASK+1; 579 args["MAX"] = llformat("%d", max); 580 LLNotificationsUtil::add("UnableToLinkObjects", args); 581 return true; 582 } 583 584 if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2) 585 { 586 LLNotificationsUtil::add("CannotLinkIncompleteSet"); 587 return true; 588 } 589 590 if (!LLSelectMgr::getInstance()->selectGetRootsModify()) 591 { 592 LLNotificationsUtil::add("CannotLinkModify"); 593 return true; 594 } 595 596 LLUUID owner_id; 597 std::string owner_name; 598 if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name)) 599 { 600 // we don't actually care if you're the owner, but novices are 601 // the most likely to be stumped by this one, so offer the 602 // easiest and most likely solution. 603 LLNotificationsUtil::add("CannotLinkDifferentOwners"); 604 return true; 605 } 606 607 LLSelectMgr::getInstance()->sendLink(); 608 609 return true; 610} 611 612bool LLSelectMgr::unlinkObjects() 613{ 614 LLSelectMgr::getInstance()->sendDelink(); 615 return true; 616} 617 618// in order to link, all objects must have the same owner, and the 619// agent must have the ability to modify all of the objects. However, 620// we're not answering that question with this method. The question 621// we're answering is: does the user have a reasonable expectation 622// that a link operation should work? If so, return true, false 623// otherwise. this allows the handle_link method to more finely check 624// the selection and give an error message when the uer has a 625// reasonable expectation for the link to work, but it will fail. 626bool LLSelectMgr::enableLinkObjects() 627{ 628 bool new_value = false; 629 // check if there are at least 2 objects selected, and that the 630 // user can modify at least one of the selected objects. 631 632 // in component mode, can't link 633 if (!gSavedSettings.getBOOL("EditLinkedParts")) 634 { 635 if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2) 636 { 637 struct f : public LLSelectedObjectFunctor 638 { 639 virtual bool apply(LLViewerObject* object) 640 { 641 return object->permModify(); 642 } 643 } func; 644 const bool firstonly = true; 645 new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly); 646 } 647 } 648 return new_value; 649} 650 651bool LLSelectMgr::enableUnlinkObjects() 652{ 653 LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject(); 654 655 bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() && 656 first_editable_object && 657 !first_editable_object->isAttachment(); 658 659 return new_value; 660} 661 662void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object) 663{ 664 // bail if nothing selected or if object wasn't selected in the first place 665 if(!object) return; 666 if(!object->isSelected()) return; 667 668 // Collect all of the objects, and remove them 669 std::vector<LLViewerObject*> objects; 670 671 if (include_entire_object) 672 { 673 // Since we're selecting a family, start at the root, but 674 // don't include an avatar. 675 LLViewerObject* root = object; 676 677 while(!root->isAvatar() && root->getParent() && !root->isJointChild()) 678 { 679 LLViewerObject* parent = (LLViewerObject*)root->getParent(); 680 if (parent->isAvatar()) 681 { 682 break; 683 } 684 root = parent; 685 } 686 687 object = root; 688 } 689 else 690 { 691 object = (LLViewerObject*)object->getRoot(); 692 } 693 694 object->addThisAndAllChildren(objects); 695 remove(objects); 696 697 if (!send_to_sim) return; 698 699 //----------------------------------------------------------- 700 // Inform simulator of deselection 701 //----------------------------------------------------------- 702 LLViewerRegion* regionp = object->getRegion(); 703 704 BOOL start_new_message = TRUE; 705 S32 select_count = 0; 706 707 LLMessageSystem* msg = gMessageSystem; 708 for (U32 i = 0; i < objects.size(); i++) 709 { 710 if (start_new_message) 711 { 712 msg->newMessageFast(_PREHASH_ObjectDeselect); 713 msg->nextBlockFast(_PREHASH_AgentData); 714 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 715 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 716 select_count++; 717 start_new_message = FALSE; 718 } 719 720 msg->nextBlockFast(_PREHASH_ObjectData); 721 msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID()); 722 select_count++; 723 724 // Zap the angular velocity, as the sim will set it to zero 725 objects[i]->setAngularVelocity( 0,0,0 ); 726 objects[i]->setVelocity( 0,0,0 ); 727 728 if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET) 729 { 730 msg->sendReliable(regionp->getHost() ); 731 select_count = 0; 732 start_new_message = TRUE; 733 } 734 } 735 736 if (!start_new_message) 737 { 738 msg->sendReliable(regionp->getHost() ); 739 } 740 741 updatePointAt(); 742 updateSelectionCenter(); 743} 744 745void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim) 746{ 747 // bail if nothing selected or if object wasn't selected in the first place 748 if (!object) return; 749 if (!object->isSelected() ) return; 750 751 // Zap the angular velocity, as the sim will set it to zero 752 object->setAngularVelocity( 0,0,0 ); 753 object->setVelocity( 0,0,0 ); 754 755 if (send_to_sim) 756 { 757 LLViewerRegion* region = object->getRegion(); 758 gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect); 759 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 760 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 761 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 762 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 763 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() ); 764 gMessageSystem->sendReliable(region->getHost()); 765 } 766 767 // This will refresh dialogs. 768 remove( object ); 769 770 updatePointAt(); 771 updateSelectionCenter(); 772} 773 774 775//----------------------------------------------------------------------------- 776// addAsFamily 777//----------------------------------------------------------------------------- 778 779void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end) 780{ 781 for (std::vector<LLViewerObject*>::iterator iter = objects.begin(); 782 iter != objects.end(); ++iter) 783 { 784 LLViewerObject* objectp = *iter; 785 786 // Can't select yourself 787 if (objectp->mID == gAgentID 788 && !LLSelectMgr::getInstance()->mAllowSelectAvatar) 789 { 790 continue; 791 } 792 793 if (!objectp->isSelected()) 794 { 795 LLSelectNode *nodep = new LLSelectNode(objectp, TRUE); 796 if (add_to_end) 797 { 798 mSelectedObjects->addNodeAtEnd(nodep); 799 } 800 else 801 { 802 mSelectedObjects->addNode(nodep); 803 } 804 objectp->setSelected(TRUE); 805 806 if (objectp->getNumTEs() > 0) 807 { 808 nodep->selectAllTEs(TRUE); 809 } 810 else 811 { 812 // object has no faces, so don't mess with faces 813 } 814 } 815 else 816 { 817 // we want this object to be selected for real 818 // so clear transient flag 819 LLSelectNode* select_node = mSelectedObjects->findNode(objectp); 820 if (select_node) 821 { 822 select_node->setTransient(FALSE); 823 } 824 } 825 } 826 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); 827} 828 829//----------------------------------------------------------------------------- 830// addAsIndividual() - a single object, face, etc 831//----------------------------------------------------------------------------- 832void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoable) 833{ 834 // check to see if object is already in list 835 LLSelectNode *nodep = mSelectedObjects->findNode(objectp); 836 837 // if not in list, add it 838 if (!nodep) 839 { 840 nodep = new LLSelectNode(objectp, TRUE); 841 mSelectedObjects->addNode(nodep); 842 llassert_always(nodep->getObject()); 843 } 844 else 845 { 846 // make this a full-fledged selection 847 nodep->setTransient(FALSE); 848 // Move it to the front of the list 849 mSelectedObjects->moveNodeToFront(nodep); 850 } 851 852 // Make sure the object is tagged as selected 853 objectp->setSelected( TRUE ); 854 855 // And make sure we don't consider it as part of a family 856 nodep->mIndividualSelection = TRUE; 857 858 // Handle face selection 859 if (objectp->getNumTEs() <= 0) 860 { 861 // object has no faces, so don't do anything 862 } 863 else if (face == SELECT_ALL_TES) 864 { 865 nodep->selectAllTEs(TRUE); 866 } 867 else if (0 <= face && face < SELECT_MAX_TES) 868 { 869 nodep->selectTE(face, TRUE); 870 } 871 else 872 { 873 llerrs << "LLSelectMgr::add face " << face << " out-of-range" << llendl; 874 return; 875 } 876 877 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); 878 updateSelectionCenter(); 879 dialog_refresh_all(); 880} 881 882 883LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face) 884{ 885 if (!objectp) 886 { 887 mHoverObjects->deleteAllNodes(); 888 return NULL; 889 } 890 891 // Can't select yourself 892 if (objectp->mID == gAgentID) 893 { 894 mHoverObjects->deleteAllNodes(); 895 return NULL; 896 } 897 898 // Can't select land 899 if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) 900 { 901 mHoverObjects->deleteAllNodes(); 902 return NULL; 903 } 904 905 mHoverObjects->mPrimaryObject = objectp; 906 907 objectp = objectp->getRootEdit(); 908 909 // is the requested object the same as the existing hover object root? 910 // NOTE: there is only ever one linked set in mHoverObjects 911 if (mHoverObjects->getFirstRootObject() != objectp) 912 { 913 914 // Collect all of the objects 915 std::vector<LLViewerObject*> objects; 916 objectp = objectp->getRootEdit(); 917 objectp->addThisAndNonJointChildren(objects); 918 919 mHoverObjects->deleteAllNodes(); 920 for (std::vector<LLViewerObject*>::iterator iter = objects.begin(); 921 iter != objects.end(); ++iter) 922 { 923 LLViewerObject* cur_objectp = *iter; 924 LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); 925 nodep->selectTE(face, TRUE); 926 mHoverObjects->addNodeAtEnd(nodep); 927 } 928 929 requestObjectPropertiesFamily(objectp); 930 } 931 932 return mHoverObjects; 933} 934 935LLSelectNode *LLSelectMgr::getHoverNode() 936{ 937 return mHoverObjects->getFirstRootNode(); 938} 939 940LLSelectNode *LLSelectMgr::getPrimaryHoverNode() 941{ 942 return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject]; 943} 944 945void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) 946{ 947 if (!objectp) 948 { 949 return; 950 } 951 952 if (objectp->getPCode() != LL_PCODE_VOLUME) 953 { 954 return; 955 } 956 957 if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) 958 || (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove())) 959 { 960 // only select my own objects 961 return; 962 } 963 964 mRectSelectedObjects.insert(objectp); 965} 966 967void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp) 968{ 969 if (!objectp) 970 { 971 return; 972 } 973 974 LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot(); 975 976 highlightObjectOnly(root_obj); 977 978 LLViewerObject::const_child_list_t& child_list = root_obj->getChildren(); 979 for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); 980 iter != child_list.end(); iter++) 981 { 982 LLViewerObject* child = *iter; 983 highlightObjectOnly(child); 984 } 985} 986 987// Note that this ignores the "select owned only" flag 988// It's also more efficient than calling the single-object version over and over. 989void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& objects) 990{ 991 for (std::vector<LLViewerObject*>::const_iterator iter1 = objects.begin(); 992 iter1 != objects.end(); ++iter1) 993 { 994 LLViewerObject* object = *iter1; 995 996 if (!object) 997 { 998 continue; 999 } 1000 if (object->getPCode() != LL_PCODE_VOLUME) 1001 { 1002 continue; 1003 } 1004 1005 LLViewerObject* root = (LLViewerObject*)object->getRoot(); 1006 mRectSelectedObjects.insert(root); 1007 1008 LLViewerObject::const_child_list_t& child_list = root->getChildren(); 1009 for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin(); 1010 iter2 != child_list.end(); iter2++) 1011 { 1012 LLViewerObject* child = *iter2; 1013 mRectSelectedObjects.insert(child); 1014 } 1015 } 1016} 1017 1018void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp) 1019{ 1020 if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) 1021 { 1022 return; 1023 } 1024 1025 mRectSelectedObjects.erase(objectp); 1026} 1027 1028void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp) 1029{ 1030 if (!objectp) 1031 { 1032 return; 1033 } 1034 1035 LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot(); 1036 1037 unhighlightObjectOnly(root_obj); 1038 1039 LLViewerObject::const_child_list_t& child_list = root_obj->getChildren(); 1040 for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); 1041 iter != child_list.end(); iter++) 1042 { 1043 LLViewerObject* child = *iter; 1044 unhighlightObjectOnly(child); 1045 } 1046} 1047 1048 1049void LLSelectMgr::unhighlightAll() 1050{ 1051 mRectSelectedObjects.clear(); 1052 mHighlightedObjects->deleteAllNodes(); 1053} 1054 1055LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects() 1056{ 1057 if (!mHighlightedObjects->getNumNodes()) 1058 { 1059 return NULL; 1060 } 1061 1062 //clear primary object 1063 mSelectedObjects->mPrimaryObject = NULL; 1064 1065 for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin(); 1066 iter != getHighlightedObjects()->end(); ) 1067 { 1068 LLObjectSelection::iterator curiter = iter++; 1069 1070 LLSelectNode *nodep = *curiter; 1071 LLViewerObject* objectp = nodep->getObject(); 1072 1073 if (!canSelectObject(objectp)) 1074 { 1075 continue; 1076 } 1077 1078 // already selected 1079 if (objectp->isSelected()) 1080 { 1081 continue; 1082 } 1083 1084 LLSelectNode* new_nodep = new LLSelectNode(*nodep); 1085 mSelectedObjects->addNode(new_nodep); 1086 1087 // flag this object as selected 1088 objectp->setSelected(TRUE); 1089 1090 mSelectedObjects->mSelectType = getSelectTypeForObject(objectp); 1091 1092 // request properties on root objects 1093 if (objectp->isRootEdit()) 1094 { 1095 requestObjectPropertiesFamily(objectp); 1096 } 1097 } 1098 1099 // pack up messages to let sim know these objects are selected 1100 sendSelect(); 1101 unhighlightAll(); 1102 updateSelectionCenter(); 1103 saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); 1104 updatePointAt(); 1105 1106 if (mSelectedObjects->getObjectCount()) 1107 { 1108 gEditMenuHandler = this; 1109 } 1110 1111 return mSelectedObjects; 1112} 1113 1114void LLSelectMgr::deselectHighlightedObjects() 1115{ 1116 BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts"); 1117 for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin(); 1118 iter != mRectSelectedObjects.end(); iter++) 1119 { 1120 LLViewerObject *objectp = *iter; 1121 if (!select_linked_set) 1122 { 1123 deselectObjectOnly(objectp); 1124 } 1125 else 1126 { 1127 LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot(); 1128 if (root_object->isSelected()) 1129 { 1130 deselectObjectAndFamily(root_object); 1131 } 1132 } 1133 } 1134 1135 unhighlightAll(); 1136} 1137 1138void LLSelectMgr::addGridObject(LLViewerObject* objectp) 1139{ 1140 LLSelectNode* nodep = new LLSelectNode(objectp, FALSE); 1141 mGridObjects.addNodeAtEnd(nodep); 1142 1143 LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); 1144 for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); 1145 iter != child_list.end(); iter++) 1146 { 1147 LLViewerObject* child = *iter; 1148 nodep = new LLSelectNode(child, FALSE); 1149 mGridObjects.addNodeAtEnd(nodep); 1150 } 1151} 1152 1153void LLSelectMgr::clearGridObjects() 1154{ 1155 mGridObjects.deleteAllNodes(); 1156} 1157 1158void LLSelectMgr::setGridMode(EGridMode mode) 1159{ 1160 mGridMode = mode; 1161 gSavedSettings.setS32("GridMode", mode); 1162 updateSelectionCenter(); 1163 mGridValid = FALSE; 1164} 1165 1166void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale) 1167{ 1168 mGridObjects.cleanupNodes(); 1169 1170 LLViewerObject* first_grid_object = mGridObjects.getFirstObject(); 1171 1172 if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount()) 1173 { 1174 //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject()); 1175 LLBBox bbox = mSavedSelectionBBox; 1176 mGridOrigin = mSavedSelectionBBox.getCenterAgent(); 1177 mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f; 1178 1179 // DEV-12570 Just taking the saved selection box rotation prevents 1180 // wild rotations of linked sets while in local grid mode 1181 //if(mSelectedObjects->getObjectCount() < 2 || !root || root->mDrawable.isNull()) 1182 { 1183 mGridRotation = mSavedSelectionBBox.getRotation(); 1184 } 1185 /*else //set to the root object 1186 { 1187 mGridRotation = root->getRenderRotation(); 1188 }*/ 1189 } 1190 else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull()) 1191 { 1192 mGridRotation = first_grid_object->getRenderRotation(); 1193 LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition(); 1194 1195 LLVector4a min_extents(F32_MAX); 1196 LLVector4a max_extents(-F32_MAX); 1197 BOOL grid_changed = FALSE; 1198 for (LLObjectSelection::iterator iter = mGridObjects.begin(); 1199 iter != mGridObjects.end(); ++iter) 1200 { 1201 LLViewerObject* object = (*iter)->getObject(); 1202 LLDrawable* drawable = object->mDrawable; 1203 if (drawable) 1204 { 1205 const LLVector4a* ext = drawable->getSpatialExtents(); 1206 update_min_max(min_extents, max_extents, ext[0]); 1207 update_min_max(min_extents, max_extents, ext[1]); 1208 grid_changed = TRUE; 1209 } 1210 } 1211 if (grid_changed) 1212 { 1213 LLVector4a center, size; 1214 center.setAdd(min_extents, max_extents); 1215 center.mul(0.5f); 1216 size.setSub(max_extents, min_extents); 1217 size.mul(0.5f); 1218 1219 mGridOrigin.set(center.getF32ptr()); 1220 LLDrawable* drawable = first_grid_object->mDrawable; 1221 if (drawable && drawable->isActive()) 1222 { 1223 mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix(); 1224 } 1225 mGridScale.set(size.getF32ptr()); 1226 } 1227 } 1228 else // GRID_MODE_WORLD or just plain default 1229 { 1230 const BOOL non_root_ok = TRUE; 1231 LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok); 1232 1233 mGridOrigin.clearVec(); 1234 mGridRotation.loadIdentity(); 1235 1236 mSelectedObjects->mSelectType = getSelectTypeForObject( first_object ); 1237 1238 switch (mSelectedObjects->mSelectType) 1239 { 1240 case SELECT_TYPE_ATTACHMENT: 1241 if (first_object && first_object->getRootEdit()->mDrawable.notNull()) 1242 { 1243 // this means this object *has* to be an attachment 1244 LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent(); 1245 mGridOrigin = attachment_point_xform->getWorldPosition(); 1246 mGridRotation = attachment_point_xform->getWorldRotation(); 1247 mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution"); 1248 } 1249 break; 1250 case SELECT_TYPE_HUD: 1251 // use HUD-scaled grid 1252 mGridScale = LLVector3(0.25f, 0.25f, 0.25f); 1253 break; 1254 case SELECT_TYPE_WORLD: 1255 mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution"); 1256 break; 1257 } 1258 } 1259 llassert(mGridOrigin.isFinite()); 1260 1261 origin = mGridOrigin; 1262 rotation = mGridRotation; 1263 scale = mGridScale; 1264 mGridValid = TRUE; 1265} 1266 1267//----------------------------------------------------------------------------- 1268// remove() - an array of objects 1269//----------------------------------------------------------------------------- 1270 1271void LLSelectMgr::remove(std::vector<LLViewerObject*>& objects) 1272{ 1273 for (std::vector<LLViewerObject*>::iterator iter = objects.begin(); 1274 iter != objects.end(); ++iter) 1275 { 1276 LLViewerObject* objectp = *iter; 1277 LLSelectNode* nodep = mSelectedObjects->findNode(objectp); 1278 if (nodep) 1279 { 1280 objectp->setSelected(FALSE); 1281 mSelectedObjects->removeNode(nodep); 1282 nodep = NULL; 1283 } 1284 } 1285 updateSelectionCenter(); 1286 dialog_refresh_all(); 1287} 1288 1289 1290//----------------------------------------------------------------------------- 1291// remove() - a single object 1292//----------------------------------------------------------------------------- 1293void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) 1294{ 1295 // get object node (and verify it is in the selected list) 1296 LLSelectNode *nodep = mSelectedObjects->findNode(objectp); 1297 if (!nodep) 1298 { 1299 return; 1300 } 1301 1302 // if face = all, remove object from list 1303 if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES)) 1304 { 1305 // Remove all faces (or the object doesn't have faces) so remove the node 1306 mSelectedObjects->removeNode(nodep); 1307 nodep = NULL; 1308 objectp->setSelected( FALSE ); 1309 } 1310 else if (0 <= te && te < SELECT_MAX_TES) 1311 { 1312 // ...valid face, check to see if it was on 1313 if (nodep->isTESelected(te)) 1314 { 1315 nodep->selectTE(te, FALSE); 1316 } 1317 else 1318 { 1319 llerrs << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; 1320 return; 1321 } 1322 1323 // ...check to see if this operation turned off all faces 1324 BOOL found = FALSE; 1325 for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++) 1326 { 1327 found = found || nodep->isTESelected(i); 1328 } 1329 1330 // ...all faces now turned off, so remove 1331 if (!found) 1332 { 1333 mSelectedObjects->removeNode(nodep); 1334 nodep = NULL; 1335 objectp->setSelected( FALSE ); 1336 // *FIXME: Doesn't update simulator that object is no longer selected 1337 } 1338 } 1339 else 1340 { 1341 // ...out of range face 1342 llerrs << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; 1343 } 1344 1345 updateSelectionCenter(); 1346 dialog_refresh_all(); 1347} 1348 1349 1350//----------------------------------------------------------------------------- 1351// removeAll() 1352//----------------------------------------------------------------------------- 1353void LLSelectMgr::removeAll() 1354{ 1355 for (LLObjectSelection::iterator iter = mSelectedObjects->begin(); 1356 iter != mSelectedObjects->end(); iter++ ) 1357 { 1358 LLViewerObject *objectp = (*iter)->getObject(); 1359 objectp->setSelected( FALSE ); 1360 } 1361 1362 mSelectedObjects->deleteAllNodes(); 1363 1364 updateSelectionCenter(); 1365 dialog_refresh_all(); 1366} 1367 1368//----------------------------------------------------------------------------- 1369// promoteSelectionToRoot() 1370//----------------------------------------------------------------------------- 1371void LLSelectMgr::promoteSelectionToRoot() 1372{ 1373 std::set<LLViewerObject*> selection_set; 1374 1375 BOOL selection_changed = FALSE; 1376 1377 for (LLObjectSelection::iterator iter = getSelection()->begin(); 1378 iter != getSelection()->end(); ) 1379 { 1380 LLObjectSelection::iterator curiter = iter++; 1381 LLSelectNode* nodep = *curiter; 1382 LLViewerObject* object = nodep->getObject(); 1383 1384 if (nodep->mIndividualSelection) 1385 { 1386 selection_changed = TRUE; 1387 } 1388 1389 LLViewerObject* parentp = object; 1390 while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild())) 1391 { 1392 parentp = (LLViewerObject*)parentp->getParent(); 1393 } 1394 1395 selection_set.insert(parentp); 1396 } 1397 1398 if (selection_changed) 1399 { 1400 deselectAll(); 1401 1402 std::set<LLViewerObject*>::iterator set_iter; 1403 for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter) 1404 { 1405 selectObjectAndFamily(*set_iter); 1406 } 1407 } 1408} 1409 1410//----------------------------------------------------------------------------- 1411// demoteSelectionToIndividuals() 1412//----------------------------------------------------------------------------- 1413void LLSelectMgr::demoteSelectionToIndividuals() 1414{ 1415 std::vector<LLViewerObject*> objects; 1416 1417 for (LLObjectSelection::root_iterator iter = getSelection()->root_begin(); 1418 iter != getSelection()->root_end(); iter++) 1419 { 1420 LLViewerObject* object = (*iter)->getObject(); 1421 object->addThisAndNonJointChildren(objects); 1422 } 1423 1424 if (!objects.empty()) 1425 { 1426 deselectAll(); 1427 for (std::vector<LLViewerObject*>::iterator iter = objects.begin(); 1428 iter != objects.end(); ++iter) 1429 { 1430 LLViewerObject* objectp = *iter; 1431 selectObjectOnly(objectp); 1432 } 1433 } 1434} 1435 1436//----------------------------------------------------------------------------- 1437// dump() 1438//----------------------------------------------------------------------------- 1439void LLSelectMgr::dump() 1440{ 1441 llinfos << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << llendl; 1442 1443 llinfos << "TE mode " << mTEMode << llendl; 1444 1445 S32 count = 0; 1446 for (LLObjectSelection::iterator iter = getSelection()->begin(); 1447 iter != getSelection()->end(); iter++ ) 1448 { 1449 LLViewerObject* objectp = (*iter)->getObject(); 1450 llinfos << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl; 1451 llinfos << " hasLSL " << objectp->flagScripted() << llendl; 1452 llinfos << " hasTouch " << objectp->flagHandleTouch() << llendl; 1453 llinfos << " hasMoney " << objectp->flagTakesMoney() << llendl; 1454 llinfos << " getposition " << objectp->getPosition() << llendl; 1455 llinfos << " getpositionAgent " << objectp->getPositionAgent() << llendl; 1456 llinfos << " getpositionRegion " << objectp->getPositionRegion() << llendl; 1457 llinfos << " getpositionGlobal " << objectp->getPositionGlobal() << llendl; 1458 LLDrawable* drawablep = objectp->mDrawable; 1459 llinfos << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << llendl; 1460 llinfos << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << llendl; 1461 count++; 1462 } 1463 1464 // Face iterator 1465 for (LLObjectSelection::iterator iter = getSelection()->begin(); 1466 iter != getSelection()->end(); iter++ ) 1467 { 1468 LLSelectNode* node = *iter; 1469 LLViewerObject* objectp = node->getObject(); 1470 if (!objectp) 1471 continue; 1472 for (S32 te = 0; te < objectp->getNumTEs(); ++te ) 1473 { 1474 if (node->isTESelected(te)) 1475 { 1476 llinfos << "Object " << objectp << " te " << te << llendl; 1477 } 1478 } 1479 } 1480 1481 llinfos << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << llendl; 1482 1483 llinfos << "Center global " << mSelectionCenterGlobal << llendl; 1484} 1485 1486//----------------------------------------------------------------------------- 1487// cleanup() 1488//----------------------------------------------------------------------------- 1489void LLSelectMgr::cleanup() 1490{ 1491 mSilhouetteImagep = NULL; 1492} 1493 1494 1495//--------------------------------------------------------------------------- 1496// Manipulate properties of selected objects 1497//--------------------------------------------------------------------------- 1498 1499struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor 1500{ 1501 virtual bool apply(LLViewerObject* object) 1502 { 1503 if (object->permModify()) 1504 { 1505 object->sendTEUpdate(); 1506 } 1507 return true; 1508 } 1509}; 1510 1511//----------------------------------------------------------------------------- 1512// selectionSetImage() 1513//----------------------------------------------------------------------------- 1514// *TODO: re-arch texture applying out of lltooldraganddrop 1515void LLSelectMgr::selectionSetImage(const LLUUID& imageid) 1516{ 1517 // First for (no copy) textures and multiple object selection 1518 LLViewerInventoryItem* item = gInventory.getItem(imageid); 1519 if(item 1520 && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) 1521 && (mSelectedObjects->getNumNodes() > 1) ) 1522 { 1523 llwarns << "Attempted to apply no-copy texture to multiple objects" 1524 << llendl; 1525 return; 1526 } 1527 1528 struct f : public LLSelectedTEFunctor 1529 { 1530 LLViewerInventoryItem* mItem; 1531 LLUUID mImageID; 1532 f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {} 1533 bool apply(LLViewerObject* objectp, S32 te) 1534 { 1535 if (mItem) 1536 { 1537 if (te == -1) // all faces 1538 { 1539 LLToolDragAndDrop::dropTextureAllFaces(objectp, 1540 mItem, 1541 LLToolDragAndDrop::SOURCE_AGENT, 1542 LLUUID::null); 1543 } 1544 else // one face 1545 { 1546 LLToolDragAndDrop::dropTextureOneFace(objectp, 1547 te, 1548 mItem, 1549 LLToolDragAndDrop::SOURCE_AGENT, 1550 LLUUID::null); 1551 } 1552 } 1553 else // not an inventory item 1554 { 1555 // Texture picker defaults aren't inventory items 1556 // * Don't need to worry about permissions for them 1557 // * Can just apply the texture and be done with it. 1558 objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); 1559 } 1560 return true; 1561 } 1562 } setfunc(item, imageid); 1563 getSelection()->applyToTEs(&setfunc); 1564 1565 struct g : public LLSelectedObjectFunctor 1566 { 1567 LLViewerInventoryItem* mItem; 1568 g(LLViewerInventoryItem* item) : mItem(item) {} 1569 virtual bool apply(LLViewerObject* object) 1570 { 1571 if (!mItem) 1572 { 1573 object->sendTEUpdate(); 1574 // 1 particle effect per object 1575 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); 1576 effectp->setSourceObject(gAgentAvatarp); 1577 effectp->setTargetObject(object); 1578 effectp->setDuration(LL_HUD_DUR_SHORT); 1579 effectp->setColor(LLColor4U(gAgent.getEffectColor())); 1580 } 1581 return true; 1582 } 1583 } sendfunc(item); 1584 getSelection()->applyToObjects(&sendfunc); 1585} 1586 1587//----------------------------------------------------------------------------- 1588// selectionSetColor() 1589//----------------------------------------------------------------------------- 1590void LLSelectMgr::selectionSetColor(const LLColor4 &color) 1591{ 1592 struct f : public LLSelectedTEFunctor 1593 { 1594 LLColor4 mColor; 1595 f(const LLColor4& c) : mColor(c) {} 1596 bool apply(LLViewerObject* object, S32 te) 1597 { 1598 if (object->permModify()) 1599 { 1600 object->setTEColor(te, mColor); 1601 } 1602 return true; 1603 } 1604 } setfunc(color); 1605 getSelection()->applyToTEs(&setfunc); 1606 1607 LLSelectMgrSendFunctor sendfunc; 1608 getSelection()->applyToObjects(&sendfunc); 1609} 1610 1611//----------------------------------------------------------------------------- 1612// selectionSetColorOnly() 1613//----------------------------------------------------------------------------- 1614void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color) 1615{ 1616 struct f : public LLSelectedTEFunctor 1617 { 1618 LLColor4 mColor; 1619 f(const LLColor4& c) : mColor(c) {} 1620 bool apply(LLViewerObject* object, S32 te) 1621 { 1622 if (object->permModify()) 1623 { 1624 LLColor4 prev_color = object->getTE(te)->getColor(); 1625 mColor.mV[VALPHA] = prev_color.mV[VALPHA]; 1626 // update viewer side color in anticipation of update from simulator 1627 object->setTEColor(te, mColor); 1628 } 1629 return true; 1630 } 1631 } setfunc(color); 1632 getSelection()->applyToTEs(&setfunc); 1633 1634 LLSelectMgrSendFunctor sendfunc; 1635 getSelection()->applyToObjects(&sendfunc); 1636} 1637 1638//----------------------------------------------------------------------------- 1639// selectionSetAlphaOnly() 1640//----------------------------------------------------------------------------- 1641void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha) 1642{ 1643 struct f : public LLSelectedTEFunctor 1644 { 1645 F32 mAlpha; 1646 f(const F32& a) : mAlpha(a) {} 1647 bool apply(LLViewerObject* object, S32 te) 1648 { 1649 if (object->permModify()) 1650 { 1651 LLColor4 prev_color = object->getTE(te)->getColor(); 1652 prev_color.mV[VALPHA] = mAlpha; 1653 // update viewer side color in anticipation of update from simulator 1654 object->setTEColor(te, prev_color); 1655 } 1656 return true; 1657 } 1658 } setfunc(alpha); 1659 getSelection()->applyToTEs(&setfunc); 1660 1661 LLSelectMgrSendFunctor sendfunc; 1662 getSelection()->applyToObjects(&sendfunc); 1663} 1664 1665void LLSelectMgr::selectionRevertColors() 1666{ 1667 struct f : public LLSelectedTEFunctor 1668 { 1669 LLObjectSelectionHandle mSelectedObjects; 1670 f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} 1671 bool apply(LLViewerObject* object, S32 te) 1672 { 1673 if (object->permModify()) 1674 { 1675 LLSelectNode* nodep = mSelectedObjects->findNode(object); 1676 if (nodep && te < (S32)nodep->mSavedColors.size()) 1677 { 1678 LLColor4 color = nodep->mSavedColors[te]; 1679 // update viewer side color in anticipation of update from simulator 1680 object->setTEColor(te, color); 1681 } 1682 } 1683 return true; 1684 } 1685 } setfunc(mSelectedObjects); 1686 getSelection()->applyToTEs(&setfunc); 1687 1688 LLSelectMgrSendFunctor sendfunc; 1689 getSelection()->applyToObjects(&sendfunc); 1690} 1691 1692BOOL LLSelectMgr::selectionRevertTextures() 1693{ 1694 struct f : public LLSelectedTEFunctor 1695 { 1696 LLObjectSelectionHandle mSelectedObjects; 1697 f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} 1698 bool apply(LLViewerObject* object, S32 te) 1699 { 1700 if (object->permModify()) 1701 { 1702 LLSelectNode* nodep = mSelectedObjects->findNode(object); 1703 if (nodep && te < (S32)nodep->mSavedTextures.size()) 1704 { 1705 LLUUID id = nodep->mSavedTextures[te]; 1706 // update textures on viewer side 1707 if (id.isNull()) 1708 { 1709 // this was probably a no-copy texture, leave image as-is 1710 return FALSE; 1711 } 1712 else 1713 { 1714 object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); 1715 } 1716 } 1717 } 1718 return true; 1719 } 1720 } setfunc(mSelectedObjects); 1721 BOOL revert_successful = getSelection()->applyToTEs(&setfunc); 1722 1723 LLSelectMgrSendFunctor sendfunc; 1724 getSelection()->applyToObjects(&sendfunc); 1725 1726 return revert_successful; 1727} 1728 1729void LLSelectMgr::selectionSetBumpmap(U8 bumpmap) 1730{ 1731 struct f : public LLSelectedTEFunctor 1732 { 1733 U8 mBump; 1734 f(const U8& b) : mBump(b) {} 1735 bool apply(LLViewerObject* object, S32 te) 1736 { 1737 if (object->permModify()) 1738 { 1739 // update viewer side color in anticipation of update from simulator 1740 object->setTEBumpmap(te, mBump); 1741 } 1742 return true; 1743 } 1744 } setfunc(bumpmap); 1745 getSelection()->applyToTEs(&setfunc); 1746 1747 LLSelectMgrSendFunctor sendfunc; 1748 getSelection()->applyToObjects(&sendfunc); 1749} 1750 1751void LLSelectMgr::selectionSetTexGen(U8 texgen) 1752{ 1753 struct f : public LLSelectedTEFunctor 1754 { 1755 U8 mTexgen; 1756 f(const U8& t) : mTexgen(t) {} 1757 bool apply(LLViewerObject* object, S32 te) 1758 { 1759 if (object->permModify()) 1760 { 1761 // update viewer side color in anticipation of update from simulator 1762 object->setTETexGen(te, mTexgen); 1763 } 1764 return true; 1765 } 1766 } setfunc(texgen); 1767 getSelection()->applyToTEs(&setfunc); 1768 1769 LLSelectMgrSendFunctor sendfunc; 1770 getSelection()->applyToObjects(&sendfunc); 1771} 1772 1773 1774void LLSelectMgr::selectionSetShiny(U8 shiny) 1775{ 1776 struct f : public LLSelectedTEFunctor 1777 { 1778 U8 mShiny; 1779 f(const U8& t) : mShiny(t) {} 1780 bool apply(LLViewerObject* object, S32 te) 1781 { 1782 if (object->permModify()) 1783 { 1784 // update viewer side color in anticipation of update from simulator 1785 object->setTEShiny(te, mShiny); 1786 } 1787 return true; 1788 } 1789 } setfunc(shiny); 1790 getSelection()->applyToTEs(&setfunc); 1791 1792 LLSelectMgrSendFunctor sendfunc; 1793 getSelection()->applyToObjects(&sendfunc); 1794} 1795 1796void LLSelectMgr::selectionSetFullbright(U8 fullbright) 1797{ 1798 struct f : public LLSelectedTEFunctor 1799 { 1800 U8 mFullbright; 1801 f(const U8& t) : mFullbright(t) {} 1802 bool apply(LLViewerObject* object, S32 te) 1803 { 1804 if (object->permModify()) 1805 { 1806 // update viewer side color in anticipation of update from simulator 1807 object->setTEFullbright(te, mFullbright…
Large files files are truncated, but you can click here to view the full file