/indra/newview/llselectmgr.cpp
https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 2415 lines · 1817 code · 300 blank · 298 comment · 267 complexity · ca67b7068cb2644ccd7bc23e3c748406 MD5 · raw file
- /**
- * @file llselectmgr.cpp
- * @brief A manager for selected objects and faces.
- *
- * $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$
- */
- #include "llviewerprecompiledheaders.h"
- // file include
- #define LLSELECTMGR_CPP
- #include "llselectmgr.h"
- // library includes
- #include "llcachename.h"
- #include "lldbstrings.h"
- #include "lleconomy.h"
- #include "llgl.h"
- #include "llmediaentry.h"
- #include "llrender.h"
- #include "llnotifications.h"
- #include "llpermissions.h"
- #include "llpermissionsflags.h"
- #include "lltrans.h"
- #include "llundo.h"
- #include "lluuid.h"
- #include "llvolume.h"
- #include "message.h"
- #include "object_flags.h"
- #include "llquaternion.h"
- // viewer includes
- #include "llagent.h"
- #include "llagentcamera.h"
- #include "llviewerwindow.h"
- #include "lldrawable.h"
- #include "llfloaterinspect.h"
- #include "llfloaterproperties.h"
- #include "llfloaterreporter.h"
- #include "llfloaterreg.h"
- #include "llfloatertools.h"
- #include "llframetimer.h"
- #include "llfocusmgr.h"
- #include "llhudeffecttrail.h"
- #include "llhudmanager.h"
- #include "llinventorymodel.h"
- #include "llmenugl.h"
- #include "llmeshrepository.h"
- #include "llmutelist.h"
- #include "llnotificationsutil.h"
- #include "llsidepaneltaskinfo.h"
- #include "llslurl.h"
- #include "llstatusbar.h"
- #include "llsurface.h"
- #include "lltool.h"
- #include "lltooldraganddrop.h"
- #include "lltoolmgr.h"
- #include "lltoolpie.h"
- #include "llui.h"
- #include "llviewercamera.h"
- #include "llviewercontrol.h"
- #include "llviewertexturelist.h"
- #include "llviewermedia.h"
- #include "llviewermediafocus.h"
- #include "llviewermenu.h"
- #include "llviewerobject.h"
- #include "llviewerobjectlist.h"
- #include "llviewerregion.h"
- #include "llviewerstats.h"
- #include "llvoavatarself.h"
- #include "llvovolume.h"
- #include "pipeline.h"
- #include "llviewershadermgr.h"
- #include "llglheaders.h"
- LLViewerObject* getSelectedParentObject(LLViewerObject *object) ;
- //
- // Consts
- //
- const S32 NUM_SELECTION_UNDO_ENTRIES = 200;
- const F32 SILHOUETTE_UPDATE_THRESHOLD_SQUARED = 0.02f;
- const S32 MAX_ACTION_QUEUE_SIZE = 20;
- const S32 MAX_SILS_PER_FRAME = 50;
- const S32 MAX_OBJECTS_PER_PACKET = 254;
- const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
- //
- // Globals
- //
- //BOOL gDebugSelectMgr = FALSE;
- //BOOL gHideSelectedObjects = FALSE;
- //BOOL gAllowSelectAvatar = FALSE;
- BOOL LLSelectMgr::sRectSelectInclusive = TRUE;
- BOOL LLSelectMgr::sRenderHiddenSelections = TRUE;
- BOOL LLSelectMgr::sRenderLightRadius = FALSE;
- F32 LLSelectMgr::sHighlightThickness = 0.f;
- F32 LLSelectMgr::sHighlightUScale = 0.f;
- F32 LLSelectMgr::sHighlightVScale = 0.f;
- F32 LLSelectMgr::sHighlightAlpha = 0.f;
- F32 LLSelectMgr::sHighlightAlphaTest = 0.f;
- F32 LLSelectMgr::sHighlightUAnim = 0.f;
- F32 LLSelectMgr::sHighlightVAnim = 0.f;
- LLColor4 LLSelectMgr::sSilhouetteParentColor;
- LLColor4 LLSelectMgr::sSilhouetteChildColor;
- LLColor4 LLSelectMgr::sHighlightInspectColor;
- LLColor4 LLSelectMgr::sHighlightParentColor;
- LLColor4 LLSelectMgr::sHighlightChildColor;
- LLColor4 LLSelectMgr::sContextSilhouetteColor;
- static LLObjectSelection *get_null_object_selection();
- template<>
- const LLSafeHandle<LLObjectSelection>::NullFunc
- LLSafeHandle<LLObjectSelection>::sNullFunc = get_null_object_selection;
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // struct LLDeRezInfo
- //
- // Used to keep track of important derez info.
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- struct LLDeRezInfo
- {
- EDeRezDestination mDestination;
- LLUUID mDestinationID;
- LLDeRezInfo(EDeRezDestination dest, const LLUUID& dest_id) :
- mDestination(dest), mDestinationID(dest_id) {}
- };
- //
- // Imports
- //
- static LLPointer<LLObjectSelection> sNullSelection;
- //
- // Functions
- //
- void LLSelectMgr::cleanupGlobals()
- {
- sNullSelection = NULL;
- LLSelectMgr::getInstance()->clearSelections();
- }
- LLObjectSelection *get_null_object_selection()
- {
- if (sNullSelection.isNull())
- {
- sNullSelection = new LLObjectSelection;
- }
- return sNullSelection;
- }
- // Build time optimization, generate this function once here
- template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
- //-----------------------------------------------------------------------------
- // LLSelectMgr()
- //-----------------------------------------------------------------------------
- LLSelectMgr::LLSelectMgr()
- : mHideSelectedObjects(LLCachedControl<bool>(gSavedSettings, "HideSelectedObjects", FALSE)),
- mRenderHighlightSelections(LLCachedControl<bool>(gSavedSettings, "RenderHighlightSelections", TRUE)),
- mAllowSelectAvatar( LLCachedControl<bool>(gSavedSettings, "AllowSelectAvatar", FALSE)),
- mDebugSelectMgr(LLCachedControl<bool>(gSavedSettings, "DebugSelectMgr", FALSE))
- {
- mTEMode = FALSE;
- mLastCameraPos.clearVec();
- sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness");
- sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale");
- sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale");
- sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha");
- sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest");
- sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim");
- sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim");
- sSilhouetteParentColor =LLUIColorTable::instance().getColor("SilhouetteParentColor");
- sSilhouetteChildColor = LLUIColorTable::instance().getColor("SilhouetteChildColor");
- sHighlightParentColor = LLUIColorTable::instance().getColor("HighlightParentColor");
- sHighlightChildColor = LLUIColorTable::instance().getColor("HighlightChildColor");
- sHighlightInspectColor = LLUIColorTable::instance().getColor("HighlightInspectColor");
- sContextSilhouetteColor = LLUIColorTable::instance().getColor("ContextSilhouetteColor")*0.5f;
- sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
-
- mRenderSilhouettes = TRUE;
- mGridMode = GRID_MODE_WORLD;
- gSavedSettings.setS32("GridMode", (S32)GRID_MODE_WORLD);
- mGridValid = FALSE;
- mSelectedObjects = new LLObjectSelection();
- mHoverObjects = new LLObjectSelection();
- mHighlightedObjects = new LLObjectSelection();
- mForceSelection = FALSE;
- mShowSelection = FALSE;
- }
- //-----------------------------------------------------------------------------
- // ~LLSelectMgr()
- //-----------------------------------------------------------------------------
- LLSelectMgr::~LLSelectMgr()
- {
- clearSelections();
- }
- void LLSelectMgr::clearSelections()
- {
- mHoverObjects->deleteAllNodes();
- mSelectedObjects->deleteAllNodes();
- mHighlightedObjects->deleteAllNodes();
- mRectSelectedObjects.clear();
- mGridObjects.deleteAllNodes();
- }
- void LLSelectMgr::update()
- {
- mSelectedObjects->cleanupNodes();
- }
- void LLSelectMgr::updateEffects()
- {
- //keep reference grid objects active
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- LLDrawable* drawable = object->mDrawable;
- if (drawable)
- {
- gPipeline.markMoved(drawable);
- }
- return true;
- }
- } func;
- mGridObjects.applyToObjects(&func);
- if (mEffectsTimer.getElapsedTimeF32() > 1.f)
- {
- mSelectedObjects->updateEffects();
- mEffectsTimer.reset();
- }
- }
- void LLSelectMgr::overrideObjectUpdates()
- {
- //override any position updates from simulator on objects being edited
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* selectNode)
- {
- LLViewerObject* object = selectNode->getObject();
- if (object && object->permMove())
- {
- if (!selectNode->mLastPositionLocal.isExactlyZero())
- {
- object->setPosition(selectNode->mLastPositionLocal);
- }
- if (selectNode->mLastRotation != LLQuaternion())
- {
- object->setRotation(selectNode->mLastRotation);
- }
- if (!selectNode->mLastScale.isExactlyZero())
- {
- object->setScale(selectNode->mLastScale);
- }
- }
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
- }
- //-----------------------------------------------------------------------------
- // Select just the object, not any other group members.
- //-----------------------------------------------------------------------------
- LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S32 face)
- {
- llassert( object );
- //remember primary object
- mSelectedObjects->mPrimaryObject = object;
- // Don't add an object that is already in the list
- if (object->isSelected() ) {
- // make sure point at position is updated
- updatePointAt();
- gEditMenuHandler = this;
- return NULL;
- }
- if (!canSelectObject(object))
- {
- //make_ui_sound("UISndInvalidOp");
- return NULL;
- }
- // llinfos << "Adding object to selected object list" << llendl;
- // Place it in the list and tag it.
- // This will refresh dialogs.
- addAsIndividual(object, face);
- // Stop the object from moving (this anticipates changes on the
- // simulator in LLTask::userSelect)
- // *FIX: shouldn't zero out these either
- object->setVelocity(LLVector3::zero);
- object->setAcceleration(LLVector3::zero);
- //object->setAngularVelocity(LLVector3::zero);
- object->resetRot();
- // Always send to simulator, so you get a copy of the
- // permissions structure back.
- gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- LLViewerRegion* regionp = object->getRegion();
- gMessageSystem->sendReliable( regionp->getHost());
- updatePointAt();
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- // have selection manager handle edit menu immediately after
- // user selects an object
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
- return mSelectedObjects;
- }
- //-----------------------------------------------------------------------------
- // Select the object, parents and children.
- //-----------------------------------------------------------------------------
- LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(LLViewerObject* obj, BOOL add_to_end)
- {
- llassert( obj );
- //remember primary object
- mSelectedObjects->mPrimaryObject = obj;
- // This may be incorrect if things weren't family selected before... - djs 07/08/02
- // Don't add an object that is already in the list
- if (obj->isSelected() )
- {
- // make sure pointat position is updated
- updatePointAt();
- gEditMenuHandler = this;
- return NULL;
- }
- if (!canSelectObject(obj))
- {
- //make_ui_sound("UISndInvalidOp");
- return NULL;
- }
- // Since we're selecting a family, start at the root, but
- // don't include an avatar.
- LLViewerObject* root = obj;
-
- while(!root->isAvatar() && root->getParent() && !root->isJointChild())
- {
- LLViewerObject* parent = (LLViewerObject*)root->getParent();
- if (parent->isAvatar())
- {
- break;
- }
- root = parent;
- }
- // Collect all of the objects
- std::vector<LLViewerObject*> objects;
- root->addThisAndNonJointChildren(objects);
- addAsFamily(objects, add_to_end);
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updatePointAt();
- dialog_refresh_all();
- // Always send to simulator, so you get a copy of the permissions
- // structure back.
- sendSelect();
- // Stop the object from moving (this anticipates changes on the
- // simulator in LLTask::userSelect)
- root->setVelocity(LLVector3::zero);
- root->setAcceleration(LLVector3::zero);
- //root->setAngularVelocity(LLVector3::zero);
- root->resetRot();
- // leave component mode
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- gSavedSettings.setBOOL("EditLinkedParts", FALSE);
- promoteSelectionToRoot();
- }
- // have selection manager handle edit menu immediately after
- // user selects an object
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
- return mSelectedObjects;
- }
- //-----------------------------------------------------------------------------
- // Select the object, parents and children.
- //-----------------------------------------------------------------------------
- LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list,
- BOOL send_to_sim)
- {
- // Collect all of the objects, children included
- std::vector<LLViewerObject*> objects;
- //clear primary object (no primary object)
- mSelectedObjects->mPrimaryObject = NULL;
- if (object_list.size() < 1)
- {
- return NULL;
- }
-
- // NOTE -- we add the objects in REVERSE ORDER
- // to preserve the order in the mSelectedObjects list
- for (std::vector<LLViewerObject*>::const_reverse_iterator riter = object_list.rbegin();
- riter != object_list.rend(); ++riter)
- {
- LLViewerObject *object = *riter;
- llassert( object );
- if (!canSelectObject(object)) continue;
- object->addThisAndNonJointChildren(objects);
- addAsFamily(objects);
- // Stop the object from moving (this anticipates changes on the
- // simulator in LLTask::userSelect)
- object->setVelocity(LLVector3::zero);
- object->setAcceleration(LLVector3::zero);
- //object->setAngularVelocity(LLVector3::zero);
- object->resetRot();
- }
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updatePointAt();
- dialog_refresh_all();
- // Almost always send to simulator, so you get a copy of the permissions
- // structure back.
- // JC: The one case where you don't want to do this is if you're selecting
- // all the objects on a sim.
- if (send_to_sim)
- {
- sendSelect();
- }
- // leave component mode
- if (gSavedSettings.getBOOL("EditLinkedParts"))
- {
- gSavedSettings.setBOOL("EditLinkedParts", FALSE);
- promoteSelectionToRoot();
- }
- // have selection manager handle edit menu immediately after
- // user selects an object
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
- return mSelectedObjects;
- }
- // Use for when the simulator kills an object. This version also
- // handles informing the current tool of the object's deletion.
- //
- // Caller needs to call dialog_refresh_all if necessary.
- BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id)
- {
- BOOL object_found = FALSE;
- LLTool *tool = NULL;
- tool = LLToolMgr::getInstance()->getCurrentTool();
- // It's possible that the tool is editing an object that is not selected
- LLViewerObject* tool_editing_object = tool->getEditingObject();
- if( tool_editing_object && tool_editing_object->mID == id)
- {
- tool->stopEditing();
- object_found = TRUE;
- }
- // Iterate through selected objects list and kill the object
- if( !object_found )
- {
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); )
- {
- LLObjectSelection::iterator curiter = iter++;
- LLViewerObject* object = (*curiter)->getObject();
- if (object->mID == id)
- {
- if (tool)
- {
- tool->stopEditing();
- }
- // lose the selection, don't tell simulator, it knows
- deselectObjectAndFamily(object, FALSE);
- object_found = TRUE;
- break; // must break here, may have removed multiple objects from list
- }
- else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id)
- {
- // It's possible the item being removed has an avatar sitting on it
- // So remove the avatar that is sitting on the object.
- deselectObjectAndFamily(object, FALSE);
- break; // must break here, may have removed multiple objects from list
- }
- }
- }
- return object_found;
- }
- bool LLSelectMgr::linkObjects()
- {
- if (!LLSelectMgr::getInstance()->selectGetAllRootsValid())
- {
- LLNotificationsUtil::add("UnableToLinkWhileDownloading");
- return true;
- }
- S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
- if (object_count > MAX_CHILDREN_PER_TASK + 1)
- {
- LLSD args;
- args["COUNT"] = llformat("%d", object_count);
- int max = MAX_CHILDREN_PER_TASK+1;
- args["MAX"] = llformat("%d", max);
- LLNotificationsUtil::add("UnableToLinkObjects", args);
- return true;
- }
- if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2)
- {
- LLNotificationsUtil::add("CannotLinkIncompleteSet");
- return true;
- }
- if (!LLSelectMgr::getInstance()->selectGetRootsModify())
- {
- LLNotificationsUtil::add("CannotLinkModify");
- return true;
- }
- LLUUID owner_id;
- std::string owner_name;
- if (!LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name))
- {
- // we don't actually care if you're the owner, but novices are
- // the most likely to be stumped by this one, so offer the
- // easiest and most likely solution.
- LLNotificationsUtil::add("CannotLinkDifferentOwners");
- return true;
- }
- LLSelectMgr::getInstance()->sendLink();
- return true;
- }
- bool LLSelectMgr::unlinkObjects()
- {
- LLSelectMgr::getInstance()->sendDelink();
- return true;
- }
- // in order to link, all objects must have the same owner, and the
- // agent must have the ability to modify all of the objects. However,
- // we're not answering that question with this method. The question
- // we're answering is: does the user have a reasonable expectation
- // that a link operation should work? If so, return true, false
- // otherwise. this allows the handle_link method to more finely check
- // the selection and give an error message when the uer has a
- // reasonable expectation for the link to work, but it will fail.
- bool LLSelectMgr::enableLinkObjects()
- {
- bool new_value = false;
- // check if there are at least 2 objects selected, and that the
- // user can modify at least one of the selected objects.
- // in component mode, can't link
- if (!gSavedSettings.getBOOL("EditLinkedParts"))
- {
- if(LLSelectMgr::getInstance()->selectGetAllRootsValid() && LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() >= 2)
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- return object->permModify();
- }
- } func;
- const bool firstonly = true;
- new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
- }
- }
- return new_value;
- }
- bool LLSelectMgr::enableUnlinkObjects()
- {
- LLViewerObject* first_editable_object = LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject();
- bool new_value = LLSelectMgr::getInstance()->selectGetAllRootsValid() &&
- first_editable_object &&
- !first_editable_object->isAttachment();
- return new_value;
- }
- void LLSelectMgr::deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim, BOOL include_entire_object)
- {
- // bail if nothing selected or if object wasn't selected in the first place
- if(!object) return;
- if(!object->isSelected()) return;
- // Collect all of the objects, and remove them
- std::vector<LLViewerObject*> objects;
- if (include_entire_object)
- {
- // Since we're selecting a family, start at the root, but
- // don't include an avatar.
- LLViewerObject* root = object;
-
- while(!root->isAvatar() && root->getParent() && !root->isJointChild())
- {
- LLViewerObject* parent = (LLViewerObject*)root->getParent();
- if (parent->isAvatar())
- {
- break;
- }
- root = parent;
- }
-
- object = root;
- }
- else
- {
- object = (LLViewerObject*)object->getRoot();
- }
- object->addThisAndAllChildren(objects);
- remove(objects);
- if (!send_to_sim) return;
- //-----------------------------------------------------------
- // Inform simulator of deselection
- //-----------------------------------------------------------
- LLViewerRegion* regionp = object->getRegion();
- BOOL start_new_message = TRUE;
- S32 select_count = 0;
- LLMessageSystem* msg = gMessageSystem;
- for (U32 i = 0; i < objects.size(); i++)
- {
- if (start_new_message)
- {
- msg->newMessageFast(_PREHASH_ObjectDeselect);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- select_count++;
- start_new_message = FALSE;
- }
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_ObjectLocalID, (objects[i])->getLocalID());
- select_count++;
- // Zap the angular velocity, as the sim will set it to zero
- objects[i]->setAngularVelocity( 0,0,0 );
- objects[i]->setVelocity( 0,0,0 );
- if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET)
- {
- msg->sendReliable(regionp->getHost() );
- select_count = 0;
- start_new_message = TRUE;
- }
- }
- if (!start_new_message)
- {
- msg->sendReliable(regionp->getHost() );
- }
- updatePointAt();
- updateSelectionCenter();
- }
- void LLSelectMgr::deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim)
- {
- // bail if nothing selected or if object wasn't selected in the first place
- if (!object) return;
- if (!object->isSelected() ) return;
- // Zap the angular velocity, as the sim will set it to zero
- object->setAngularVelocity( 0,0,0 );
- object->setVelocity( 0,0,0 );
- if (send_to_sim)
- {
- LLViewerRegion* region = object->getRegion();
- gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- gMessageSystem->sendReliable(region->getHost());
- }
- // This will refresh dialogs.
- remove( object );
- updatePointAt();
- updateSelectionCenter();
- }
- //-----------------------------------------------------------------------------
- // addAsFamily
- //-----------------------------------------------------------------------------
- void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end)
- {
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
-
- // Can't select yourself
- if (objectp->mID == gAgentID
- && !LLSelectMgr::getInstance()->mAllowSelectAvatar)
- {
- continue;
- }
- if (!objectp->isSelected())
- {
- LLSelectNode *nodep = new LLSelectNode(objectp, TRUE);
- if (add_to_end)
- {
- mSelectedObjects->addNodeAtEnd(nodep);
- }
- else
- {
- mSelectedObjects->addNode(nodep);
- }
- objectp->setSelected(TRUE);
- if (objectp->getNumTEs() > 0)
- {
- nodep->selectAllTEs(TRUE);
- }
- else
- {
- // object has no faces, so don't mess with faces
- }
- }
- else
- {
- // we want this object to be selected for real
- // so clear transient flag
- LLSelectNode* select_node = mSelectedObjects->findNode(objectp);
- if (select_node)
- {
- select_node->setTransient(FALSE);
- }
- }
- }
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- }
- //-----------------------------------------------------------------------------
- // addAsIndividual() - a single object, face, etc
- //-----------------------------------------------------------------------------
- void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoable)
- {
- // check to see if object is already in list
- LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
- // if not in list, add it
- if (!nodep)
- {
- nodep = new LLSelectNode(objectp, TRUE);
- mSelectedObjects->addNode(nodep);
- llassert_always(nodep->getObject());
- }
- else
- {
- // make this a full-fledged selection
- nodep->setTransient(FALSE);
- // Move it to the front of the list
- mSelectedObjects->moveNodeToFront(nodep);
- }
- // Make sure the object is tagged as selected
- objectp->setSelected( TRUE );
- // And make sure we don't consider it as part of a family
- nodep->mIndividualSelection = TRUE;
- // Handle face selection
- if (objectp->getNumTEs() <= 0)
- {
- // object has no faces, so don't do anything
- }
- else if (face == SELECT_ALL_TES)
- {
- nodep->selectAllTEs(TRUE);
- }
- else if (0 <= face && face < SELECT_MAX_TES)
- {
- nodep->selectTE(face, TRUE);
- }
- else
- {
- llerrs << "LLSelectMgr::add face " << face << " out-of-range" << llendl;
- return;
- }
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updateSelectionCenter();
- dialog_refresh_all();
- }
- LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face)
- {
- if (!objectp)
- {
- mHoverObjects->deleteAllNodes();
- return NULL;
- }
- // Can't select yourself
- if (objectp->mID == gAgentID)
- {
- mHoverObjects->deleteAllNodes();
- return NULL;
- }
- // Can't select land
- if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
- {
- mHoverObjects->deleteAllNodes();
- return NULL;
- }
- mHoverObjects->mPrimaryObject = objectp;
- objectp = objectp->getRootEdit();
- // is the requested object the same as the existing hover object root?
- // NOTE: there is only ever one linked set in mHoverObjects
- if (mHoverObjects->getFirstRootObject() != objectp)
- {
- // Collect all of the objects
- std::vector<LLViewerObject*> objects;
- objectp = objectp->getRootEdit();
- objectp->addThisAndNonJointChildren(objects);
- mHoverObjects->deleteAllNodes();
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* cur_objectp = *iter;
- LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE);
- nodep->selectTE(face, TRUE);
- mHoverObjects->addNodeAtEnd(nodep);
- }
- requestObjectPropertiesFamily(objectp);
- }
- return mHoverObjects;
- }
- LLSelectNode *LLSelectMgr::getHoverNode()
- {
- return mHoverObjects->getFirstRootNode();
- }
- LLSelectNode *LLSelectMgr::getPrimaryHoverNode()
- {
- return mHoverObjects->mSelectNodeMap[mHoverObjects->mPrimaryObject];
- }
- void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
- {
- if (!objectp)
- {
- return;
- }
- if (objectp->getPCode() != LL_PCODE_VOLUME)
- {
- return;
- }
-
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
- || (gSavedSettings.getBOOL("SelectMovableOnly") && !objectp->permMove()))
- {
- // only select my own objects
- return;
- }
- mRectSelectedObjects.insert(objectp);
- }
- void LLSelectMgr::highlightObjectAndFamily(LLViewerObject* objectp)
- {
- if (!objectp)
- {
- return;
- }
- LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
- highlightObjectOnly(root_obj);
- LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- highlightObjectOnly(child);
- }
- }
- // Note that this ignores the "select owned only" flag
- // It's also more efficient than calling the single-object version over and over.
- void LLSelectMgr::highlightObjectAndFamily(const std::vector<LLViewerObject*>& objects)
- {
- for (std::vector<LLViewerObject*>::const_iterator iter1 = objects.begin();
- iter1 != objects.end(); ++iter1)
- {
- LLViewerObject* object = *iter1;
- if (!object)
- {
- continue;
- }
- if (object->getPCode() != LL_PCODE_VOLUME)
- {
- continue;
- }
- LLViewerObject* root = (LLViewerObject*)object->getRoot();
- mRectSelectedObjects.insert(root);
- LLViewerObject::const_child_list_t& child_list = root->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter2 = child_list.begin();
- iter2 != child_list.end(); iter2++)
- {
- LLViewerObject* child = *iter2;
- mRectSelectedObjects.insert(child);
- }
- }
- }
- void LLSelectMgr::unhighlightObjectOnly(LLViewerObject* objectp)
- {
- if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
- {
- return;
- }
- mRectSelectedObjects.erase(objectp);
- }
- void LLSelectMgr::unhighlightObjectAndFamily(LLViewerObject* objectp)
- {
- if (!objectp)
- {
- return;
- }
- LLViewerObject* root_obj = (LLViewerObject*)objectp->getRoot();
- unhighlightObjectOnly(root_obj);
- LLViewerObject::const_child_list_t& child_list = root_obj->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- unhighlightObjectOnly(child);
- }
- }
- void LLSelectMgr::unhighlightAll()
- {
- mRectSelectedObjects.clear();
- mHighlightedObjects->deleteAllNodes();
- }
- LLObjectSelectionHandle LLSelectMgr::selectHighlightedObjects()
- {
- if (!mHighlightedObjects->getNumNodes())
- {
- return NULL;
- }
- //clear primary object
- mSelectedObjects->mPrimaryObject = NULL;
- for (LLObjectSelection::iterator iter = getHighlightedObjects()->begin();
- iter != getHighlightedObjects()->end(); )
- {
- LLObjectSelection::iterator curiter = iter++;
-
- LLSelectNode *nodep = *curiter;
- LLViewerObject* objectp = nodep->getObject();
- if (!canSelectObject(objectp))
- {
- continue;
- }
- // already selected
- if (objectp->isSelected())
- {
- continue;
- }
- LLSelectNode* new_nodep = new LLSelectNode(*nodep);
- mSelectedObjects->addNode(new_nodep);
- // flag this object as selected
- objectp->setSelected(TRUE);
- mSelectedObjects->mSelectType = getSelectTypeForObject(objectp);
- // request properties on root objects
- if (objectp->isRootEdit())
- {
- requestObjectPropertiesFamily(objectp);
- }
- }
- // pack up messages to let sim know these objects are selected
- sendSelect();
- unhighlightAll();
- updateSelectionCenter();
- saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- updatePointAt();
- if (mSelectedObjects->getObjectCount())
- {
- gEditMenuHandler = this;
- }
- return mSelectedObjects;
- }
- void LLSelectMgr::deselectHighlightedObjects()
- {
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
- iter != mRectSelectedObjects.end(); iter++)
- {
- LLViewerObject *objectp = *iter;
- if (!select_linked_set)
- {
- deselectObjectOnly(objectp);
- }
- else
- {
- LLViewerObject* root_object = (LLViewerObject*)objectp->getRoot();
- if (root_object->isSelected())
- {
- deselectObjectAndFamily(root_object);
- }
- }
- }
- unhighlightAll();
- }
- void LLSelectMgr::addGridObject(LLViewerObject* objectp)
- {
- LLSelectNode* nodep = new LLSelectNode(objectp, FALSE);
- mGridObjects.addNodeAtEnd(nodep);
- LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- nodep = new LLSelectNode(child, FALSE);
- mGridObjects.addNodeAtEnd(nodep);
- }
- }
- void LLSelectMgr::clearGridObjects()
- {
- mGridObjects.deleteAllNodes();
- }
- void LLSelectMgr::setGridMode(EGridMode mode)
- {
- mGridMode = mode;
- gSavedSettings.setS32("GridMode", mode);
- updateSelectionCenter();
- mGridValid = FALSE;
- }
- void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &scale)
- {
- mGridObjects.cleanupNodes();
-
- LLViewerObject* first_grid_object = mGridObjects.getFirstObject();
- if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
- {
- //LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject());
- LLBBox bbox = mSavedSelectionBBox;
- mGridOrigin = mSavedSelectionBBox.getCenterAgent();
- mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
- // DEV-12570 Just taking the saved selection box rotation prevents
- // wild rotations of linked sets while in local grid mode
- //if(mSelectedObjects->getObjectCount() < 2 || !root || root->mDrawable.isNull())
- {
- mGridRotation = mSavedSelectionBBox.getRotation();
- }
- /*else //set to the root object
- {
- mGridRotation = root->getRenderRotation();
- }*/
- }
- else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
- {
- mGridRotation = first_grid_object->getRenderRotation();
- LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
- LLVector4a min_extents(F32_MAX);
- LLVector4a max_extents(-F32_MAX);
- BOOL grid_changed = FALSE;
- for (LLObjectSelection::iterator iter = mGridObjects.begin();
- iter != mGridObjects.end(); ++iter)
- {
- LLViewerObject* object = (*iter)->getObject();
- LLDrawable* drawable = object->mDrawable;
- if (drawable)
- {
- const LLVector4a* ext = drawable->getSpatialExtents();
- update_min_max(min_extents, max_extents, ext[0]);
- update_min_max(min_extents, max_extents, ext[1]);
- grid_changed = TRUE;
- }
- }
- if (grid_changed)
- {
- LLVector4a center, size;
- center.setAdd(min_extents, max_extents);
- center.mul(0.5f);
- size.setSub(max_extents, min_extents);
- size.mul(0.5f);
- mGridOrigin.set(center.getF32ptr());
- LLDrawable* drawable = first_grid_object->mDrawable;
- if (drawable && drawable->isActive())
- {
- mGridOrigin = mGridOrigin * first_grid_object->getRenderMatrix();
- }
- mGridScale.set(size.getF32ptr());
- }
- }
- else // GRID_MODE_WORLD or just plain default
- {
- const BOOL non_root_ok = TRUE;
- LLViewerObject* first_object = mSelectedObjects->getFirstRootObject(non_root_ok);
- mGridOrigin.clearVec();
- mGridRotation.loadIdentity();
- mSelectedObjects->mSelectType = getSelectTypeForObject( first_object );
- switch (mSelectedObjects->mSelectType)
- {
- case SELECT_TYPE_ATTACHMENT:
- if (first_object && first_object->getRootEdit()->mDrawable.notNull())
- {
- // this means this object *has* to be an attachment
- LLXform* attachment_point_xform = first_object->getRootEdit()->mDrawable->mXform.getParent();
- mGridOrigin = attachment_point_xform->getWorldPosition();
- mGridRotation = attachment_point_xform->getWorldRotation();
- mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
- }
- break;
- case SELECT_TYPE_HUD:
- // use HUD-scaled grid
- mGridScale = LLVector3(0.25f, 0.25f, 0.25f);
- break;
- case SELECT_TYPE_WORLD:
- mGridScale = LLVector3(1.f, 1.f, 1.f) * gSavedSettings.getF32("GridResolution");
- break;
- }
- }
- llassert(mGridOrigin.isFinite());
- origin = mGridOrigin;
- rotation = mGridRotation;
- scale = mGridScale;
- mGridValid = TRUE;
- }
- //-----------------------------------------------------------------------------
- // remove() - an array of objects
- //-----------------------------------------------------------------------------
- void LLSelectMgr::remove(std::vector<LLViewerObject*>& objects)
- {
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
- if (nodep)
- {
- objectp->setSelected(FALSE);
- mSelectedObjects->removeNode(nodep);
- nodep = NULL;
- }
- }
- updateSelectionCenter();
- dialog_refresh_all();
- }
- //-----------------------------------------------------------------------------
- // remove() - a single object
- //-----------------------------------------------------------------------------
- void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable)
- {
- // get object node (and verify it is in the selected list)
- LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
- if (!nodep)
- {
- return;
- }
- // if face = all, remove object from list
- if ((objectp->getNumTEs() <= 0) || (te == SELECT_ALL_TES))
- {
- // Remove all faces (or the object doesn't have faces) so remove the node
- mSelectedObjects->removeNode(nodep);
- nodep = NULL;
- objectp->setSelected( FALSE );
- }
- else if (0 <= te && te < SELECT_MAX_TES)
- {
- // ...valid face, check to see if it was on
- if (nodep->isTESelected(te))
- {
- nodep->selectTE(te, FALSE);
- }
- else
- {
- llerrs << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl;
- return;
- }
- // ...check to see if this operation turned off all faces
- BOOL found = FALSE;
- for (S32 i = 0; i < nodep->getObject()->getNumTEs(); i++)
- {
- found = found || nodep->isTESelected(i);
- }
- // ...all faces now turned off, so remove
- if (!found)
- {
- mSelectedObjects->removeNode(nodep);
- nodep = NULL;
- objectp->setSelected( FALSE );
- // *FIXME: Doesn't update simulator that object is no longer selected
- }
- }
- else
- {
- // ...out of range face
- llerrs << "LLSelectMgr::remove - TE " << te << " out of range" << llendl;
- }
- updateSelectionCenter();
- dialog_refresh_all();
- }
- //-----------------------------------------------------------------------------
- // removeAll()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::removeAll()
- {
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++ )
- {
- LLViewerObject *objectp = (*iter)->getObject();
- objectp->setSelected( FALSE );
- }
- mSelectedObjects->deleteAllNodes();
-
- updateSelectionCenter();
- dialog_refresh_all();
- }
- //-----------------------------------------------------------------------------
- // promoteSelectionToRoot()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::promoteSelectionToRoot()
- {
- std::set<LLViewerObject*> selection_set;
- BOOL selection_changed = FALSE;
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); )
- {
- LLObjectSelection::iterator curiter = iter++;
- LLSelectNode* nodep = *curiter;
- LLViewerObject* object = nodep->getObject();
- if (nodep->mIndividualSelection)
- {
- selection_changed = TRUE;
- }
- LLViewerObject* parentp = object;
- while(parentp->getParent() && !(parentp->isRootEdit() || parentp->isJointChild()))
- {
- parentp = (LLViewerObject*)parentp->getParent();
- }
-
- selection_set.insert(parentp);
- }
- if (selection_changed)
- {
- deselectAll();
- std::set<LLViewerObject*>::iterator set_iter;
- for (set_iter = selection_set.begin(); set_iter != selection_set.end(); ++set_iter)
- {
- selectObjectAndFamily(*set_iter);
- }
- }
- }
- //-----------------------------------------------------------------------------
- // demoteSelectionToIndividuals()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::demoteSelectionToIndividuals()
- {
- std::vector<LLViewerObject*> objects;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- LLViewerObject* object = (*iter)->getObject();
- object->addThisAndNonJointChildren(objects);
- }
- if (!objects.empty())
- {
- deselectAll();
- for (std::vector<LLViewerObject*>::iterator iter = objects.begin();
- iter != objects.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- selectObjectOnly(objectp);
- }
- }
- }
- //-----------------------------------------------------------------------------
- // dump()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::dump()
- {
- llinfos << "Selection Manager: " << mSelectedObjects->getNumNodes() << " items" << llendl;
- llinfos << "TE mode " << mTEMode << llendl;
- S32 count = 0;
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLViewerObject* objectp = (*iter)->getObject();
- llinfos << "Object " << count << " type " << LLPrimitive::pCodeToString(objectp->getPCode()) << llendl;
- llinfos << " hasLSL " << objectp->flagScripted() << llendl;
- llinfos << " hasTouch " << objectp->flagHandleTouch() << llendl;
- llinfos << " hasMoney " << objectp->flagTakesMoney() << llendl;
- llinfos << " getposition " << objectp->getPosition() << llendl;
- llinfos << " getpositionAgent " << objectp->getPositionAgent() << llendl;
- llinfos << " getpositionRegion " << objectp->getPositionRegion() << llendl;
- llinfos << " getpositionGlobal " << objectp->getPositionGlobal() << llendl;
- LLDrawable* drawablep = objectp->mDrawable;
- llinfos << " " << (drawablep&& drawablep->isVisible() ? "visible" : "invisible") << llendl;
- llinfos << " " << (drawablep&& drawablep->isState(LLDrawable::FORCE_INVISIBLE) ? "force_invisible" : "") << llendl;
- count++;
- }
- // Face iterator
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++ )
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- for (S32 te = 0; te < objectp->getNumTEs(); ++te )
- {
- if (node->isTESelected(te))
- {
- llinfos << "Object " << objectp << " te " << te << llendl;
- }
- }
- }
- llinfos << mHighlightedObjects->getNumNodes() << " objects currently highlighted." << llendl;
- llinfos << "Center global " << mSelectionCenterGlobal << llendl;
- }
- //-----------------------------------------------------------------------------
- // cleanup()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::cleanup()
- {
- mSilhouetteImagep = NULL;
- }
- //---------------------------------------------------------------------------
- // Manipulate properties of selected objects
- //---------------------------------------------------------------------------
- struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- }
- return true;
- }
- };
- //-----------------------------------------------------------------------------
- // selectionSetImage()
- //-----------------------------------------------------------------------------
- // *TODO: re-arch texture applying out of lltooldraganddrop
- void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
- {
- // First for (no copy) textures and multiple object selection
- LLViewerInventoryItem* item = gInventory.getItem(imageid);
- if(item
- && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
- && (mSelectedObjects->getNumNodes() > 1) )
- {
- llwarns << "Attempted to apply no-copy texture to multiple objects"
- << llendl;
- return;
- }
- struct f : public LLSelectedTEFunctor
- {
- LLViewerInventoryItem* mItem;
- LLUUID mImageID;
- f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
- bool apply(LLViewerObject* objectp, S32 te)
- {
- if (mItem)
- {
- if (te == -1) // all faces
- {
- LLToolDragAndDrop::dropTextureAllFaces(objectp,
- mItem,
- LLToolDragAndDrop::SOURCE_AGENT,
- LLUUID::null);
- }
- else // one face
- {
- LLToolDragAndDrop::dropTextureOneFace(objectp,
- te,
- mItem,
- LLToolDragAndDrop::SOURCE_AGENT,
- LLUUID::null);
- }
- }
- else // not an inventory item
- {
- // Texture picker defaults aren't inventory items
- // * Don't need to worry about permissions for them
- // * Can just apply the texture and be done with it.
- objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
- }
- return true;
- }
- } setfunc(item, imageid);
- getSelection()->applyToTEs(&setfunc);
- struct g : public LLSelectedObjectFunctor
- {
- LLViewerInventoryItem* mItem;
- g(LLViewerInventoryItem* item) : mItem(item) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (!mItem)
- {
- object->sendTEUpdate();
- // 1 particle effect per object
- LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
- effectp->setSourceObject(gAgentAvatarp);
- effectp->setTargetObject(object);
- effectp->setDuration(LL_HUD_DUR_SHORT);
- effectp->setColor(LLColor4U(gAgent.getEffectColor()));
- }
- return true;
- }
- } sendfunc(item);
- getSelection()->applyToObjects(&sendfunc);
- }
- //-----------------------------------------------------------------------------
- // selectionSetColor()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::selectionSetColor(const LLColor4 &color)
- {
- struct f : public LLSelectedTEFunctor
- {
- LLColor4 mColor;
- f(const LLColor4& c) : mColor(c) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- object->setTEColor(te, mColor);
- }
- return true;
- }
- } setfunc(color);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- //-----------------------------------------------------------------------------
- // selectionSetColorOnly()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::selectionSetColorOnly(const LLColor4 &color)
- {
- struct f : public LLSelectedTEFunctor
- {
- LLColor4 mColor;
- f(const LLColor4& c) : mColor(c) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLColor4 prev_color = object->getTE(te)->getColor();
- mColor.mV[VALPHA] = prev_color.mV[VALPHA];
- // update viewer side color in anticipation of update from simulator
- object->setTEColor(te, mColor);
- }
- return true;
- }
- } setfunc(color);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- //-----------------------------------------------------------------------------
- // selectionSetAlphaOnly()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::selectionSetAlphaOnly(const F32 alpha)
- {
- struct f : public LLSelectedTEFunctor
- {
- F32 mAlpha;
- f(const F32& a) : mAlpha(a) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLColor4 prev_color = object->getTE(te)->getColor();
- prev_color.mV[VALPHA] = mAlpha;
- // update viewer side color in anticipation of update from simulator
- object->setTEColor(te, prev_color);
- }
- return true;
- }
- } setfunc(alpha);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionRevertColors()
- {
- struct f : public LLSelectedTEFunctor
- {
- LLObjectSelectionHandle mSelectedObjects;
- f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLSelectNode* nodep = mSelectedObjects->findNode(object);
- if (nodep && te < (S32)nodep->mSavedColors.size())
- {
- LLColor4 color = nodep->mSavedColors[te];
- // update viewer side color in anticipation of update from simulator
- object->setTEColor(te, color);
- }
- }
- return true;
- }
- } setfunc(mSelectedObjects);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- BOOL LLSelectMgr::selectionRevertTextures()
- {
- struct f : public LLSelectedTEFunctor
- {
- LLObjectSelectionHandle mSelectedObjects;
- f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- LLSelectNode* nodep = mSelectedObjects->findNode(object);
- if (nodep && te < (S32)nodep->mSavedTextures.size())
- {
- LLUUID id = nodep->mSavedTextures[te];
- // update textures on viewer side
- if (id.isNull())
- {
- // this was probably a no-copy texture, leave image as-is
- return FALSE;
- }
- else
- {
- object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
- }
- }
- }
- return true;
- }
- } setfunc(mSelectedObjects);
- BOOL revert_successful = getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- return revert_successful;
- }
- void LLSelectMgr::selectionSetBumpmap(U8 bumpmap)
- {
- struct f : public LLSelectedTEFunctor
- {
- U8 mBump;
- f(const U8& b) : mBump(b) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEBumpmap(te, mBump);
- }
- return true;
- }
- } setfunc(bumpmap);
- getSelection()->applyToTEs(&setfunc);
-
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetTexGen(U8 texgen)
- {
- struct f : public LLSelectedTEFunctor
- {
- U8 mTexgen;
- f(const U8& t) : mTexgen(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTETexGen(te, mTexgen);
- }
- return true;
- }
- } setfunc(texgen);
- getSelection()->applyToTEs(&setfunc);
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetShiny(U8 shiny)
- {
- struct f : public LLSelectedTEFunctor
- {
- U8 mShiny;
- f(const U8& t) : mShiny(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEShiny(te, mShiny);
- }
- return true;
- }
- } setfunc(shiny);
- getSelection()->applyToTEs(&setfunc);
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetFullbright(U8 fullbright)
- {
- struct f : public LLSelectedTEFunctor
- {
- U8 mFullbright;
- f(const U8& t) : mFullbright(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEFullbright(te, mFullbright);
- }
- return true;
- }
- } setfunc(fullbright);
- getSelection()->applyToTEs(&setfunc);
- struct g : public LLSelectedObjectFunctor
- {
- U8 mFullbright;
- g(const U8& t) : mFullbright(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- if (mFullbright)
- {
- U8 material = object->getMaterial();
- U8 mcode = material & LL_MCODE_MASK;
- if (mcode == LL_MCODE_LIGHT)
- {
- mcode = LL_MCODE_GLASS;
- material = (material & ~LL_MCODE_MASK) | mcode;
- object->setMaterial(material);
- object->sendMaterialUpdate();
- }
- }
- }
- return true;
- }
- } sendfunc(fullbright);
- getSelection()->applyToObjects(&sendfunc);
- }
- // This function expects media_data to be a map containing relevant
- // media data name/value pairs (e.g. home_url, etc.)
- void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data)
- {
- struct f : public LLSelectedTEFunctor
- {
- U8 mMediaFlags;
- const LLSD &mMediaData;
- f(const U8& t, const LLSD& d) : mMediaFlags(t), mMediaData(d) {}
- bool apply(LLViewerObject* object, S32 te)
- {
- if (object->permModify())
- {
- // If we are adding media, then check the current state of the
- // media data on this face.
- // - If it does not have media, AND we are NOT setting the HOME URL, then do NOT add media to this
- // face.
- // - If it does not have media, and we ARE setting the HOME URL, add media to this face.
- // - If it does already have media, add/update media to/on this face
- // If we are removing media, just do it (ignore the passed-in LLSD).
- if (mMediaFlags & LLTextureEntry::MF_HAS_MEDIA)
- {
- llassert(mMediaData.isMap());
- const LLTextureEntry *texture_entry = object->getTE(te);
- if (!mMediaData.isMap() ||
- (NULL != texture_entry) && !texture_entry->hasMedia() && !mMediaData.has(LLMediaEntry::HOME_URL_KEY))
- {
- // skip adding/updating media
- }
- else {
- // Add/update media
- object->setTEMediaFlags(te, mMediaFlags);
- LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
- llassert(NULL != vo);
- if (NULL != vo)
- {
- vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
- }
- }
- }
- else
- {
- // delete media (or just set the flags)
- object->setTEMediaFlags(te, mMediaFlags);
- }
- }
- return true;
- }
- } setfunc(media_type, media_data);
- getSelection()->applyToTEs(&setfunc);
-
- struct f2 : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
- llassert(NULL != vo);
- // It's okay to skip this object if hasMedia() is false...
- // the sendTEUpdate() above would remove all media data if it were
- // there.
- if (NULL != vo && vo->hasMedia())
- {
- // Send updated media data FOR THE ENTIRE OBJECT
- vo->sendMediaDataUpdate();
- }
- }
- return true;
- }
- } func2;
- mSelectedObjects->applyToObjects( &func2 );
- }
- void LLSelectMgr::selectionSetGlow(F32 glow)
- {
- struct f1 : public LLSelectedTEFunctor
- {
- F32 mGlow;
- f1(F32 glow) : mGlow(glow) {};
- bool apply(LLViewerObject* object, S32 face)
- {
- if (object->permModify())
- {
- // update viewer side color in anticipation of update from simulator
- object->setTEGlow(face, mGlow);
- }
- return true;
- }
- } func1(glow);
- mSelectedObjects->applyToTEs( &func1 );
- struct f2 : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->sendTEUpdate();
- }
- return true;
- }
- } func2;
- mSelectedObjects->applyToObjects( &func2 );
- }
- //-----------------------------------------------------------------------------
- // findObjectPermissions()
- //-----------------------------------------------------------------------------
- LLPermissions* LLSelectMgr::findObjectPermissions(const LLViewerObject* object)
- {
- for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();
- iter != getSelection()->valid_end(); iter++ )
- {
- LLSelectNode* nodep = *iter;
- if (nodep->getObject() == object)
- {
- return nodep->mPermissions;
- }
- }
- return NULL;
- }
- //-----------------------------------------------------------------------------
- // selectionGetGlow()
- //-----------------------------------------------------------------------------
- BOOL LLSelectMgr::selectionGetGlow(F32 *glow)
- {
- BOOL identical;
- F32 lglow = 0.f;
- struct f1 : public LLSelectedTEGetFunctor<F32>
- {
- F32 get(LLViewerObject* object, S32 face)
- {
- return object->getTE(face)->getGlow();
- }
- } func;
- identical = mSelectedObjects->getSelectedTEValue( &func, lglow );
- *glow = lglow;
- return identical;
- }
- void LLSelectMgr::selectionSetPhysicsType(U8 type)
- {
- struct f : public LLSelectedObjectFunctor
- {
- U8 mType;
- f(const U8& t) : mType(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsShapeType(mType);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(type);
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetFriction(F32 friction)
- {
- struct f : public LLSelectedObjectFunctor
- {
- F32 mFriction;
- f(const F32& friction) : mFriction(friction) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsFriction(mFriction);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(friction);
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetGravity(F32 gravity )
- {
- struct f : public LLSelectedObjectFunctor
- {
- F32 mGravity;
- f(const F32& gravity) : mGravity(gravity) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsGravity(mGravity);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(gravity);
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetDensity(F32 density )
- {
- struct f : public LLSelectedObjectFunctor
- {
- F32 mDensity;
- f(const F32& density ) : mDensity(density) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsDensity(mDensity);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(density);
- getSelection()->applyToObjects(&sendfunc);
- }
- void LLSelectMgr::selectionSetRestitution(F32 restitution)
- {
- struct f : public LLSelectedObjectFunctor
- {
- F32 mRestitution;
- f(const F32& restitution ) : mRestitution(restitution) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- object->setPhysicsRestitution(mRestitution);
- object->updateFlags(TRUE);
- }
- return true;
- }
- } sendfunc(restitution);
- getSelection()->applyToObjects(&sendfunc);
- }
- //-----------------------------------------------------------------------------
- // selectionSetMaterial()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::selectionSetMaterial(U8 material)
- {
- struct f : public LLSelectedObjectFunctor
- {
- U8 mMaterial;
- f(const U8& t) : mMaterial(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->permModify())
- {
- U8 cur_material = object->getMaterial();
- U8 material = mMaterial | (cur_material & ~LL_MCODE_MASK);
- object->setMaterial(material);
- object->sendMaterialUpdate();
- }
- return true;
- }
- } sendfunc(material);
- getSelection()->applyToObjects(&sendfunc);
- }
- // TRUE if all selected objects have this PCode
- BOOL LLSelectMgr::selectionAllPCode(LLPCode code)
- {
- struct f : public LLSelectedObjectFunctor
- {
- LLPCode mCode;
- f(const LLPCode& t) : mCode(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if (object->getPCode() != mCode)
- {
- return FALSE;
- }
- return true;
- }
- } func(code);
- BOOL res = getSelection()->applyToObjects(&func);
- return res;
- }
- bool LLSelectMgr::selectionGetIncludeInSearch(bool* include_in_search_out)
- {
- LLViewerObject *object = mSelectedObjects->getFirstRootObject();
- if (!object) return FALSE;
- bool include_in_search = object->getIncludeInSearch();
- bool identical = true;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- LLViewerObject* object = (*iter)->getObject();
- if ( include_in_search != object->getIncludeInSearch())
- {
- identical = false;
- break;
- }
- }
- *include_in_search_out = include_in_search;
- return identical;
- }
- void LLSelectMgr::selectionSetIncludeInSearch(bool include_in_search)
- {
- LLViewerObject* object = NULL;
- for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
- iter != getSelection()->root_end(); iter++)
- {
- object = (*iter)->getObject();
- object->setIncludeInSearch(include_in_search);
- }
- sendListToRegions(
- "ObjectIncludeInSearch",
- packAgentAndSessionID,
- packObjectIncludeInSearch,
- &include_in_search,
- SEND_ONLY_ROOTS);
- }
- BOOL LLSelectMgr::selectionGetClickAction(U8 *out_action)
- {
- LLViewerObject *object = mSelectedObjects->getFirstObject();
- if (!object)
- {
- return FALSE;
- }
-
- U8 action = object->getClickAction();
- *out_action = action;
- struct f : public LLSelectedObjectFunctor
- {
- U8 mAction;
- f(const U8& t) : mAction(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- if ( mAction != object->getClickAction())
- {
- return false;
- }
- return true;
- }
- } func(action);
- BOOL res = getSelection()->applyToObjects(&func);
- return res;
- }
- void LLSelectMgr::selectionSetClickAction(U8 action)
- {
- struct f : public LLSelectedObjectFunctor
- {
- U8 mAction;
- f(const U8& t) : mAction(t) {}
- virtual bool apply(LLViewerObject* object)
- {
- object->setClickAction(mAction);
- return true;
- }
- } func(action);
- getSelection()->applyToObjects(&func);
- sendListToRegions("ObjectClickAction",
- packAgentAndSessionID,
- packObjectClickAction,
- &action,
- SEND_INDIVIDUALS);
- }
- //-----------------------------------------------------------------------------
- // godlike requests
- //-----------------------------------------------------------------------------
- typedef std::pair<const std::string, const std::string> godlike_request_t;
- void LLSelectMgr::sendGodlikeRequest(const std::string& request, const std::string& param)
- {
- // If the agent is neither godlike nor an estate owner, the server
- // will reject the request.
- std::string message_type;
- if (gAgent.isGodlike())
- {
- message_type = "GodlikeMessage";
- }
- else
- {
- message_type = "EstateOwnerMessage";
- }
- godlike_request_t data(request, param);
- if(!mSelectedObjects->getRootObjectCount())
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessage(message_type.c_str());
- LLSelectMgr::packGodlikeHead(&data);
- gAgent.sendReliableMessage();
- }
- else
- {
- sendListToRegions(message_type, packGodlikeHead, packObjectIDAsParam, &data, SEND_ONLY_ROOTS);
- }
- }
- void LLSelectMgr::packGodlikeHead(void* user_data)
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUID("TransactionID", LLUUID::null);
- godlike_request_t* data = (godlike_request_t*)user_data;
- msg->nextBlock("MethodData");
- msg->addString("Method", data->first);
- msg->addUUID("Invoice", LLUUID::null);
- // The parameters used to be restricted to either string or
- // integer. This mimics that behavior under the new 'string-only'
- // parameter list by not packing a string if there wasn't one
- // specified. The object ids will be packed in the
- // packObjectIDAsParam() method.
- if(data->second.size() > 0)
- {
- msg->nextBlock("ParamList");
- msg->addString("Parameter", data->second);
- }
- }
- // static
- void LLSelectMgr::packObjectIDAsParam(LLSelectNode* node, void *)
- {
- std::string buf = llformat("%u", node->getObject()->getLocalID());
- gMessageSystem->nextBlock("ParamList");
- gMessageSystem->addString("Parameter", buf);
- }
- //-----------------------------------------------------------------------------
- // Rotation options
- //-----------------------------------------------------------------------------
- void LLSelectMgr::selectionResetRotation()
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- LLQuaternion identity(0.f, 0.f, 0.f, 1.f);
- object->setRotation(identity);
- if (object->mDrawable.notNull())
- {
- gPipeline.markMoved(object->mDrawable, TRUE);
- }
- object->sendRotationUpdate();
- return true;
- }
- } func;
- getSelection()->applyToRootObjects(&func);
- }
- void LLSelectMgr::selectionRotateAroundZ(F32 degrees)
- {
- LLQuaternion rot( degrees * DEG_TO_RAD, LLVector3(0,0,1) );
- struct f : public LLSelectedObjectFunctor
- {
- LLQuaternion mRot;
- f(const LLQuaternion& rot) : mRot(rot) {}
- virtual bool apply(LLViewerObject* object)
- {
- object->setRotation( object->getRotationEdit() * mRot );
- if (object->mDrawable.notNull())
- {
- gPipeline.markMoved(object->mDrawable, TRUE);
- }
- object->sendRotationUpdate();
- return true;
- }
- } func(rot);
- getSelection()->applyToRootObjects(&func);
- }
- //-----------------------------------------------------------------------------
- // selectionTexScaleAutofit()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::selectionTexScaleAutofit(F32 repeats_per_meter)
- {
- struct f : public LLSelectedTEFunctor
- {
- F32 mRepeatsPerMeter;
- f(const F32& t) : mRepeatsPerMeter(t) {}
- bool apply(LLViewerObject* object, S32 te)
- {
-
- if (object->permModify())
- {
- // Compute S,T to axis mapping
- U32 s_axis, t_axis;
- if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis))
- {
- return TRUE;
- }
- F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter;
- F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter;
- object->setTEScale(te, new_s, new_t);
- }
- return true;
- }
- } setfunc(repeats_per_meter);
- getSelection()->applyToTEs(&setfunc);
- LLSelectMgrSendFunctor sendfunc;
- getSelection()->applyToObjects(&sendfunc);
- }
- // Called at the end of a scale operation, this adjusts the textures to attempt to
- // maintain a constant repeats per meter.
- // BUG: Only works for flex boxes.
- //-----------------------------------------------------------------------------
- // adjustTexturesByScale()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)
- {
- for (LLObjectSelection::iterator iter = getSelection()->begin();
- iter != getSelection()->end(); iter++)
- {
- LLSelectNode* selectNode = *iter;
- LLViewerObject* object = selectNode->getObject();
- if (!object)
- {
- continue;
- }
-
- if (!object->permModify())
- {
- continue;
- }
- if (object->getNumTEs() == 0)
- {
- continue;
- }
- BOOL send = FALSE;
-
- for (U8 te_num = 0; te_num < object->getNumTEs(); te_num++)
- {
- const LLTextureEntry* tep = object->getTE(te_num);
- BOOL planar = tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR;
- if (planar == stretch)
- {
- // Figure out how S,T changed with scale operation
- U32 s_axis, t_axis;
- if (!LLPrimitive::getTESTAxes(te_num, &s_axis, &t_axis))
- {
- continue;
- }
-
- LLVector3 scale_ratio = selectNode->mTextureScaleRatios[te_num];
- LLVector3 object_sca