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 78f51d0aec..bbc6d566cb 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 |