PageRenderTime 195ms CodeModel.GetById 10ms app.highlight 166ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llselectmgr.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2415 lines | 1817 code | 300 blank | 298 comment | 264 complexity | ca67b7068cb2644ccd7bc23e3c748406 MD5 | raw file

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