diff options
Diffstat (limited to 'indra/newview/llselectmgr.h')
| -rw-r--r-- | indra/newview/llselectmgr.h | 2116 | 
1 files changed, 1058 insertions, 1058 deletions
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 2470717db3..78f51d0aec 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -1,1058 +1,1058 @@ -/**  - * @file llselectmgr.h - * @brief A manager for selected objects and TEs. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLSELECTMGR_H -#define LL_LLSELECTMGR_H - -#include "llcharacter.h" -#include "lleditmenuhandler.h" -#include "llundo.h" -#include "lluuid.h" -#include "llpointer.h" -#include "llsafehandle.h" -#include "llsaleinfo.h" -#include "llcategory.h" -#include "v3dmath.h" -#include "llquaternion.h" -#include "llcoord.h" -#include "llframetimer.h" -#include "llbbox.h" -#include "llpermissions.h" -#include "llcontrol.h" -#include "llviewerobject.h"	// LLObjectSelection::getSelectedTEValue template -#include "llmaterial.h" - -#include <deque> -#include <boost/iterator/filter_iterator.hpp> -#include <boost/signals2.hpp> -#include <boost/make_shared.hpp>	// boost::make_shared - -class LLMessageSystem; -class LLViewerTexture; -class LLColor4; -class LLVector3; -class LLSelectNode; - -const U8 UPD_NONE      		= 0x00; -const U8 UPD_POSITION  		= 0x01; -const U8 UPD_ROTATION  		= 0x02; -const U8 UPD_SCALE     		= 0x04; -const U8 UPD_LINKED_SETS 	= 0x08; -const U8 UPD_UNIFORM 		= 0x10;	// used with UPD_SCALE - -// This is used by the DeRezObject message to determine where to put -// derezed tasks. -enum EDeRezDestination -{ -	DRD_SAVE_INTO_AGENT_INVENTORY = 0, -	DRD_ACQUIRE_TO_AGENT_INVENTORY = 1,		// try to leave copy in world -	DRD_SAVE_INTO_TASK_INVENTORY = 2, -	DRD_ATTACHMENT = 3, -	DRD_TAKE_INTO_AGENT_INVENTORY = 4,		// delete from world -	DRD_FORCE_TO_GOD_INVENTORY = 5,			// force take copy -	DRD_TRASH = 6, -	DRD_ATTACHMENT_TO_INV = 7, -	DRD_ATTACHMENT_EXISTS = 8, -	DRD_RETURN_TO_OWNER = 9,				// back to owner's inventory -	DRD_RETURN_TO_LAST_OWNER = 10,			// deeded object back to last owner's inventory - -	DRD_COUNT = 11 -}; - - -const S32 SELECT_ALL_TES = -1; -const S32 SELECT_MAX_TES = 32; - -// Do something to all objects in the selection manager. -// The bool return value can be used to indicate if all -// objects are identical (gathering information) or if -// the operation was successful. -struct LLSelectedObjectFunctor -{ -	virtual ~LLSelectedObjectFunctor() {}; -	virtual bool apply(LLViewerObject* object) = 0; -}; - -// Do something to all select nodes in the selection manager. -// The bool return value can be used to indicate if all -// objects are identical (gathering information) or if -// the operation was successful. -struct LLSelectedNodeFunctor -{ -	virtual ~LLSelectedNodeFunctor() {}; -	virtual bool apply(LLSelectNode* node) = 0; -}; - -struct LLSelectedTEFunctor -{ -	virtual ~LLSelectedTEFunctor() {}; -	virtual bool apply(LLViewerObject* object, S32 face) = 0; -}; - -struct LLSelectedTEMaterialFunctor -{ -	virtual ~LLSelectedTEMaterialFunctor() {}; -	virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0; -}; - -template <typename T> struct LLSelectedTEGetFunctor -{ -	virtual ~LLSelectedTEGetFunctor() {}; -	virtual T get(LLViewerObject* object, S32 te) = 0; -}; - -template <typename T> struct LLCheckIdenticalFunctor -{ -	static bool same(const T& a, const T& b, const T& tolerance); -}; - -typedef enum e_send_type -{ -	SEND_ONLY_ROOTS, -	SEND_INDIVIDUALS, -	SEND_ROOTS_FIRST, // useful for serial undos on linked sets -	SEND_CHILDREN_FIRST // useful for serial transforms of linked sets -} ESendType; - -typedef enum e_grid_mode -{ -	GRID_MODE_WORLD, -	GRID_MODE_LOCAL, -	GRID_MODE_REF_OBJECT -} EGridMode; - -typedef enum e_action_type -{ -	SELECT_ACTION_TYPE_BEGIN, -	SELECT_ACTION_TYPE_PICK, -	SELECT_ACTION_TYPE_MOVE, -	SELECT_ACTION_TYPE_ROTATE, -	SELECT_ACTION_TYPE_SCALE, -	NUM_ACTION_TYPES -}EActionType; - -typedef enum e_selection_type -{ -	SELECT_TYPE_WORLD, -	SELECT_TYPE_ATTACHMENT, -	SELECT_TYPE_HUD -}ESelectType; - -typedef std::vector<LLPointer<LLGLTFMaterial> > gltf_materials_vec_t; - -const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; - -// Contains information about a selected object, particularly which TEs are selected. -class LLSelectNode -{ -public: -	LLSelectNode(LLViewerObject* object, bool do_glow); -	LLSelectNode(const LLSelectNode& nodep); -	~LLSelectNode(); - -	void selectAllTEs(bool b); -	void selectTE(S32 te_index, bool selected); -	bool isTESelected(S32 te_index) const; -	bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; } -	S32 getLastSelectedTE() const; -	S32 getLastOperatedTE() const { return mLastTESelected; } -	S32 getTESelectMask() { return mTESelectMask; } -	void renderOneSilhouette(const LLColor4 &color); -	void setTransient(bool transient) { mTransient = transient; } -	bool isTransient() const { return mTransient; } -	LLViewerObject* getObject(); -	void setObject(LLViewerObject* object); -	// *NOTE: invalidate stored textures and colors when # faces change -    // Used by tools floater's color/texture pickers to restore changes -	void saveColors(); -	void saveShinyColors(); -	void saveTextures(const uuid_vec_t& textures); -	void saveTextureScaleRatios(LLRender::eTexIndex index_to_query); - -    // GLTF materials are applied to objects by ids, -    // overrides get applied on top of materials resulting in -    // final gltf material that users see. -    // Ids get applied and restored by tools floater, -    // overrides get applied in live material editor -    void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials); - -	bool allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const; - -public: -	bool			mIndividualSelection;		// For root objects and objects individually selected - -	bool			mTransient; -	bool			mValid;				// is extra information valid? -	LLPermissions*	mPermissions; -	LLSaleInfo		mSaleInfo; -	LLAggregatePermissions mAggregatePerm; -	LLAggregatePermissions mAggregateTexturePerm; -	LLAggregatePermissions mAggregateTexturePermOwner; -	std::string		mName; -	std::string		mDescription; -	LLCategory		mCategory; -	S16				mInventorySerial; -	LLVector3		mSavedPositionLocal;	// for interactively modifying object position -	LLVector3		mLastPositionLocal; -	LLVector3d		mSavedPositionGlobal;	// for interactively modifying object position -	LLVector3		mSavedScale;			// for interactively modifying object scale -	LLVector3		mLastScale; -	LLQuaternion	mSavedRotation;			// for interactively modifying object rotation -	LLQuaternion	mLastRotation; -	bool			mDuplicated; -	LLVector3d		mDuplicatePos; -	LLQuaternion	mDuplicateRot; -	LLUUID			mItemID; -	LLUUID			mFolderID; -	LLUUID			mFromTaskID; -	std::string		mTouchName; -	std::string		mSitName; -	U64				mCreationDate; -	std::vector<LLColor4>	mSavedColors; -	std::vector<LLColor4>	mSavedShinyColors; -	uuid_vec_t		mSavedTextures; -    uuid_vec_t		mSavedGLTFMaterialIds; -    gltf_materials_vec_t mSavedGLTFOverrideMaterials; -	std::vector<LLVector3>  mTextureScaleRatios; -	std::vector<LLVector3>	mSilhouetteVertices;	// array of vertices to render silhouette of object -	std::vector<LLVector3>	mSilhouetteNormals;	// array of normals to render silhouette of object -	bool					mSilhouetteExists;	// need to generate silhouette? - -protected: -	LLPointer<LLViewerObject>	mObject; -	S32				mTESelectMask; -	S32				mLastTESelected; -}; - -class LLObjectSelection : public LLRefCount -{ -	friend class LLSelectMgr; -	friend class LLSafeHandle<LLObjectSelection>; -	friend class LLSelectionCallbackData; - -protected: -	~LLObjectSelection(); - -public: -	typedef std::list<LLSelectNode*> list_t; - -	// Iterators -	struct is_non_null -	{ -		bool operator()(LLSelectNode* node) -		{ -			return (node->getObject() != NULL); -		} -	}; -	typedef boost::filter_iterator<is_non_null, list_t::iterator > iterator; -	iterator begin() { return iterator(mList.begin(), mList.end()); } -	iterator end() { return iterator(mList.end(), mList.end()); } - -	struct is_valid -	{ -		bool operator()(LLSelectNode* node) -		{ -			return (node->getObject() != NULL) && node->mValid; -		} -	}; -	typedef boost::filter_iterator<is_valid, list_t::iterator > valid_iterator; -	valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); } -	valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); } - -	struct is_root -	{ -		bool operator()(LLSelectNode* node); -	}; -	typedef boost::filter_iterator<is_root, list_t::iterator > root_iterator; -	root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); } -	root_iterator root_end() { return root_iterator(mList.end(), mList.end()); } -	 -	struct is_valid_root -	{ -		bool operator()(LLSelectNode* node); -	}; -	typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator; -	valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); } -	valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); } -	 -	struct is_root_object -	{ -		bool operator()(LLSelectNode* node); -	}; -	typedef boost::filter_iterator<is_root_object, list_t::iterator > root_object_iterator; -	root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); } -	root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); } -	 -public: -	LLObjectSelection(); - -	void updateEffects(); - -	bool isEmpty() const; - -	LLSelectNode*	getFirstNode(LLSelectedNodeFunctor* func = NULL); -	LLSelectNode*	getFirstRootNode(LLSelectedNodeFunctor* func = NULL, bool non_root_ok = false); -	LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, bool get_parent = false); -	LLViewerObject*	getFirstObject(); -	LLViewerObject*	getFirstRootObject(bool non_root_ok = false); -	 -	LLSelectNode*	getFirstMoveableNode(bool get_root_first = false); - -	LLViewerObject*	getFirstEditableObject(bool get_parent = false); -	LLViewerObject*	getFirstCopyableObject(bool get_parent = false); -	LLViewerObject* getFirstDeleteableObject(); -	LLViewerObject*	getFirstMoveableObject(bool get_parent = false); -	LLViewerObject*	getFirstUndoEnabledObject(bool get_parent = false); - -	/// Return the object that lead to this selection, possible a child -	LLViewerObject* getPrimaryObject() { return mPrimaryObject; } - -	// iterate through texture entries -	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance = false, T tolerance = T()); -	template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value); -	 -	S32 getNumNodes(); -	LLSelectNode* findNode(LLViewerObject* objectp); - -	// count members -	S32 getObjectCount(); -	F32 getSelectedObjectCost(); -	F32 getSelectedLinksetCost(); -	F32 getSelectedPhysicsCost(); -	F32 getSelectedLinksetPhysicsCost(); -	S32 getSelectedObjectRenderCost(); -	 -	F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL); -	U32 getSelectedObjectTriangleCount(S32* vcount = NULL); - -	S32 getTECount(); -	S32 getRootObjectCount(); - -	bool isMultipleTESelected(); -	bool contains(LLViewerObject* object); -	bool contains(LLViewerObject* object, S32 te); - -	// returns true is any node is currenly worn as an attachment -	bool isAttachment(); - -    bool checkAnimatedObjectEstTris(); -    bool checkAnimatedObjectLinkable(); -     -	// Apply functors to various subsets of the selected objects -	// If firstonly is false, returns the AND of all apply() calls. -	// Else returns true immediately if any apply() call succeeds (i.e. OR with early exit) -	bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false); -	bool applyToObjects(LLSelectedObjectFunctor* func); -	bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false); -	bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false); -	bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false); - -	/* -	 * Used to apply (no-copy) textures to the selected object or -	 * selected face/faces of the object. -	 * This method moves (no-copy) texture to the object's inventory -	 * and doesn't make copy of the texture for each face. -	 * Then this only texture is used for all selected faces. -	 */ -	void applyNoCopyTextureToTEs(LLViewerInventoryItem* item); -    /* -     * Multi-purpose function for applying PBR materials to the -     * selected object or faces, any combination of copy/mod/transfer -     * permission restrictions. This method moves the restricted -     * material to the object's inventory and doesn't make a copy of the -     * material for each face. Then this only material is used for -     * all selected faces. -     * Returns false if applying the material failed on one or more selected -     * faces. -     */ -    bool applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item); - -	ESelectType getSelectType() const { return mSelectType; } - -private: -	void addNode(LLSelectNode *nodep); -	void addNodeAtEnd(LLSelectNode *nodep); -	void moveNodeToFront(LLSelectNode *nodep); -	void removeNode(LLSelectNode *nodep); -	void deleteAllNodes(); -	void cleanupNodes(); - - -private: -	list_t mList; -	const LLObjectSelection &operator=(const LLObjectSelection &); - -	LLPointer<LLViewerObject> mPrimaryObject; -	std::map<LLPointer<LLViewerObject>, LLSelectNode*> mSelectNodeMap; -	ESelectType mSelectType; -}; - -typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle; - -// Build time optimization, generate this once in .cpp file -#ifndef LLSELECTMGR_CPP -extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance(); -#endif - -// For use with getFirstTest() -struct LLSelectGetFirstTest; - -// temporary storage, Ex: to attach objects after autopilot -class LLSelectionCallbackData -{ -public: -    LLSelectionCallbackData(); -    LLObjectSelectionHandle	getSelection() { return mSelectedObjects; } -private: -    LLObjectSelectionHandle					mSelectedObjects; -}; - -class LLSelectMgr : public LLEditMenuHandler, public LLSimpleton<LLSelectMgr> -{ -public: -	static bool					sRectSelectInclusive;	// do we need to surround an object to pick it? -	static bool					sRenderHiddenSelections;	// do we show selection silhouettes that are occluded? -	static bool					sRenderLightRadius;	// do we show the radius of selected lights? - -	static F32					sHighlightThickness; -	static F32					sHighlightUScale; -	static F32					sHighlightVScale; -	static F32					sHighlightAlpha; -	static F32					sHighlightAlphaTest; -	static F32					sHighlightUAnim; -	static F32					sHighlightVAnim; -	static LLColor4				sSilhouetteParentColor; -	static LLColor4				sSilhouetteChildColor; -	static LLColor4				sHighlightParentColor; -	static LLColor4				sHighlightChildColor; -	static LLColor4				sHighlightInspectColor; -	static LLColor4				sContextSilhouetteColor; - -	LLCachedControl<bool>					mHideSelectedObjects; -	LLCachedControl<bool>					mRenderHighlightSelections; -	LLCachedControl<bool>					mAllowSelectAvatar; -	LLCachedControl<bool>					mDebugSelectMgr; - -public: -    LLSelectMgr(); -    ~LLSelectMgr(); - -	static void cleanupGlobals(); - -	// LLEditMenuHandler interface -	virtual bool canUndo() const; -	virtual void undo(); - -	virtual bool canRedo() const; -	virtual void redo(); - -	virtual bool canDoDelete() const; -	virtual void doDelete(); - -	virtual void deselect(); -	virtual bool canDeselect() const; - -	virtual void duplicate(); -	virtual bool canDuplicate() const; - -	void clearSelections(); -	void update(); -	void updateEffects(); // Update HUD effects - -	// When we edit object's position/rotation/scale we set local -	// overrides and ignore any updates (override received valeus). -	// When we send data to server, we send local values and reset -	// overrides -	void resetObjectOverrides(); -	void resetObjectOverrides(LLObjectSelectionHandle selected_handle); -	void overrideObjectUpdates(); - -    void resetAvatarOverrides(); -    void overrideAvatarUpdates(); - -    struct AvatarPositionOverride -    { -        AvatarPositionOverride(); -        AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) : -            mLastPositionLocal(vec), -            mLastRotation(quat), -            mObject(obj) -        { -        } -        LLVector3 mLastPositionLocal; -        LLQuaternion mLastRotation; -        LLPointer<LLViewerObject> mObject; -    }; - -    // Avatar overrides should persist even after selection -    // was removed as long as edit floater is up -    typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t; -    uuid_av_override_map_t mAvatarOverridesMap; -public: - - -	// Returns the previous value of mForceSelection -	bool setForceSelection(bool force); - -	//////////////////////////////////////////////////////////////// -	// Selection methods -	//////////////////////////////////////////////////////////////// - -	//////////////////////////////////////////////////////////////// -	// Add -	//////////////////////////////////////////////////////////////// - -	// This method is meant to select an object, and then select all -	// of the ancestors and descendants. This should be the normal behavior. -	// -	// *NOTE: You must hold on to the object selection handle, otherwise -	// the objects will be automatically deselected in 1 frame. -	LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, bool add_to_end = false, bool ignore_select_owned = false); - -	// For when you want just a child object. -	LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES); - -	// Same as above, but takes a list of objects.  Used by rectangle select. -	LLObjectSelectionHandle selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list, bool send_to_sim = true); - -	// converts all objects currently highlighted to a selection, and returns it -	LLObjectSelectionHandle selectHighlightedObjects(); - -	LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1); -	LLSelectNode *getHoverNode(); -	LLSelectNode *getPrimaryHoverNode(); - -	void highlightObjectOnly(LLViewerObject *objectp); -	void highlightObjectAndFamily(LLViewerObject *objectp); -	void highlightObjectAndFamily(const std::vector<LLViewerObject*>& list); - -	//////////////////////////////////////////////////////////////// -	// Remove -	//////////////////////////////////////////////////////////////// - -	void deselectObjectOnly(LLViewerObject* object, bool send_to_sim = true); -	void deselectObjectAndFamily(LLViewerObject* object, bool send_to_sim = true, bool include_entire_object = false); - -	// Send deselect messages to simulator, then clear the list -	void deselectAll(); -	void deselectAllForStandingUp(); - -	// deselect only if nothing else currently referencing the selection -	void deselectUnused(); - -	// Deselect if the selection center is too far away from the agent. -	void deselectAllIfTooFar(); - -	// Removes all highlighted objects from current selection -	void deselectHighlightedObjects(); - -	void unhighlightObjectOnly(LLViewerObject *objectp); -	void unhighlightObjectAndFamily(LLViewerObject *objectp); -	void unhighlightAll(); - -	bool removeObjectFromSelections(const LLUUID &id); - -	//////////////////////////////////////////////////////////////// -	// Selection editing -	//////////////////////////////////////////////////////////////// -	bool linkObjects(); - -	bool unlinkObjects(); - -	void confirmUnlinkObjects(const LLSD& notification, const LLSD& response); - -	bool enableLinkObjects(); - -	bool enableUnlinkObjects(); - -	//////////////////////////////////////////////////////////////// -	// Selection accessors -	//////////////////////////////////////////////////////////////// -	LLObjectSelectionHandle	getSelection() { return mSelectedObjects; } -	// right now this just renders the selection with root/child colors instead of a single color -	LLObjectSelectionHandle	getEditSelection() { convertTransient(); return mSelectedObjects; } -	LLObjectSelectionHandle	getHighlightedObjects() { return mHighlightedObjects; } - -	//////////////////////////////////////////////////////////////// -	// Grid manipulation -	//////////////////////////////////////////////////////////////// -	void			addGridObject(LLViewerObject* objectp); -	void			clearGridObjects(); -	void			setGridMode(EGridMode mode); -	EGridMode		getGridMode() { return mGridMode; } -	void			getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false); - -	bool getTEMode() const { return mTEMode; } -	void setTEMode(bool b) { mTEMode = b; } - -	bool shouldShowSelection() const { return mShowSelection; } - -	LLBBox getBBoxOfSelection() const; -	LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; } - -	void dump(); -	void cleanup(); - -	void updateSilhouettes(); -	void renderSilhouettes(bool for_hud); -	void enableSilhouette(bool enable) { mRenderSilhouettes = enable; } -	 -	//////////////////////////////////////////////////////////////// -	// Utility functions that operate on the current selection -	//////////////////////////////////////////////////////////////// -	void saveSelectedObjectTransform(EActionType action_type); -	void saveSelectedObjectColors(); -	void saveSelectedShinyColors(); -	void saveSelectedObjectTextures(); - -	void selectionUpdatePhysics(bool use_physics); -	void selectionUpdateTemporary(bool is_temporary); -	void selectionUpdatePhantom(bool is_ghost); -	void selectionDump(); - -	bool selectionAllPCode(LLPCode code);		// all objects have this PCode -	bool selectionGetClickAction(U8 *out_action); -	bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same -	bool selectionGetGlow(F32 *glow); - -	void selectionSetPhysicsType(U8 type); -	void selectionSetGravity(F32 gravity); -	void selectionSetFriction(F32 friction); -	void selectionSetDensity(F32 density); -	void selectionSetRestitution(F32 restitution); -	void selectionSetMaterial(U8 material); -	bool selectionSetImage(const LLUUID& imageid); // could be item or asset id -    bool selectionSetGLTFMaterial(const LLUUID& mat_id); // material id only -	void selectionSetColor(const LLColor4 &color); -	void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels -	void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel -	void selectionRevertColors(); -	void selectionRevertShinyColors(); -	bool selectionRevertTextures(); -    void selectionRevertGLTFMaterials(); -	void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id ); -	void selectionSetTexGen( U8 texgen ); -	void selectionSetShiny( U8 shiny, const LLUUID &image_id ); -	void selectionSetFullbright( U8 fullbright ); -	void selectionSetMedia( U8 media_type, const LLSD &media_data ); -	void selectionSetClickAction(U8 action); -	void selectionSetIncludeInSearch(bool include_in_search); -	void selectionSetGlow(const F32 glow); -	void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1); -	void selectionRemoveMaterial(); - -	void selectionSetObjectPermissions(U8 perm_field, bool set, U32 perm_mask, bool override = false); -	void selectionSetObjectName(const std::string& name); -	void selectionSetObjectDescription(const std::string& desc); -	void selectionSetObjectCategory(const LLCategory& category); -	void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info); - -	void selectionTexScaleAutofit(F32 repeats_per_meter); -	void adjustTexturesByScale(bool send_to_sim, bool stretch); - -	bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz, -					   U32 update_type); -	void sendSelectionMove(); - -	void sendGodlikeRequest(const std::string& request, const std::string& parameter); - - -	// will make sure all selected object meet current criteria, or deselect them otherwise -	void validateSelection(); - -	// returns true if it is possible to select this object -	bool canSelectObject(LLViewerObject* object, bool ignore_select_owned = false); - -	// Returns true if the viewer has information on all selected objects -	bool selectGetAllRootsValid(); -	bool selectGetAllValid(); -	bool selectGetAllValidAndObjectsFound(); - -	// returns true if you can modify all selected objects.  -	bool selectGetRootsModify(); -	bool selectGetModify(); - -	// returns true if all objects are in same region -	bool selectGetSameRegion(); - -	// returns true if is all objects are non-permanent-enforced -	bool selectGetRootsNonPermanentEnforced(); -	bool selectGetNonPermanentEnforced(); - -	// returns true if is all objects are permanent -	bool selectGetRootsPermanent(); -	bool selectGetPermanent(); - -	// returns true if is all objects are character -	bool selectGetRootsCharacter(); -	bool selectGetCharacter(); - -	// returns true if is all objects are not permanent -	bool selectGetRootsNonPathfinding(); -	bool selectGetNonPathfinding(); - -	// returns true if is all objects are not permanent -	bool selectGetRootsNonPermanent(); -	bool selectGetNonPermanent(); - -	// returns true if is all objects are not character -	bool selectGetRootsNonCharacter(); -	bool selectGetNonCharacter(); - -	bool selectGetEditableLinksets(); -	bool selectGetViewableCharacters(); - -	// returns true if selected objects can be transferred. -	bool selectGetRootsTransfer(); - -	// returns true if selected objects can be copied. -	bool selectGetRootsCopy(); -	 -	bool selectGetCreator(LLUUID& id, std::string& name);					// true if all have same creator, returns id -	bool selectGetOwner(LLUUID& id, std::string& name);					// true if all objects have same owner, returns id -	bool selectGetLastOwner(LLUUID& id, std::string& name);				// true if all objects have same owner, returns id - -	// returns true if all are the same. id is stuffed with -	// the value found if available. -	bool selectGetGroup(LLUUID& id);  -	bool selectGetPerm(	U8 which_perm, U32* mask_on, U32* mask_off);	// true if all have data, returns two masks, each indicating which bits are all on and all off - -	bool selectIsGroupOwned();											// true if all root objects have valid data and are group owned. - -	// returns true if all the nodes are valid. Accumulates -	// permissions in the parameter. -	bool selectGetPermissions(LLPermissions& perm); - -	// returns true if all the nodes are valid. Depends onto "edit linked" state -	// Children in linksets are a bit special - they require not only move permission -	// but also modify if "edit linked" is set, since you move them relative to parent -	bool selectGetEditMoveLinksetPermissions(bool &move, bool &modify); -	 -	// Get a bunch of useful sale information for the object(s) selected. -	// "_mixed" is true if not all objects have the same setting. -	void selectGetAggregateSaleInfo(U32 &num_for_sale, -									bool &is_for_sale_mixed,  -									bool &is_sale_price_mixed, -									S32 &total_sale_price, -									S32 &individual_sale_price); - -	// returns true if all nodes are valid.  -	bool selectGetCategory(LLCategory& category); -	 -	// returns true if all nodes are valid. method also stores an -	// accumulated sale info. -	bool selectGetSaleInfo(LLSaleInfo& sale_info); - -	// returns true if all nodes are valid. fills passed in object -	// with the aggregate permissions of the selection. -	bool selectGetAggregatePermissions(LLAggregatePermissions& ag_perm); - -	// returns true if all nodes are valid. fills passed in object -	// with the aggregate permissions for texture inventory items of the selection. -	bool selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm); - -	LLPermissions* findObjectPermissions(const LLViewerObject* object); - -	bool isMovableAvatarSelected(); - -	void selectDelete();							// Delete on simulator -	void selectForceDelete();			// just delete, no into trash -	void selectDuplicate(const LLVector3& offset, bool select_copy);	// Duplicate on simulator -	void repeatDuplicate(); -	void selectDuplicateOnRay(const LLVector3 &ray_start_region, -								const LLVector3 &ray_end_region, -								bool bypass_raycast, -								bool ray_end_is_intersection, -								const LLUUID &ray_target_id, -								bool copy_centers, -								bool copy_rotates, -								bool select_copy); - -	void sendMultipleUpdate(U32 type);	// Position, rotation, scale all in one -	void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, bool override = false); -	void sendGroup(const LLUUID& group_id); - -	// Category ID is the UUID of the folder you want to contain the purchase. -	// *NOTE: sale_info check doesn't work for multiple object buy, -	// which UI does not currently support sale info is used for -	// verification only, if it doesn't match region info then sale is -	// canceled -	void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info); -	void sendAttach(U8 attachment_point, bool replace); -	void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace); -	void sendDetach(); -	void sendDropAttachment(); -	void sendLink(); -	void sendDelink(); -	//void sendHinge(U8 type); -	//void sendDehinge(); -	void sendSelect(); - -	void requestObjectPropertiesFamily(LLViewerObject* object);	// asks sim for creator, permissions, resources, etc. -	static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data); -	static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data); -	static void processForceObjectSelect(LLMessageSystem* msg, void**); - -	void requestGodInfo(); - -	LLVector3d		getSelectionCenterGlobal() const	{ return mSelectionCenterGlobal; } -	void			updateSelectionCenter(); - -    void pauseAssociatedAvatars(); - -	void resetAgentHUDZoom(); -	void setAgentHUDZoom(F32 target_zoom, F32 current_zoom); -	void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const; - -	void updatePointAt(); - -	// Internal list maintenance functions. TODO: Make these private! -	void remove(std::vector<LLViewerObject*>& objects); -	void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, bool undoable = true); -	void removeAll(); -	void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, bool undoable = true); -	void promoteSelectionToRoot(); -	void demoteSelectionToIndividuals(); - -private: -	void convertTransient(); // converts temporarily selected objects to full-fledged selections -	ESelectType getSelectTypeForObject(LLViewerObject* object); -	void addAsFamily(std::vector<LLViewerObject*>& objects, bool add_to_end = false); -	void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point); -	void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects); -	// Send one message to each region containing an object on selection list. -	void sendListToRegions(	const std::string& message_name, -							void (*pack_header)(void *user_data),  -							void (*pack_body)(LLSelectNode* node, void *user_data),  -							void (*log_func)(LLSelectNode* node, void *user_data),  -							void *user_data, -							ESendType send_type); -	void sendListToRegions(	LLObjectSelectionHandle selected_handle, -							const std::string& message_name, -							void (*pack_header)(void *user_data), -							void (*pack_body)(LLSelectNode* node, void *user_data), -							void (*log_func)(LLSelectNode* node, void *user_data), -							void *user_data, -							ESendType send_type); - - -	static void packAgentID(	void *); -	static void packAgentAndSessionID(void* user_data); -	static void packAgentAndGroupID(void* user_data); -	static void packAgentAndSessionAndGroupID(void* user_data); -	static void packAgentIDAndSessionAndAttachment(void*); -	static void packAgentGroupAndCatID(void*); -	static void packDeleteHeader(void* userdata); -	static void packDeRezHeader(void* user_data); -	static void packObjectID(	LLSelectNode* node, void *); -	static void packObjectIDAsParam(LLSelectNode* node, void *); -	static void packObjectIDAndRotation(LLSelectNode* node, void *); -	static void packObjectLocalID(LLSelectNode* node, void *); -	static void packObjectClickAction(LLSelectNode* node, void* data); -	static void packObjectIncludeInSearch(LLSelectNode* node, void* data); -	static void packObjectName(LLSelectNode* node, void* user_data); -	static void packObjectDescription(LLSelectNode* node, void* user_data); -	static void packObjectCategory(LLSelectNode* node, void* user_data); -	static void packObjectSaleInfo(LLSelectNode* node, void* user_data); -	static void packBuyObjectIDs(LLSelectNode* node, void* user_data); -	static void packDuplicate(	LLSelectNode* node, void *duplicate_data); -	static void packDuplicateHeader(void*); -	static void packDuplicateOnRayHead(void *user_data); -	static void packPermissions(LLSelectNode* node, void *user_data); -	static void packDeselect(	LLSelectNode* node, void *user_data); -	static void packMultipleUpdate(LLSelectNode* node, void *user_data); -	static void packPhysics(LLSelectNode* node, void *user_data); -	static void packShape(LLSelectNode* node, void *user_data); -	static void packOwnerHead(void *user_data); -	static void packHingeHead(void *user_data); -	static void packPermissionsHead(void* user_data); -	static void packGodlikeHead(void* user_data); -    static void logNoOp(LLSelectNode* node, void *user_data); -    static void logAttachmentRequest(LLSelectNode* node, void *user_data); -    static void logDetachRequest(LLSelectNode* node, void *user_data); -	static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle); - -	// Get the first ID that matches test and whether or not all ids are identical in selected objects. -	void getFirst(LLSelectGetFirstTest* test); - -public: -	// Observer/callback support for when object selection changes or -	// properties are received/updated -	typedef boost::signals2::signal< void ()> update_signal_t; -	update_signal_t mUpdateSignal; - -private: -	LLPointer<LLViewerTexture>				mSilhouetteImagep; -	LLObjectSelectionHandle					mSelectedObjects; -	LLObjectSelectionHandle					mHoverObjects; -	LLObjectSelectionHandle					mHighlightedObjects; -	std::set<LLPointer<LLViewerObject> >	mRectSelectedObjects; -	 -	LLObjectSelection		mGridObjects; -	LLQuaternion			mGridRotation; -	LLVector3				mGridOrigin; -	LLVector3				mGridScale; -	EGridMode				mGridMode; - -	bool					mTEMode;			// render te -	LLRender::eTexIndex	mTextureChannel; // diff, norm, or spec, depending on UI editing mode -	LLVector3d				mSelectionCenterGlobal; -	LLBBox					mSelectionBBox; - -	LLVector3d				mLastSentSelectionCenterGlobal; -	bool					mShowSelection; // do we send the selection center name value and do we animate this selection? -	LLVector3d				mLastCameraPos;		// camera position from last generation of selection silhouette -	bool					mRenderSilhouettes;	// do we render the silhouette -	LLBBox					mSavedSelectionBBox; - -	LLFrameTimer			mEffectsTimer; -	bool					mForceSelection; - -    std::vector<LLAnimPauseRequest>	mPauseRequests; -}; - -// *DEPRECATED: For callbacks or observers, use -// LLSelectMgr::getInstance()->mUpdateSignal.connect( callback ) -// Update subscribers to the selection list -void dialog_refresh_all();		 - -// Templates -//----------------------------------------------------------------------------- -// getSelectedTEValue -//----------------------------------------------------------------------------- -template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance, T tolerance) -{ -	bool have_first = false; -	bool have_selected = false; -	T selected_value = T(); - -	// Now iterate through all TEs to test for sameness -	bool identical = true; -	for (iterator iter = begin(); iter != end(); iter++) -	{ -		LLSelectNode* node = *iter; -		LLViewerObject* object = node->getObject(); -		S32 selected_te = -1; -		if (object == getPrimaryObject()) -		{ -			selected_te = node->getLastSelectedTE(); -		} -		for (S32 te = 0; te < object->getNumTEs(); ++te) -		{ -			if (!node->isTESelected(te)) -			{ -				continue; -			} -			T value = func->get(object, te); -			if (!have_first) -			{ -				have_first = true; -				if (!have_selected) -				{ -					selected_value = value; -				} -			} -			else -			{ -				if ( value != selected_value ) -				{ -                    if (!has_tolerance) -                    { -					    identical = false; -                    } -                    else if (!LLCheckIdenticalFunctor<T>::same(value, selected_value, tolerance)) -                    { -                        identical = false; -                    } -				} -				if (te == selected_te) -				{ -					selected_value = value; -					have_selected = true; -				} -			} -		} -		if (!identical && have_selected) -		{ -			break; -		} -	} -	if (have_first || have_selected) -	{ -		res = selected_value; -	} -	return identical; -} - -// Templates -//----------------------------------------------------------------------------- -// isMultipleTEValue iterate through all TEs and test for uniqueness  -// with certain return value ignored when performing the test.  -// e.g. when testing if the selection has a unique non-empty homeurl : -// you can set ignore_value = "" and it will only compare among the non-empty   -// homeUrls and ignore the empty ones. -//----------------------------------------------------------------------------- -template <typename T> bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value) -{ -	bool have_first = false; -	T selected_value = T(); -	 -	// Now iterate through all TEs to test for sameness -	bool unique = true; -	for (iterator iter = begin(); iter != end(); iter++) -	{ -		LLSelectNode* node = *iter; -		LLViewerObject* object = node->getObject(); -		for (S32 te = 0; te < object->getNumTEs(); ++te) -		{ -			if (!node->isTESelected(te)) -			{ -				continue; -			} -			T value = func->get(object, te); -			if(value == ignore_value) -			{ -				continue; -			} -			if (!have_first) -			{ -				have_first = true; -			} -			else -			{ -				if (value !=selected_value  ) -				{ -					unique = false; -					return !unique; -				} -			} -		} -	} -	return !unique; -} - - -#endif +/**
 + * @file llselectmgr.h
 + * @brief A manager for selected objects and TEs.
 + *
 + * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 + * Second Life Viewer Source Code
 + * Copyright (C) 2010, Linden Research, Inc.
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation;
 + * version 2.1 of the License only.
 + *
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + *
 + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 + * $/LicenseInfo$
 + */
 +
 +#ifndef LL_LLSELECTMGR_H
 +#define LL_LLSELECTMGR_H
 +
 +#include "llcharacter.h"
 +#include "lleditmenuhandler.h"
 +#include "llundo.h"
 +#include "lluuid.h"
 +#include "llpointer.h"
 +#include "llsafehandle.h"
 +#include "llsaleinfo.h"
 +#include "llcategory.h"
 +#include "v3dmath.h"
 +#include "llquaternion.h"
 +#include "llcoord.h"
 +#include "llframetimer.h"
 +#include "llbbox.h"
 +#include "llpermissions.h"
 +#include "llcontrol.h"
 +#include "llviewerobject.h" // LLObjectSelection::getSelectedTEValue template
 +#include "llmaterial.h"
 +
 +#include <deque>
 +#include <boost/iterator/filter_iterator.hpp>
 +#include <boost/signals2.hpp>
 +#include <boost/make_shared.hpp>    // boost::make_shared
 +
 +class LLMessageSystem;
 +class LLViewerTexture;
 +class LLColor4;
 +class LLVector3;
 +class LLSelectNode;
 +
 +const U8 UPD_NONE           = 0x00;
 +const U8 UPD_POSITION       = 0x01;
 +const U8 UPD_ROTATION       = 0x02;
 +const U8 UPD_SCALE          = 0x04;
 +const U8 UPD_LINKED_SETS    = 0x08;
 +const U8 UPD_UNIFORM        = 0x10; // used with UPD_SCALE
 +
 +// This is used by the DeRezObject message to determine where to put
 +// derezed tasks.
 +enum EDeRezDestination
 +{
 +    DRD_SAVE_INTO_AGENT_INVENTORY = 0,
 +    DRD_ACQUIRE_TO_AGENT_INVENTORY = 1,     // try to leave copy in world
 +    DRD_SAVE_INTO_TASK_INVENTORY = 2,
 +    DRD_ATTACHMENT = 3,
 +    DRD_TAKE_INTO_AGENT_INVENTORY = 4,      // delete from world
 +    DRD_FORCE_TO_GOD_INVENTORY = 5,         // force take copy
 +    DRD_TRASH = 6,
 +    DRD_ATTACHMENT_TO_INV = 7,
 +    DRD_ATTACHMENT_EXISTS = 8,
 +    DRD_RETURN_TO_OWNER = 9,                // back to owner's inventory
 +    DRD_RETURN_TO_LAST_OWNER = 10,          // deeded object back to last owner's inventory
 +
 +    DRD_COUNT = 11
 +};
 +
 +
 +const S32 SELECT_ALL_TES = -1;
 +const S32 SELECT_MAX_TES = 32;
 +
 +// Do something to all objects in the selection manager.
 +// The bool return value can be used to indicate if all
 +// objects are identical (gathering information) or if
 +// the operation was successful.
 +struct LLSelectedObjectFunctor
 +{
 +    virtual ~LLSelectedObjectFunctor() {};
 +    virtual bool apply(LLViewerObject* object) = 0;
 +};
 +
 +// Do something to all select nodes in the selection manager.
 +// The bool return value can be used to indicate if all
 +// objects are identical (gathering information) or if
 +// the operation was successful.
 +struct LLSelectedNodeFunctor
 +{
 +    virtual ~LLSelectedNodeFunctor() {};
 +    virtual bool apply(LLSelectNode* node) = 0;
 +};
 +
 +struct LLSelectedTEFunctor
 +{
 +    virtual ~LLSelectedTEFunctor() {};
 +    virtual bool apply(LLViewerObject* object, S32 face) = 0;
 +};
 +
 +struct LLSelectedTEMaterialFunctor
 +{
 +    virtual ~LLSelectedTEMaterialFunctor() {};
 +    virtual LLMaterialPtr apply(LLViewerObject* object, S32 face, LLTextureEntry* tep, LLMaterialPtr& current_material) = 0;
 +};
 +
 +template <typename T> struct LLSelectedTEGetFunctor
 +{
 +    virtual ~LLSelectedTEGetFunctor() {};
 +    virtual T get(LLViewerObject* object, S32 te) = 0;
 +};
 +
 +template <typename T> struct LLCheckIdenticalFunctor
 +{
 +    static bool same(const T& a, const T& b, const T& tolerance);
 +};
 +
 +typedef enum e_send_type
 +{
 +    SEND_ONLY_ROOTS,
 +    SEND_INDIVIDUALS,
 +    SEND_ROOTS_FIRST, // useful for serial undos on linked sets
 +    SEND_CHILDREN_FIRST // useful for serial transforms of linked sets
 +} ESendType;
 +
 +typedef enum e_grid_mode
 +{
 +    GRID_MODE_WORLD,
 +    GRID_MODE_LOCAL,
 +    GRID_MODE_REF_OBJECT
 +} EGridMode;
 +
 +typedef enum e_action_type
 +{
 +    SELECT_ACTION_TYPE_BEGIN,
 +    SELECT_ACTION_TYPE_PICK,
 +    SELECT_ACTION_TYPE_MOVE,
 +    SELECT_ACTION_TYPE_ROTATE,
 +    SELECT_ACTION_TYPE_SCALE,
 +    NUM_ACTION_TYPES
 +}EActionType;
 +
 +typedef enum e_selection_type
 +{
 +    SELECT_TYPE_WORLD,
 +    SELECT_TYPE_ATTACHMENT,
 +    SELECT_TYPE_HUD
 +}ESelectType;
 +
 +typedef std::vector<LLPointer<LLGLTFMaterial> > gltf_materials_vec_t;
 +
 +const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
 +
 +// Contains information about a selected object, particularly which TEs are selected.
 +class LLSelectNode
 +{
 +public:
 +    LLSelectNode(LLViewerObject* object, bool do_glow);
 +    LLSelectNode(const LLSelectNode& nodep);
 +    ~LLSelectNode();
 +
 +    void selectAllTEs(bool b);
 +    void selectTE(S32 te_index, bool selected);
 +    bool isTESelected(S32 te_index) const;
 +    bool hasSelectedTE() const { return TE_SELECT_MASK_ALL & mTESelectMask; }
 +    S32 getLastSelectedTE() const;
 +    S32 getLastOperatedTE() const { return mLastTESelected; }
 +    S32 getTESelectMask() { return mTESelectMask; }
 +    void renderOneSilhouette(const LLColor4 &color);
 +    void setTransient(bool transient) { mTransient = transient; }
 +    bool isTransient() const { return mTransient; }
 +    LLViewerObject* getObject();
 +    void setObject(LLViewerObject* object);
 +    // *NOTE: invalidate stored textures and colors when # faces change
 +    // Used by tools floater's color/texture pickers to restore changes
 +    void saveColors();
 +    void saveShinyColors();
 +    void saveTextures(const uuid_vec_t& textures);
 +    void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
 +
 +    // GLTF materials are applied to objects by ids,
 +    // overrides get applied on top of materials resulting in
 +    // final gltf material that users see.
 +    // Ids get applied and restored by tools floater,
 +    // overrides get applied in live material editor
 +    void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials);
 +
 +    bool allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
 +
 +public:
 +    bool            mIndividualSelection;       // For root objects and objects individually selected
 +
 +    bool            mTransient;
 +    bool            mValid;             // is extra information valid?
 +    LLPermissions*  mPermissions;
 +    LLSaleInfo      mSaleInfo;
 +    LLAggregatePermissions mAggregatePerm;
 +    LLAggregatePermissions mAggregateTexturePerm;
 +    LLAggregatePermissions mAggregateTexturePermOwner;
 +    std::string     mName;
 +    std::string     mDescription;
 +    LLCategory      mCategory;
 +    S16             mInventorySerial;
 +    LLVector3       mSavedPositionLocal;    // for interactively modifying object position
 +    LLVector3       mLastPositionLocal;
 +    LLVector3d      mSavedPositionGlobal;   // for interactively modifying object position
 +    LLVector3       mSavedScale;            // for interactively modifying object scale
 +    LLVector3       mLastScale;
 +    LLQuaternion    mSavedRotation;         // for interactively modifying object rotation
 +    LLQuaternion    mLastRotation;
 +    bool            mDuplicated;
 +    LLVector3d      mDuplicatePos;
 +    LLQuaternion    mDuplicateRot;
 +    LLUUID          mItemID;
 +    LLUUID          mFolderID;
 +    LLUUID          mFromTaskID;
 +    std::string     mTouchName;
 +    std::string     mSitName;
 +    U64             mCreationDate;
 +    std::vector<LLColor4>   mSavedColors;
 +    std::vector<LLColor4>   mSavedShinyColors;
 +    uuid_vec_t      mSavedTextures;
 +    uuid_vec_t      mSavedGLTFMaterialIds;
 +    gltf_materials_vec_t mSavedGLTFOverrideMaterials;
 +    std::vector<LLVector3>  mTextureScaleRatios;
 +    std::vector<LLVector3>  mSilhouetteVertices;    // array of vertices to render silhouette of object
 +    std::vector<LLVector3>  mSilhouetteNormals; // array of normals to render silhouette of object
 +    bool                    mSilhouetteExists;  // need to generate silhouette?
 +
 +protected:
 +    LLPointer<LLViewerObject>   mObject;
 +    S32             mTESelectMask;
 +    S32             mLastTESelected;
 +};
 +
 +class LLObjectSelection : public LLRefCount
 +{
 +    friend class LLSelectMgr;
 +    friend class LLSafeHandle<LLObjectSelection>;
 +    friend class LLSelectionCallbackData;
 +
 +protected:
 +    ~LLObjectSelection();
 +
 +public:
 +    typedef std::list<LLSelectNode*> list_t;
 +
 +    // Iterators
 +    struct is_non_null
 +    {
 +        bool operator()(LLSelectNode* node)
 +        {
 +            return (node->getObject() != NULL);
 +        }
 +    };
 +    typedef boost::filter_iterator<is_non_null, list_t::iterator > iterator;
 +    iterator begin() { return iterator(mList.begin(), mList.end()); }
 +    iterator end() { return iterator(mList.end(), mList.end()); }
 +
 +    struct is_valid
 +    {
 +        bool operator()(LLSelectNode* node)
 +        {
 +            return (node->getObject() != NULL) && node->mValid;
 +        }
 +    };
 +    typedef boost::filter_iterator<is_valid, list_t::iterator > valid_iterator;
 +    valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); }
 +    valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); }
 +
 +    struct is_root
 +    {
 +        bool operator()(LLSelectNode* node);
 +    };
 +    typedef boost::filter_iterator<is_root, list_t::iterator > root_iterator;
 +    root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); }
 +    root_iterator root_end() { return root_iterator(mList.end(), mList.end()); }
 +
 +    struct is_valid_root
 +    {
 +        bool operator()(LLSelectNode* node);
 +    };
 +    typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator;
 +    valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); }
 +    valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); }
 +
 +    struct is_root_object
 +    {
 +        bool operator()(LLSelectNode* node);
 +    };
 +    typedef boost::filter_iterator<is_root_object, list_t::iterator > root_object_iterator;
 +    root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); }
 +    root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); }
 +
 +public:
 +    LLObjectSelection();
 +
 +    void updateEffects();
 +
 +    bool isEmpty() const;
 +
 +    LLSelectNode*   getFirstNode(LLSelectedNodeFunctor* func = NULL);
 +    LLSelectNode*   getFirstRootNode(LLSelectedNodeFunctor* func = NULL, bool non_root_ok = false);
 +    LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, bool get_parent = false);
 +    LLViewerObject* getFirstObject();
 +    LLViewerObject* getFirstRootObject(bool non_root_ok = false);
 +
 +    LLSelectNode*   getFirstMoveableNode(bool get_root_first = false);
 +
 +    LLViewerObject* getFirstEditableObject(bool get_parent = false);
 +    LLViewerObject* getFirstCopyableObject(bool get_parent = false);
 +    LLViewerObject* getFirstDeleteableObject();
 +    LLViewerObject* getFirstMoveableObject(bool get_parent = false);
 +    LLViewerObject* getFirstUndoEnabledObject(bool get_parent = false);
 +
 +    /// Return the object that lead to this selection, possible a child
 +    LLViewerObject* getPrimaryObject() { return mPrimaryObject; }
 +
 +    // iterate through texture entries
 +    template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance = false, T tolerance = T());
 +    template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value);
 +
 +    S32 getNumNodes();
 +    LLSelectNode* findNode(LLViewerObject* objectp);
 +
 +    // count members
 +    S32 getObjectCount();
 +    F32 getSelectedObjectCost();
 +    F32 getSelectedLinksetCost();
 +    F32 getSelectedPhysicsCost();
 +    F32 getSelectedLinksetPhysicsCost();
 +    S32 getSelectedObjectRenderCost();
 +
 +    F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL);
 +    U32 getSelectedObjectTriangleCount(S32* vcount = NULL);
 +
 +    S32 getTECount();
 +    S32 getRootObjectCount();
 +
 +    bool isMultipleTESelected();
 +    bool contains(LLViewerObject* object);
 +    bool contains(LLViewerObject* object, S32 te);
 +
 +    // returns true is any node is currenly worn as an attachment
 +    bool isAttachment();
 +
 +    bool checkAnimatedObjectEstTris();
 +    bool checkAnimatedObjectLinkable();
 +
 +    // Apply functors to various subsets of the selected objects
 +    // If firstonly is false, returns the AND of all apply() calls.
 +    // Else returns true immediately if any apply() call succeeds (i.e. OR with early exit)
 +    bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false);
 +    bool applyToObjects(LLSelectedObjectFunctor* func);
 +    bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false);
 +    bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
 +    bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
 +
 +    /*
 +     * Used to apply (no-copy) textures to the selected object or
 +     * selected face/faces of the object.
 +     * This method moves (no-copy) texture to the object's inventory
 +     * and doesn't make copy of the texture for each face.
 +     * Then this only texture is used for all selected faces.
 +     */
 +    void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
 +    /*
 +     * Multi-purpose function for applying PBR materials to the
 +     * selected object or faces, any combination of copy/mod/transfer
 +     * permission restrictions. This method moves the restricted
 +     * material to the object's inventory and doesn't make a copy of the
 +     * material for each face. Then this only material is used for
 +     * all selected faces.
 +     * Returns false if applying the material failed on one or more selected
 +     * faces.
 +     */
 +    bool applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item);
 +
 +    ESelectType getSelectType() const { return mSelectType; }
 +
 +private:
 +    void addNode(LLSelectNode *nodep);
 +    void addNodeAtEnd(LLSelectNode *nodep);
 +    void moveNodeToFront(LLSelectNode *nodep);
 +    void removeNode(LLSelectNode *nodep);
 +    void deleteAllNodes();
 +    void cleanupNodes();
 +
 +
 +private:
 +    list_t mList;
 +    const LLObjectSelection &operator=(const LLObjectSelection &);
 +
 +    LLPointer<LLViewerObject> mPrimaryObject;
 +    std::map<LLPointer<LLViewerObject>, LLSelectNode*> mSelectNodeMap;
 +    ESelectType mSelectType;
 +};
 +
 +typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;
 +
 +// Build time optimization, generate this once in .cpp file
 +#ifndef LLSELECTMGR_CPP
 +extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
 +#endif
 +
 +// For use with getFirstTest()
 +struct LLSelectGetFirstTest;
 +
 +// temporary storage, Ex: to attach objects after autopilot
 +class LLSelectionCallbackData
 +{
 +public:
 +    LLSelectionCallbackData();
 +    LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
 +private:
 +    LLObjectSelectionHandle                 mSelectedObjects;
 +};
 +
 +class LLSelectMgr : public LLEditMenuHandler, public LLSimpleton<LLSelectMgr>
 +{
 +public:
 +    static bool                 sRectSelectInclusive;   // do we need to surround an object to pick it?
 +    static bool                 sRenderHiddenSelections;    // do we show selection silhouettes that are occluded?
 +    static bool                 sRenderLightRadius; // do we show the radius of selected lights?
 +
 +    static F32                  sHighlightThickness;
 +    static F32                  sHighlightUScale;
 +    static F32                  sHighlightVScale;
 +    static F32                  sHighlightAlpha;
 +    static F32                  sHighlightAlphaTest;
 +    static F32                  sHighlightUAnim;
 +    static F32                  sHighlightVAnim;
 +    static LLColor4             sSilhouetteParentColor;
 +    static LLColor4             sSilhouetteChildColor;
 +    static LLColor4             sHighlightParentColor;
 +    static LLColor4             sHighlightChildColor;
 +    static LLColor4             sHighlightInspectColor;
 +    static LLColor4             sContextSilhouetteColor;
 +
 +    LLCachedControl<bool>                   mHideSelectedObjects;
 +    LLCachedControl<bool>                   mRenderHighlightSelections;
 +    LLCachedControl<bool>                   mAllowSelectAvatar;
 +    LLCachedControl<bool>                   mDebugSelectMgr;
 +
 +public:
 +    LLSelectMgr();
 +    ~LLSelectMgr();
 +
 +    static void cleanupGlobals();
 +
 +    // LLEditMenuHandler interface
 +    virtual bool canUndo() const;
 +    virtual void undo();
 +
 +    virtual bool canRedo() const;
 +    virtual void redo();
 +
 +    virtual bool canDoDelete() const;
 +    virtual void doDelete();
 +
 +    virtual void deselect();
 +    virtual bool canDeselect() const;
 +
 +    virtual void duplicate();
 +    virtual bool canDuplicate() const;
 +
 +    void clearSelections();
 +    void update();
 +    void updateEffects(); // Update HUD effects
 +
 +    // When we edit object's position/rotation/scale we set local
 +    // overrides and ignore any updates (override received valeus).
 +    // When we send data to server, we send local values and reset
 +    // overrides
 +    void resetObjectOverrides();
 +    void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
 +    void overrideObjectUpdates();
 +
 +    void resetAvatarOverrides();
 +    void overrideAvatarUpdates();
 +
 +    struct AvatarPositionOverride
 +    {
 +        AvatarPositionOverride();
 +        AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) :
 +            mLastPositionLocal(vec),
 +            mLastRotation(quat),
 +            mObject(obj)
 +        {
 +        }
 +        LLVector3 mLastPositionLocal;
 +        LLQuaternion mLastRotation;
 +        LLPointer<LLViewerObject> mObject;
 +    };
 +
 +    // Avatar overrides should persist even after selection
 +    // was removed as long as edit floater is up
 +    typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t;
 +    uuid_av_override_map_t mAvatarOverridesMap;
 +public:
 +
 +
 +    // Returns the previous value of mForceSelection
 +    bool setForceSelection(bool force);
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Selection methods
 +    ////////////////////////////////////////////////////////////////
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Add
 +    ////////////////////////////////////////////////////////////////
 +
 +    // This method is meant to select an object, and then select all
 +    // of the ancestors and descendants. This should be the normal behavior.
 +    //
 +    // *NOTE: You must hold on to the object selection handle, otherwise
 +    // the objects will be automatically deselected in 1 frame.
 +    LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, bool add_to_end = false, bool ignore_select_owned = false);
 +
 +    // For when you want just a child object.
 +    LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES);
 +
 +    // Same as above, but takes a list of objects.  Used by rectangle select.
 +    LLObjectSelectionHandle selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list, bool send_to_sim = true);
 +
 +    // converts all objects currently highlighted to a selection, and returns it
 +    LLObjectSelectionHandle selectHighlightedObjects();
 +
 +    LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1);
 +    LLSelectNode *getHoverNode();
 +    LLSelectNode *getPrimaryHoverNode();
 +
 +    void highlightObjectOnly(LLViewerObject *objectp);
 +    void highlightObjectAndFamily(LLViewerObject *objectp);
 +    void highlightObjectAndFamily(const std::vector<LLViewerObject*>& list);
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Remove
 +    ////////////////////////////////////////////////////////////////
 +
 +    void deselectObjectOnly(LLViewerObject* object, bool send_to_sim = true);
 +    void deselectObjectAndFamily(LLViewerObject* object, bool send_to_sim = true, bool include_entire_object = false);
 +
 +    // Send deselect messages to simulator, then clear the list
 +    void deselectAll();
 +    void deselectAllForStandingUp();
 +
 +    // deselect only if nothing else currently referencing the selection
 +    void deselectUnused();
 +
 +    // Deselect if the selection center is too far away from the agent.
 +    void deselectAllIfTooFar();
 +
 +    // Removes all highlighted objects from current selection
 +    void deselectHighlightedObjects();
 +
 +    void unhighlightObjectOnly(LLViewerObject *objectp);
 +    void unhighlightObjectAndFamily(LLViewerObject *objectp);
 +    void unhighlightAll();
 +
 +    bool removeObjectFromSelections(const LLUUID &id);
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Selection editing
 +    ////////////////////////////////////////////////////////////////
 +    bool linkObjects();
 +
 +    bool unlinkObjects();
 +
 +    void confirmUnlinkObjects(const LLSD& notification, const LLSD& response);
 +
 +    bool enableLinkObjects();
 +
 +    bool enableUnlinkObjects();
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Selection accessors
 +    ////////////////////////////////////////////////////////////////
 +    LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
 +    // right now this just renders the selection with root/child colors instead of a single color
 +    LLObjectSelectionHandle getEditSelection() { convertTransient(); return mSelectedObjects; }
 +    LLObjectSelectionHandle getHighlightedObjects() { return mHighlightedObjects; }
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Grid manipulation
 +    ////////////////////////////////////////////////////////////////
 +    void            addGridObject(LLViewerObject* objectp);
 +    void            clearGridObjects();
 +    void            setGridMode(EGridMode mode);
 +    EGridMode       getGridMode() { return mGridMode; }
 +    void            getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale, bool for_snap_guides = false);
 +
 +    bool getTEMode() const { return mTEMode; }
 +    void setTEMode(bool b) { mTEMode = b; }
 +
 +    bool shouldShowSelection() const { return mShowSelection; }
 +
 +    LLBBox getBBoxOfSelection() const;
 +    LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; }
 +
 +    void dump();
 +    void cleanup();
 +
 +    void updateSilhouettes();
 +    void renderSilhouettes(bool for_hud);
 +    void enableSilhouette(bool enable) { mRenderSilhouettes = enable; }
 +
 +    ////////////////////////////////////////////////////////////////
 +    // Utility functions that operate on the current selection
 +    ////////////////////////////////////////////////////////////////
 +    void saveSelectedObjectTransform(EActionType action_type);
 +    void saveSelectedObjectColors();
 +    void saveSelectedShinyColors();
 +    void saveSelectedObjectTextures();
 +
 +    void selectionUpdatePhysics(bool use_physics);
 +    void selectionUpdateTemporary(bool is_temporary);
 +    void selectionUpdatePhantom(bool is_ghost);
 +    void selectionDump();
 +
 +    bool selectionAllPCode(LLPCode code);       // all objects have this PCode
 +    bool selectionGetClickAction(U8 *out_action);
 +    bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same
 +    bool selectionGetGlow(F32 *glow);
 +
 +    void selectionSetPhysicsType(U8 type);
 +    void selectionSetGravity(F32 gravity);
 +    void selectionSetFriction(F32 friction);
 +    void selectionSetDensity(F32 density);
 +    void selectionSetRestitution(F32 restitution);
 +    void selectionSetMaterial(U8 material);
 +    bool selectionSetImage(const LLUUID& imageid); // could be item or asset id
 +    bool selectionSetGLTFMaterial(const LLUUID& mat_id); // material id only
 +    void selectionSetColor(const LLColor4 &color);
 +    void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
 +    void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
 +    void selectionRevertColors();
 +    void selectionRevertShinyColors();
 +    bool selectionRevertTextures();
 +    void selectionRevertGLTFMaterials();
 +    void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id );
 +    void selectionSetTexGen( U8 texgen );
 +    void selectionSetShiny( U8 shiny, const LLUUID &image_id );
 +    void selectionSetFullbright( U8 fullbright );
 +    void selectionSetMedia( U8 media_type, const LLSD &media_data );
 +    void selectionSetClickAction(U8 action);
 +    void selectionSetIncludeInSearch(bool include_in_search);
 +    void selectionSetGlow(const F32 glow);
 +    void selectionSetMaterialParams(LLSelectedTEMaterialFunctor* material_func, int specific_te = -1);
 +    void selectionRemoveMaterial();
 +
 +    void selectionSetObjectPermissions(U8 perm_field, bool set, U32 perm_mask, bool override = false);
 +    void selectionSetObjectName(const std::string& name);
 +    void selectionSetObjectDescription(const std::string& desc);
 +    void selectionSetObjectCategory(const LLCategory& category);
 +    void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info);
 +
 +    void selectionTexScaleAutofit(F32 repeats_per_meter);
 +    void adjustTexturesByScale(bool send_to_sim, bool stretch);
 +
 +    bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz,
 +                       U32 update_type);
 +    void sendSelectionMove();
 +
 +    void sendGodlikeRequest(const std::string& request, const std::string& parameter);
 +
 +
 +    // will make sure all selected object meet current criteria, or deselect them otherwise
 +    void validateSelection();
 +
 +    // returns true if it is possible to select this object
 +    bool canSelectObject(LLViewerObject* object, bool ignore_select_owned = false);
 +
 +    // Returns true if the viewer has information on all selected objects
 +    bool selectGetAllRootsValid();
 +    bool selectGetAllValid();
 +    bool selectGetAllValidAndObjectsFound();
 +
 +    // returns true if you can modify all selected objects.
 +    bool selectGetRootsModify();
 +    bool selectGetModify();
 +
 +    // returns true if all objects are in same region
 +    bool selectGetSameRegion();
 +
 +    // returns true if is all objects are non-permanent-enforced
 +    bool selectGetRootsNonPermanentEnforced();
 +    bool selectGetNonPermanentEnforced();
 +
 +    // returns true if is all objects are permanent
 +    bool selectGetRootsPermanent();
 +    bool selectGetPermanent();
 +
 +    // returns true if is all objects are character
 +    bool selectGetRootsCharacter();
 +    bool selectGetCharacter();
 +
 +    // returns true if is all objects are not permanent
 +    bool selectGetRootsNonPathfinding();
 +    bool selectGetNonPathfinding();
 +
 +    // returns true if is all objects are not permanent
 +    bool selectGetRootsNonPermanent();
 +    bool selectGetNonPermanent();
 +
 +    // returns true if is all objects are not character
 +    bool selectGetRootsNonCharacter();
 +    bool selectGetNonCharacter();
 +
 +    bool selectGetEditableLinksets();
 +    bool selectGetViewableCharacters();
 +
 +    // returns true if selected objects can be transferred.
 +    bool selectGetRootsTransfer();
 +
 +    // returns true if selected objects can be copied.
 +    bool selectGetRootsCopy();
 +
 +    bool selectGetCreator(LLUUID& id, std::string& name);                   // true if all have same creator, returns id
 +    bool selectGetOwner(LLUUID& id, std::string& name);                 // true if all objects have same owner, returns id
 +    bool selectGetLastOwner(LLUUID& id, std::string& name);             // true if all objects have same owner, returns id
 +
 +    // returns true if all are the same. id is stuffed with
 +    // the value found if available.
 +    bool selectGetGroup(LLUUID& id);
 +    bool selectGetPerm( U8 which_perm, U32* mask_on, U32* mask_off);    // true if all have data, returns two masks, each indicating which bits are all on and all off
 +
 +    bool selectIsGroupOwned();                                          // true if all root objects have valid data and are group owned.
 +
 +    // returns true if all the nodes are valid. Accumulates
 +    // permissions in the parameter.
 +    bool selectGetPermissions(LLPermissions& perm);
 +
 +    // returns true if all the nodes are valid. Depends onto "edit linked" state
 +    // Children in linksets are a bit special - they require not only move permission
 +    // but also modify if "edit linked" is set, since you move them relative to parent
 +    bool selectGetEditMoveLinksetPermissions(bool &move, bool &modify);
 +
 +    // Get a bunch of useful sale information for the object(s) selected.
 +    // "_mixed" is true if not all objects have the same setting.
 +    void selectGetAggregateSaleInfo(U32 &num_for_sale,
 +                                    bool &is_for_sale_mixed,
 +                                    bool &is_sale_price_mixed,
 +                                    S32 &total_sale_price,
 +                                    S32 &individual_sale_price);
 +
 +    // returns true if all nodes are valid.
 +    bool selectGetCategory(LLCategory& category);
 +
 +    // returns true if all nodes are valid. method also stores an
 +    // accumulated sale info.
 +    bool selectGetSaleInfo(LLSaleInfo& sale_info);
 +
 +    // returns true if all nodes are valid. fills passed in object
 +    // with the aggregate permissions of the selection.
 +    bool selectGetAggregatePermissions(LLAggregatePermissions& ag_perm);
 +
 +    // returns true if all nodes are valid. fills passed in object
 +    // with the aggregate permissions for texture inventory items of the selection.
 +    bool selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm);
 +
 +    LLPermissions* findObjectPermissions(const LLViewerObject* object);
 +
 +    bool isMovableAvatarSelected();
 +
 +    void selectDelete();                            // Delete on simulator
 +    void selectForceDelete();           // just delete, no into trash
 +    void selectDuplicate(const LLVector3& offset, bool select_copy);    // Duplicate on simulator
 +    void repeatDuplicate();
 +    void selectDuplicateOnRay(const LLVector3 &ray_start_region,
 +                                const LLVector3 &ray_end_region,
 +                                bool bypass_raycast,
 +                                bool ray_end_is_intersection,
 +                                const LLUUID &ray_target_id,
 +                                bool copy_centers,
 +                                bool copy_rotates,
 +                                bool select_copy);
 +
 +    void sendMultipleUpdate(U32 type);  // Position, rotation, scale all in one
 +    void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, bool override = false);
 +    void sendGroup(const LLUUID& group_id);
 +
 +    // Category ID is the UUID of the folder you want to contain the purchase.
 +    // *NOTE: sale_info check doesn't work for multiple object buy,
 +    // which UI does not currently support sale info is used for
 +    // verification only, if it doesn't match region info then sale is
 +    // canceled
 +    void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info);
 +    void sendAttach(U8 attachment_point, bool replace);
 +    void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace);
 +    void sendDetach();
 +    void sendDropAttachment();
 +    void sendLink();
 +    void sendDelink();
 +    //void sendHinge(U8 type);
 +    //void sendDehinge();
 +    void sendSelect();
 +
 +    void requestObjectPropertiesFamily(LLViewerObject* object); // asks sim for creator, permissions, resources, etc.
 +    static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data);
 +    static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data);
 +    static void processForceObjectSelect(LLMessageSystem* msg, void**);
 +
 +    void requestGodInfo();
 +
 +    LLVector3d      getSelectionCenterGlobal() const    { return mSelectionCenterGlobal; }
 +    void            updateSelectionCenter();
 +
 +    void pauseAssociatedAvatars();
 +
 +    void resetAgentHUDZoom();
 +    void setAgentHUDZoom(F32 target_zoom, F32 current_zoom);
 +    void getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const;
 +
 +    void updatePointAt();
 +
 +    // Internal list maintenance functions. TODO: Make these private!
 +    void remove(std::vector<LLViewerObject*>& objects);
 +    void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, bool undoable = true);
 +    void removeAll();
 +    void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, bool undoable = true);
 +    void promoteSelectionToRoot();
 +    void demoteSelectionToIndividuals();
 +
 +private:
 +    void convertTransient(); // converts temporarily selected objects to full-fledged selections
 +    ESelectType getSelectTypeForObject(LLViewerObject* object);
 +    void addAsFamily(std::vector<LLViewerObject*>& objects, bool add_to_end = false);
 +    void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point);
 +    void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects);
 +    // Send one message to each region containing an object on selection list.
 +    void sendListToRegions( const std::string& message_name,
 +                            void (*pack_header)(void *user_data),
 +                            void (*pack_body)(LLSelectNode* node, void *user_data),
 +                            void (*log_func)(LLSelectNode* node, void *user_data),
 +                            void *user_data,
 +                            ESendType send_type);
 +    void sendListToRegions( LLObjectSelectionHandle selected_handle,
 +                            const std::string& message_name,
 +                            void (*pack_header)(void *user_data),
 +                            void (*pack_body)(LLSelectNode* node, void *user_data),
 +                            void (*log_func)(LLSelectNode* node, void *user_data),
 +                            void *user_data,
 +                            ESendType send_type);
 +
 +
 +    static void packAgentID(    void *);
 +    static void packAgentAndSessionID(void* user_data);
 +    static void packAgentAndGroupID(void* user_data);
 +    static void packAgentAndSessionAndGroupID(void* user_data);
 +    static void packAgentIDAndSessionAndAttachment(void*);
 +    static void packAgentGroupAndCatID(void*);
 +    static void packDeleteHeader(void* userdata);
 +    static void packDeRezHeader(void* user_data);
 +    static void packObjectID(   LLSelectNode* node, void *);
 +    static void packObjectIDAsParam(LLSelectNode* node, void *);
 +    static void packObjectIDAndRotation(LLSelectNode* node, void *);
 +    static void packObjectLocalID(LLSelectNode* node, void *);
 +    static void packObjectClickAction(LLSelectNode* node, void* data);
 +    static void packObjectIncludeInSearch(LLSelectNode* node, void* data);
 +    static void packObjectName(LLSelectNode* node, void* user_data);
 +    static void packObjectDescription(LLSelectNode* node, void* user_data);
 +    static void packObjectCategory(LLSelectNode* node, void* user_data);
 +    static void packObjectSaleInfo(LLSelectNode* node, void* user_data);
 +    static void packBuyObjectIDs(LLSelectNode* node, void* user_data);
 +    static void packDuplicate(  LLSelectNode* node, void *duplicate_data);
 +    static void packDuplicateHeader(void*);
 +    static void packDuplicateOnRayHead(void *user_data);
 +    static void packPermissions(LLSelectNode* node, void *user_data);
 +    static void packDeselect(   LLSelectNode* node, void *user_data);
 +    static void packMultipleUpdate(LLSelectNode* node, void *user_data);
 +    static void packPhysics(LLSelectNode* node, void *user_data);
 +    static void packShape(LLSelectNode* node, void *user_data);
 +    static void packOwnerHead(void *user_data);
 +    static void packHingeHead(void *user_data);
 +    static void packPermissionsHead(void* user_data);
 +    static void packGodlikeHead(void* user_data);
 +    static void logNoOp(LLSelectNode* node, void *user_data);
 +    static void logAttachmentRequest(LLSelectNode* node, void *user_data);
 +    static void logDetachRequest(LLSelectNode* node, void *user_data);
 +    static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
 +
 +    // Get the first ID that matches test and whether or not all ids are identical in selected objects.
 +    void getFirst(LLSelectGetFirstTest* test);
 +
 +public:
 +    // Observer/callback support for when object selection changes or
 +    // properties are received/updated
 +    typedef boost::signals2::signal< void ()> update_signal_t;
 +    update_signal_t mUpdateSignal;
 +
 +private:
 +    LLPointer<LLViewerTexture>              mSilhouetteImagep;
 +    LLObjectSelectionHandle                 mSelectedObjects;
 +    LLObjectSelectionHandle                 mHoverObjects;
 +    LLObjectSelectionHandle                 mHighlightedObjects;
 +    std::set<LLPointer<LLViewerObject> >    mRectSelectedObjects;
 +
 +    LLObjectSelection       mGridObjects;
 +    LLQuaternion            mGridRotation;
 +    LLVector3               mGridOrigin;
 +    LLVector3               mGridScale;
 +    EGridMode               mGridMode;
 +
 +    bool                    mTEMode;            // render te
 +    LLRender::eTexIndex mTextureChannel; // diff, norm, or spec, depending on UI editing mode
 +    LLVector3d              mSelectionCenterGlobal;
 +    LLBBox                  mSelectionBBox;
 +
 +    LLVector3d              mLastSentSelectionCenterGlobal;
 +    bool                    mShowSelection; // do we send the selection center name value and do we animate this selection?
 +    LLVector3d              mLastCameraPos;     // camera position from last generation of selection silhouette
 +    bool                    mRenderSilhouettes; // do we render the silhouette
 +    LLBBox                  mSavedSelectionBBox;
 +
 +    LLFrameTimer            mEffectsTimer;
 +    bool                    mForceSelection;
 +
 +    std::vector<LLAnimPauseRequest> mPauseRequests;
 +};
 +
 +// *DEPRECATED: For callbacks or observers, use
 +// LLSelectMgr::getInstance()->mUpdateSignal.connect( callback )
 +// Update subscribers to the selection list
 +void dialog_refresh_all();
 +
 +// Templates
 +//-----------------------------------------------------------------------------
 +// getSelectedTEValue
 +//-----------------------------------------------------------------------------
 +template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res, bool has_tolerance, T tolerance)
 +{
 +    bool have_first = false;
 +    bool have_selected = false;
 +    T selected_value = T();
 +
 +    // Now iterate through all TEs to test for sameness
 +    bool identical = true;
 +    for (iterator iter = begin(); iter != end(); iter++)
 +    {
 +        LLSelectNode* node = *iter;
 +        LLViewerObject* object = node->getObject();
 +        S32 selected_te = -1;
 +        if (object == getPrimaryObject())
 +        {
 +            selected_te = node->getLastSelectedTE();
 +        }
 +        for (S32 te = 0; te < object->getNumTEs(); ++te)
 +        {
 +            if (!node->isTESelected(te))
 +            {
 +                continue;
 +            }
 +            T value = func->get(object, te);
 +            if (!have_first)
 +            {
 +                have_first = true;
 +                if (!have_selected)
 +                {
 +                    selected_value = value;
 +                }
 +            }
 +            else
 +            {
 +                if ( value != selected_value )
 +                {
 +                    if (!has_tolerance)
 +                    {
 +                        identical = false;
 +                    }
 +                    else if (!LLCheckIdenticalFunctor<T>::same(value, selected_value, tolerance))
 +                    {
 +                        identical = false;
 +                    }
 +                }
 +                if (te == selected_te)
 +                {
 +                    selected_value = value;
 +                    have_selected = true;
 +                }
 +            }
 +        }
 +        if (!identical && have_selected)
 +        {
 +            break;
 +        }
 +    }
 +    if (have_first || have_selected)
 +    {
 +        res = selected_value;
 +    }
 +    return identical;
 +}
 +
 +// Templates
 +//-----------------------------------------------------------------------------
 +// isMultipleTEValue iterate through all TEs and test for uniqueness
 +// with certain return value ignored when performing the test.
 +// e.g. when testing if the selection has a unique non-empty homeurl :
 +// you can set ignore_value = "" and it will only compare among the non-empty
 +// homeUrls and ignore the empty ones.
 +//-----------------------------------------------------------------------------
 +template <typename T> bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value)
 +{
 +    bool have_first = false;
 +    T selected_value = T();
 +
 +    // Now iterate through all TEs to test for sameness
 +    bool unique = true;
 +    for (iterator iter = begin(); iter != end(); iter++)
 +    {
 +        LLSelectNode* node = *iter;
 +        LLViewerObject* object = node->getObject();
 +        for (S32 te = 0; te < object->getNumTEs(); ++te)
 +        {
 +            if (!node->isTESelected(te))
 +            {
 +                continue;
 +            }
 +            T value = func->get(object, te);
 +            if(value == ignore_value)
 +            {
 +                continue;
 +            }
 +            if (!have_first)
 +            {
 +                have_first = true;
 +            }
 +            else
 +            {
 +                if (value !=selected_value  )
 +                {
 +                    unique = false;
 +                    return !unique;
 +                }
 +            }
 +        }
 +    }
 +    return !unique;
 +}
 +
 +
 +#endif
  | 
