llselectmgr.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:177k
- gMessageSystem->addUUIDFast(_PREHASH_OwnerID, data->owner_id);
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id);
- }
- //------------------------------------------------------------------------
- // Group
- //------------------------------------------------------------------------
- void LLSelectMgr::sendGroup(const LLUUID& group_id)
- {
- LLUUID local_group_id(group_id);
- sendListToRegions("ObjectGroup", packAgentAndSessionAndGroupID, packObjectLocalID, &local_group_id, SEND_ONLY_ROOTS);
- }
- //------------------------------------------------------------------------
- // Buy
- //------------------------------------------------------------------------
- struct LLBuyData
- {
- std::vector<LLViewerObject*> mObjectsSent;
- LLUUID mCategoryID;
- LLSaleInfo mSaleInfo;
- };
- // *NOTE: does not 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 Need to get sale
- // info -as displayed in the UI- for every item.
- void LLSelectMgr::sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info)
- {
- LLBuyData buy;
- buy.mCategoryID = category_id;
- buy.mSaleInfo = sale_info;
- sendListToRegions("ObjectBuy", packAgentGroupAndCatID, packBuyObjectIDs, &buy, SEND_ONLY_ROOTS);
- }
- // static
- void LLSelectMgr::packBuyObjectIDs(LLSelectNode* node, void* data)
- {
- LLBuyData* buy = (LLBuyData*)data;
- LLViewerObject* object = node->getObject();
- if (std::find(buy->mObjectsSent.begin(), buy->mObjectsSent.end(), object) == buy->mObjectsSent.end())
- {
- buy->mObjectsSent.push_back(object);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID() );
- gMessageSystem->addU8Fast(_PREHASH_SaleType, buy->mSaleInfo.getSaleType());
- gMessageSystem->addS32Fast(_PREHASH_SalePrice, buy->mSaleInfo.getSalePrice());
- }
- }
- //------------------------------------------------------------------------
- // Permissions
- //------------------------------------------------------------------------
- struct LLPermData
- {
- U8 mField;
- BOOL mSet;
- U32 mMask;
- BOOL mOverride;
- };
- // TODO: Make this able to fail elegantly.
- void LLSelectMgr::selectionSetObjectPermissions(U8 field,
- BOOL set,
- U32 mask,
- BOOL override)
- {
- LLPermData data;
- data.mField = field;
- data.mSet = set;
- data.mMask = mask;
- data.mOverride = override;
- sendListToRegions("ObjectPermissions", packPermissionsHead, packPermissions, &data, SEND_ONLY_ROOTS);
- }
- void LLSelectMgr::packPermissionsHead(void* user_data)
- {
- LLPermData* data = (LLPermData*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_HeaderData);
- gMessageSystem->addBOOLFast(_PREHASH_Override, data->mOverride);
- }
- // Now that you've added a bunch of objects, send a select message
- // on the entire list for efficiency.
- /*
- void LLSelectMgr::sendSelect()
- {
- llerrs << "Not implemented" << llendl;
- }
- */
- void LLSelectMgr::deselectAll()
- {
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
-
- // Zap the angular velocity, as the sim will set it to zero
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++ )
- {
- LLViewerObject *objectp = (*iter)->getObject();
- objectp->setAngularVelocity( 0,0,0 );
- objectp->setVelocity( 0,0,0 );
- }
- sendListToRegions(
- "ObjectDeselect",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_INDIVIDUALS);
- removeAll();
-
- mLastSentSelectionCenterGlobal.clearVec();
- updatePointAt();
- }
- void LLSelectMgr::deselectAllForStandingUp()
- {
- /*
- This function is similar deselectAll() except for the first if statement
- which was removed. This is needed as a workaround for DEV-2854
- */
- // Zap the angular velocity, as the sim will set it to zero
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++ )
- {
- LLViewerObject *objectp = (*iter)->getObject();
- objectp->setAngularVelocity( 0,0,0 );
- objectp->setVelocity( 0,0,0 );
- }
- sendListToRegions(
- "ObjectDeselect",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_INDIVIDUALS);
- removeAll();
-
- mLastSentSelectionCenterGlobal.clearVec();
- updatePointAt();
- }
- void LLSelectMgr::deselectUnused()
- {
- // no more outstanding references to this selection
- if (mSelectedObjects->getNumRefs() == 1)
- {
- deselectAll();
- }
- }
- void LLSelectMgr::convertTransient()
- {
- LLObjectSelection::iterator node_it;
- for (node_it = mSelectedObjects->begin(); node_it != mSelectedObjects->end(); ++node_it)
- {
- LLSelectNode *nodep = *node_it;
- nodep->setTransient(FALSE);
- }
- }
- void LLSelectMgr::deselectAllIfTooFar()
- {
- if (mSelectedObjects->isEmpty() || mSelectedObjects->mSelectType == SELECT_TYPE_HUD)
- {
- return;
- }
- // HACK: Don't deselect when we're navigating to rate an object's
- // owner or creator. JC
- if (gMenuObject->getVisible())
- {
- return;
- }
- LLVector3d selectionCenter = getSelectionCenterGlobal();
- if (gSavedSettings.getBOOL("LimitSelectDistance")
- && (!mSelectedObjects->getPrimaryObject() || !mSelectedObjects->getPrimaryObject()->isAvatar())
- && (mSelectedObjects->getPrimaryObject() != LLViewerMediaFocus::getInstance()->getFocusedObject())
- && !mSelectedObjects->isAttachment()
- && !selectionCenter.isExactlyZero())
- {
- F32 deselect_dist = gSavedSettings.getF32("MaxSelectDistance");
- F32 deselect_dist_sq = deselect_dist * deselect_dist;
- LLVector3d select_delta = gAgent.getPositionGlobal() - selectionCenter;
- F32 select_dist_sq = (F32) select_delta.magVecSquared();
- if (select_dist_sq > deselect_dist_sq)
- {
- if (mDebugSelectMgr)
- {
- llinfos << "Selection manager: auto-deselecting, select_dist = " << fsqrtf(select_dist_sq) << llendl;
- llinfos << "agent pos global = " << gAgent.getPositionGlobal() << llendl;
- llinfos << "selection pos global = " << selectionCenter << llendl;
- }
- deselectAll();
- }
- }
- }
- void LLSelectMgr::selectionSetObjectName(const std::string& name)
- {
- // we only work correctly if 1 object is selected.
- if(mSelectedObjects->getRootObjectCount() == 1)
- {
- sendListToRegions("ObjectName",
- packAgentAndSessionID,
- packObjectName,
- (void*)(new std::string(name)),
- SEND_ONLY_ROOTS);
- }
- else if(mSelectedObjects->getObjectCount() == 1)
- {
- sendListToRegions("ObjectName",
- packAgentAndSessionID,
- packObjectName,
- (void*)(new std::string(name)),
- SEND_INDIVIDUALS);
- }
- }
- void LLSelectMgr::selectionSetObjectDescription(const std::string& desc)
- {
- // we only work correctly if 1 object is selected.
- if(mSelectedObjects->getRootObjectCount() == 1)
- {
- sendListToRegions("ObjectDescription",
- packAgentAndSessionID,
- packObjectDescription,
- (void*)(new std::string(desc)),
- SEND_ONLY_ROOTS);
- }
- else if(mSelectedObjects->getObjectCount() == 1)
- {
- sendListToRegions("ObjectDescription",
- packAgentAndSessionID,
- packObjectDescription,
- (void*)(new std::string(desc)),
- SEND_INDIVIDUALS);
- }
- }
- void LLSelectMgr::selectionSetObjectCategory(const LLCategory& category)
- {
- // for now, we only want to be able to set one root category at
- // a time.
- if(mSelectedObjects->getRootObjectCount() != 1) return;
- sendListToRegions("ObjectCategory",
- packAgentAndSessionID,
- packObjectCategory,
- (void*)(&category),
- SEND_ONLY_ROOTS);
- }
- void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info)
- {
- sendListToRegions("ObjectSaleInfo",
- packAgentAndSessionID,
- packObjectSaleInfo,
- (void*)(&sale_info),
- SEND_ONLY_ROOTS);
- }
- //----------------------------------------------------------------------
- // Attachments
- //----------------------------------------------------------------------
- void LLSelectMgr::sendAttach(U8 attachment_point)
- {
- LLViewerObject* attach_object = mSelectedObjects->getFirstRootObject();
- if (!attach_object || !gAgent.getAvatarObject() || mSelectedObjects->mSelectType != SELECT_TYPE_WORLD)
- {
- return;
- }
- #if ENABLE_MULTIATTACHMENTS
- attachment_point |= ATTACHMENT_ADD;
- #endif
- BOOL build_mode = LLToolMgr::getInstance()->inEdit();
- // Special case: Attach to default location for this object.
- if (0 == attachment_point ||
- get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, (S32)attachment_point, (LLViewerJointAttachment*)NULL))
- {
- sendListToRegions(
- "ObjectAttach",
- packAgentIDAndSessionAndAttachment,
- packObjectIDAndRotation,
- &attachment_point,
- SEND_ONLY_ROOTS );
- if (!build_mode)
- {
- deselectAll();
- }
- }
- }
- void LLSelectMgr::sendDetach()
- {
- if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
- {
- return;
- }
- sendListToRegions(
- "ObjectDetach",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_ONLY_ROOTS );
- }
- void LLSelectMgr::sendDropAttachment()
- {
- if (!mSelectedObjects->getNumNodes() || mSelectedObjects->mSelectType == SELECT_TYPE_WORLD)
- {
- return;
- }
- sendListToRegions(
- "ObjectDrop",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_ONLY_ROOTS);
- }
- //----------------------------------------------------------------------
- // Links
- //----------------------------------------------------------------------
- void LLSelectMgr::sendLink()
- {
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
- sendListToRegions(
- "ObjectLink",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_ONLY_ROOTS);
- }
- void LLSelectMgr::sendDelink()
- {
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
- // Delink needs to send individuals so you can unlink a single object from
- // a linked set.
- sendListToRegions(
- "ObjectDelink",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_INDIVIDUALS);
- }
- //----------------------------------------------------------------------
- // Hinges
- //----------------------------------------------------------------------
- /*
- void LLSelectMgr::sendHinge(U8 type)
- {
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
- sendListToRegions(
- "ObjectHinge",
- packHingeHead,
- packObjectLocalID,
- &type,
- SEND_ONLY_ROOTS);
- }
- void LLSelectMgr::sendDehinge()
- {
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
- sendListToRegions(
- "ObjectDehinge",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_ONLY_ROOTS);
- }*/
- void LLSelectMgr::sendSelect()
- {
- if (!mSelectedObjects->getNumNodes())
- {
- return;
- }
- sendListToRegions(
- "ObjectSelect",
- packAgentAndSessionID,
- packObjectLocalID,
- NULL,
- SEND_INDIVIDUALS);
- }
- // static
- void LLSelectMgr::packHingeHead(void *user_data)
- {
- U8 *type = (U8 *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- gMessageSystem->nextBlockFast(_PREHASH_JointType);
- gMessageSystem->addU8Fast(_PREHASH_Type, *type );
- }
- void LLSelectMgr::selectionDump()
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- object->dump();
- return true;
- }
- } func;
- getSelection()->applyToObjects(&func);
- }
- void LLSelectMgr::saveSelectedObjectColors()
- {
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->saveColors();
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
- }
- void LLSelectMgr::saveSelectedObjectTextures()
- {
- // invalidate current selection so we update saved textures
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->mValid = FALSE;
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
- // request object properties message to get updated permissions data
- sendSelect();
- }
- // This routine should be called whenever a drag is initiated.
- // also need to know to which simulator to send update message
- void LLSelectMgr::saveSelectedObjectTransform(EActionType action_type)
- {
- if (mSelectedObjects->isEmpty())
- {
- // nothing selected, so nothing to save
- return;
- }
- struct f : public LLSelectedNodeFunctor
- {
- EActionType mActionType;
- f(EActionType a) : mActionType(a) {}
- virtual bool apply(LLSelectNode* selectNode)
- {
- LLViewerObject* object = selectNode->getObject();
- if (!object)
- {
- return true; // skip
- }
- selectNode->mSavedPositionLocal = object->getPosition();
- if (object->isAttachment())
- {
- if (object->isRootEdit())
- {
- LLXform* parent_xform = object->mDrawable->getXform()->getParent();
- if (parent_xform)
- {
- selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition());
- }
- else
- {
- selectNode->mSavedPositionGlobal = object->getPositionGlobal();
- }
- }
- else
- {
- LLViewerObject* attachment_root = (LLViewerObject*)object->getParent();
- LLXform* parent_xform = attachment_root ? attachment_root->mDrawable->getXform()->getParent() : NULL;
- if (parent_xform)
- {
- LLVector3 root_pos = (attachment_root->getPosition() * parent_xform->getWorldRotation()) + parent_xform->getWorldPosition();
- LLQuaternion root_rot = (attachment_root->getRotation() * parent_xform->getWorldRotation());
- selectNode->mSavedPositionGlobal = gAgent.getPosGlobalFromAgent((object->getPosition() * root_rot) + root_pos);
- }
- else
- {
- selectNode->mSavedPositionGlobal = object->getPositionGlobal();
- }
- }
- selectNode->mSavedRotation = object->getRenderRotation();
- }
- else
- {
- selectNode->mSavedPositionGlobal = object->getPositionGlobal();
- selectNode->mSavedRotation = object->getRotationRegion();
- }
-
- selectNode->mSavedScale = object->getScale();
- selectNode->saveTextureScaleRatios();
- return true;
- }
- } func(action_type);
- getSelection()->applyToNodes(&func);
-
- mSavedSelectionBBox = getBBoxOfSelection();
- }
- struct LLSelectMgrApplyFlags : public LLSelectedObjectFunctor
- {
- LLSelectMgrApplyFlags(U32 flags, BOOL state) : mFlags(flags), mState(state) {}
- U32 mFlags;
- BOOL mState;
- virtual bool apply(LLViewerObject* object)
- {
- if ( object->permModify() && // preemptive permissions check
- object->isRoot() && // don't send for child objects
- !object->isJointChild())
- {
- object->setFlags( mFlags, mState);
- }
- return true;
- }
- };
- void LLSelectMgr::selectionUpdatePhysics(BOOL physics)
- {
- LLSelectMgrApplyFlags func( FLAGS_USE_PHYSICS, physics);
- getSelection()->applyToObjects(&func);
- }
- void LLSelectMgr::selectionUpdateTemporary(BOOL is_temporary)
- {
- LLSelectMgrApplyFlags func( FLAGS_TEMPORARY_ON_REZ, is_temporary);
- getSelection()->applyToObjects(&func);
- }
- void LLSelectMgr::selectionUpdatePhantom(BOOL is_phantom)
- {
- LLSelectMgrApplyFlags func( FLAGS_PHANTOM, is_phantom);
- getSelection()->applyToObjects(&func);
- }
- void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows)
- {
- LLSelectMgrApplyFlags func( FLAGS_CAST_SHADOWS, cast_shadows);
- getSelection()->applyToObjects(&func);
- }
- //----------------------------------------------------------------------
- // Helpful packing functions for sendObjectMessage()
- //----------------------------------------------------------------------
- // static
- void LLSelectMgr::packAgentIDAndSessionAndAttachment( void *user_data)
- {
- U8 *attachment_point = (U8*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addU8Fast(_PREHASH_AttachmentPoint, *attachment_point);
- }
- // static
- void LLSelectMgr::packAgentID( void *user_data)
- {
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- }
- // static
- void LLSelectMgr::packAgentAndSessionID(void* user_data)
- {
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- }
- // static
- void LLSelectMgr::packAgentAndGroupID(void* user_data)
- {
- LLOwnerData *data = (LLOwnerData *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, data->owner_id );
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, data->group_id );
- }
- // static
- void LLSelectMgr::packAgentAndSessionAndGroupID(void* user_data)
- {
- LLUUID* group_idp = (LLUUID*) user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, *group_idp);
- }
- // static
- void LLSelectMgr::packDuplicateHeader(void* data)
- {
- LLUUID group_id(gAgent.getGroupID());
- packAgentAndSessionAndGroupID(&group_id);
- LLDuplicateData* dup_data = (LLDuplicateData*) data;
- gMessageSystem->nextBlockFast(_PREHASH_SharedData);
- gMessageSystem->addVector3Fast(_PREHASH_Offset, dup_data->offset);
- gMessageSystem->addU32Fast(_PREHASH_DuplicateFlags, dup_data->flags);
- }
- // static
- void LLSelectMgr::packDeleteHeader(void* userdata)
- {
- BOOL force = (BOOL)(intptr_t)userdata;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addBOOLFast(_PREHASH_Force, force);
- }
- // static
- void LLSelectMgr::packAgentGroupAndCatID(void* user_data)
- {
- LLBuyData* buy = (LLBuyData*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
- gMessageSystem->addUUIDFast(_PREHASH_CategoryID, buy->mCategoryID);
- }
- //static
- void LLSelectMgr::packDeRezHeader(void* user_data)
- {
- LLDeRezInfo* info = (LLDeRezInfo*)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_AgentData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- gMessageSystem->nextBlockFast(_PREHASH_AgentBlock);
- gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
- gMessageSystem->addU8Fast(_PREHASH_Destination, (U8)info->mDestination);
- gMessageSystem->addUUIDFast(_PREHASH_DestinationID, info->mDestinationID);
- LLUUID tid;
- tid.generate();
- gMessageSystem->addUUIDFast(_PREHASH_TransactionID, tid);
- const U8 PACKET = 1;
- gMessageSystem->addU8Fast(_PREHASH_PacketCount, PACKET);
- gMessageSystem->addU8Fast(_PREHASH_PacketNumber, PACKET);
- }
- // static
- void LLSelectMgr::packObjectID(LLSelectNode* node, void *user_data)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addUUIDFast(_PREHASH_ObjectID, node->getObject()->mID );
- }
- void LLSelectMgr::packObjectIDAndRotation(LLSelectNode* node, void *user_data)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
- gMessageSystem->addQuatFast(_PREHASH_Rotation, node->getObject()->getRotation());
- }
- void LLSelectMgr::packObjectClickAction(LLSelectNode* node, void *user_data)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
- gMessageSystem->addU8("ClickAction", node->getObject()->getClickAction());
- }
- void LLSelectMgr::packObjectIncludeInSearch(LLSelectNode* node, void *user_data)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID() );
- gMessageSystem->addBOOL("IncludeInSearch", node->getObject()->getIncludeInSearch());
- }
- // static
- void LLSelectMgr::packObjectLocalID(LLSelectNode* node, void *)
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
- }
- // static
- void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data)
- {
- const std::string* name = (const std::string*)user_data;
- if(!name->empty())
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- gMessageSystem->addStringFast(_PREHASH_Name, *name);
- }
- delete name;
- }
- // static
- void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data)
- {
- const std::string* desc = (const std::string*)user_data;
- if(!desc->empty())
- {
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- gMessageSystem->addStringFast(_PREHASH_Description, *desc);
- }
- }
- // static
- void LLSelectMgr::packObjectCategory(LLSelectNode* node, void* user_data)
- {
- LLCategory* category = (LLCategory*)user_data;
- if(!category) return;
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- category->packMessage(gMessageSystem);
- }
- // static
- void LLSelectMgr::packObjectSaleInfo(LLSelectNode* node, void* user_data)
- {
- LLSaleInfo* sale_info = (LLSaleInfo*)user_data;
- if(!sale_info) return;
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
- sale_info->packMessage(gMessageSystem);
- }
- // static
- void LLSelectMgr::packPhysics(LLSelectNode* node, void *user_data)
- {
- }
- // static
- void LLSelectMgr::packShape(LLSelectNode* node, void *user_data)
- {
- }
- // static
- void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data)
- {
- LLPermData *data = (LLPermData *)user_data;
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, node->getObject()->getLocalID());
- gMessageSystem->addU8Fast(_PREHASH_Field, data->mField);
- gMessageSystem->addBOOLFast(_PREHASH_Set, data->mSet);
- gMessageSystem->addU32Fast(_PREHASH_Mask, data->mMask);
- }
- // Utility function to send some information to every region containing
- // an object on the selection list. We want to do this to reduce the total
- // number of packets sent by the viewer.
- void LLSelectMgr::sendListToRegions(const std::string& message_name,
- void (*pack_header)(void *user_data),
- void (*pack_body)(LLSelectNode* node, void *user_data),
- void *user_data,
- ESendType send_type)
- {
- LLSelectNode* node;
- LLViewerRegion* last_region;
- LLViewerRegion* current_region;
- S32 objects_sent = 0;
- S32 packets_sent = 0;
- S32 objects_in_this_packet = 0;
- //clear update override data (allow next update through)
- struct f : public LLSelectedNodeFunctor
- {
- virtual bool apply(LLSelectNode* node)
- {
- node->mLastPositionLocal.setVec(0,0,0);
- node->mLastRotation = LLQuaternion();
- node->mLastScale.setVec(0,0,0);
- return true;
- }
- } func;
- getSelection()->applyToNodes(&func);
- std::queue<LLSelectNode*> nodes_to_send;
- struct push_all : public LLSelectedNodeFunctor
- {
- std::queue<LLSelectNode*>& nodes_to_send;
- push_all(std::queue<LLSelectNode*>& n) : nodes_to_send(n) {}
- virtual bool apply(LLSelectNode* node)
- {
- if (node->getObject())
- {
- nodes_to_send.push(node);
- }
- return true;
- }
- };
- struct push_some : public LLSelectedNodeFunctor
- {
- std::queue<LLSelectNode*>& nodes_to_send;
- bool mRoots;
- push_some(std::queue<LLSelectNode*>& n, bool roots) : nodes_to_send(n), mRoots(roots) {}
- virtual bool apply(LLSelectNode* node)
- {
- if (node->getObject())
- {
- BOOL is_root = node->getObject()->isRootEdit();
- if ((mRoots && is_root) || (!mRoots && !is_root))
- {
- nodes_to_send.push(node);
- }
- }
- return true;
- }
- };
- struct push_all pushall(nodes_to_send);
- struct push_some pushroots(nodes_to_send, TRUE);
- struct push_some pushnonroots(nodes_to_send, FALSE);
-
- switch(send_type)
- {
- case SEND_ONLY_ROOTS:
- if(message_name == "ObjectBuy")
- getSelection()->applyToRootNodes(&pushroots);
- else
- getSelection()->applyToRootNodes(&pushall);
-
- break;
- case SEND_INDIVIDUALS:
- getSelection()->applyToNodes(&pushall);
- break;
- case SEND_ROOTS_FIRST:
- // first roots...
- getSelection()->applyToNodes(&pushroots);
- // then children...
- getSelection()->applyToNodes(&pushnonroots);
- break;
- case SEND_CHILDREN_FIRST:
- // first children...
- getSelection()->applyToNodes(&pushnonroots);
- // then roots...
- getSelection()->applyToNodes(&pushroots);
- break;
- default:
- llerrs << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl;
- }
- // bail if nothing selected
- if (nodes_to_send.empty())
- {
- return;
- }
-
- node = nodes_to_send.front();
- nodes_to_send.pop();
- // cache last region information
- current_region = node->getObject()->getRegion();
- // Start duplicate message
- // CRO: this isn't
- gMessageSystem->newMessage(message_name.c_str());
- (*pack_header)(user_data);
- // For each object
- while (node != NULL)
- {
- // remember the last region, look up the current one
- last_region = current_region;
- current_region = node->getObject()->getRegion();
- // if to same simulator and message not too big
- if ((current_region == last_region)
- && (! gMessageSystem->isSendFull(NULL))
- && (objects_in_this_packet < MAX_OBJECTS_PER_PACKET))
- {
- // add another instance of the body of the data
- (*pack_body)(node, user_data);
- ++objects_sent;
- ++objects_in_this_packet;
- // and on to the next object
- if(nodes_to_send.empty())
- {
- node = NULL;
- }
- else
- {
- node = nodes_to_send.front();
- nodes_to_send.pop();
- }
- }
- else
- {
- // otherwise send current message and start new one
- gMessageSystem->sendReliable( last_region->getHost());
- packets_sent++;
- objects_in_this_packet = 0;
- gMessageSystem->newMessage(message_name.c_str());
- (*pack_header)(user_data);
- // don't move to the next object, we still need to add the
- // body data.
- }
- }
- // flush messages
- if (gMessageSystem->getCurrentSendTotal() > 0)
- {
- gMessageSystem->sendReliable( current_region->getHost());
- packets_sent++;
- }
- else
- {
- gMessageSystem->clearMessage();
- }
- // llinfos << "sendListToRegions " << message_name << " obj " << objects_sent << " pkt " << packets_sent << llendl;
- }
- //
- // Network communications
- //
- void LLSelectMgr::requestObjectPropertiesFamily(LLViewerObject* object)
- {
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addU32Fast(_PREHASH_RequestFlags, 0x0 );
- msg->addUUIDFast(_PREHASH_ObjectID, object->mID );
- LLViewerRegion* regionp = object->getRegion();
- msg->sendReliable( regionp->getHost() );
- }
- // static
- void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data)
- {
- S32 i;
- S32 count = msg->getNumberOfBlocksFast(_PREHASH_ObjectData);
- for (i = 0; i < count; i++)
- {
- LLUUID id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id, i);
- LLUUID creator_id;
- LLUUID owner_id;
- LLUUID group_id;
- LLUUID last_owner_id;
- U64 creation_date;
- LLUUID extra_id;
- U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
- LLSaleInfo sale_info;
- LLCategory category;
- LLAggregatePermissions ag_perms;
- LLAggregatePermissions ag_texture_perms;
- LLAggregatePermissions ag_texture_perms_owner;
-
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_CreatorID, creator_id, i);
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id, i);
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id, i);
- msg->getU64Fast(_PREHASH_ObjectData, _PREHASH_CreationDate, creation_date, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_GroupMask, group_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask, i);
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask, i);
- sale_info.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
- ag_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePerms, i);
- ag_texture_perms.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTextures, i);
- ag_texture_perms_owner.unpackMessage(msg, _PREHASH_ObjectData, _PREHASH_AggregatePermTexturesOwner, i);
- category.unpackMultiMessage(msg, _PREHASH_ObjectData, i);
- S16 inv_serial = 0;
- msg->getS16Fast(_PREHASH_ObjectData, _PREHASH_InventorySerial, inv_serial, i);
- LLUUID item_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ItemID, item_id, i);
- LLUUID folder_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FolderID, folder_id, i);
- LLUUID from_task_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FromTaskID, from_task_id, i);
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id, i);
- std::string name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name, i);
- std::string desc;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc, i);
- std::string touch_name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_TouchName, touch_name, i);
- std::string sit_name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_SitName, sit_name, i);
- //unpack TE IDs
- std::vector<LLUUID> texture_ids;
- S32 size = msg->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_TextureID);
- if (size > 0)
- {
- S8 packed_buffer[SELECT_MAX_TES * UUID_BYTES];
- msg->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureID, packed_buffer, 0, i, SELECT_MAX_TES * UUID_BYTES);
- for (S32 buf_offset = 0; buf_offset < size; buf_offset += UUID_BYTES)
- {
- LLUUID tid;
- memcpy(tid.mData, packed_buffer + buf_offset, UUID_BYTES); /* Flawfinder: ignore */
- texture_ids.push_back(tid);
- }
- }
- // Iterate through nodes at end, since it can be on both the regular AND hover list
- struct f : public LLSelectedNodeFunctor
- {
- LLUUID mID;
- f(const LLUUID& id) : mID(id) {}
- virtual bool apply(LLSelectNode* node)
- {
- return (node->getObject() && node->getObject()->mID == mID);
- }
- } func(id);
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
- if (node)
- {
- if (node->mInventorySerial != inv_serial)
- {
- node->getObject()->dirtyInventory();
- }
- // save texture data as soon as we get texture perms first time
- if (!node->mValid)
- {
- BOOL can_copy = FALSE;
- BOOL can_transfer = FALSE;
- LLAggregatePermissions::EValue value = LLAggregatePermissions::AP_NONE;
- if(node->getObject()->permYouOwner())
- {
- value = ag_texture_perms_owner.getValue(PERM_COPY);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_copy = TRUE;
- }
- value = ag_texture_perms_owner.getValue(PERM_TRANSFER);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_transfer = TRUE;
- }
- }
- else
- {
- value = ag_texture_perms.getValue(PERM_COPY);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_copy = TRUE;
- }
- value = ag_texture_perms.getValue(PERM_TRANSFER);
- if (value == LLAggregatePermissions::AP_EMPTY || value == LLAggregatePermissions::AP_ALL)
- {
- can_transfer = TRUE;
- }
- }
- if (can_copy && can_transfer)
- {
- // this should be the only place that saved textures is called
- node->saveTextures(texture_ids);
- }
- }
- node->mValid = TRUE;
- node->mPermissions->init(creator_id, owner_id,
- last_owner_id, group_id);
- node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
- node->mCreationDate = creation_date;
- node->mItemID = item_id;
- node->mFolderID = folder_id;
- node->mFromTaskID = from_task_id;
- node->mName.assign(name);
- node->mDescription.assign(desc);
- node->mSaleInfo = sale_info;
- node->mAggregatePerm = ag_perms;
- node->mAggregateTexturePerm = ag_texture_perms;
- node->mAggregateTexturePermOwner = ag_texture_perms_owner;
- node->mCategory = category;
- node->mInventorySerial = inv_serial;
- node->mSitName.assign(sit_name);
- node->mTouchName.assign(touch_name);
- }
- }
- dialog_refresh_all();
- // silly hack to allow 'save into inventory'
- if(gPopupMenuView->getVisible())
- {
- gPopupMenuView->setItemEnabled(SAVE_INTO_INVENTORY,
- enable_save_into_inventory(NULL));
- }
- // hack for left-click buy object
- LLToolPie::selectionPropertiesReceived();
- }
- // static
- void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data)
- {
- LLUUID id;
- U32 request_flags;
- LLUUID creator_id;
- LLUUID owner_id;
- LLUUID group_id;
- LLUUID extra_id;
- U32 base_mask, owner_mask, group_mask, everyone_mask, next_owner_mask;
- LLSaleInfo sale_info;
- LLCategory category;
-
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_RequestFlags, request_flags );
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, id );
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, owner_id );
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, group_id );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_BaseMask, base_mask );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_OwnerMask, owner_mask );
- msg->getU32Fast(_PREHASH_ObjectData,_PREHASH_GroupMask, group_mask );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_EveryoneMask, everyone_mask );
- msg->getU32Fast(_PREHASH_ObjectData, _PREHASH_NextOwnerMask, next_owner_mask);
- sale_info.unpackMessage(msg, _PREHASH_ObjectData);
- category.unpackMessage(msg, _PREHASH_ObjectData);
- LLUUID last_owner_id;
- msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_LastOwnerID, last_owner_id );
- // unpack name & desc
- std::string name;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, name);
- std::string desc;
- msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, desc);
- // the reporter widget askes the server for info about picked objects
- if (request_flags & COMPLAINT_REPORT_REQUEST )
- {
- LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
- if (reporterp)
- {
- std::string fullname;
- gCacheName->getFullName(owner_id, fullname);
- reporterp->setPickedObjectProperties(name, fullname, owner_id);
- }
- }
- else if (request_flags & OBJECT_PAY_REQUEST)
- {
- // check if the owner of the paid object is muted
- LLMuteList::getInstance()->autoRemove(owner_id, LLMuteList::AR_MONEY);
- }
- // Now look through all of the hovered nodes
- struct f : public LLSelectedNodeFunctor
- {
- LLUUID mID;
- f(const LLUUID& id) : mID(id) {}
- virtual bool apply(LLSelectNode* node)
- {
- return (node->getObject() && node->getObject()->mID == mID);
- }
- } func(id);
- LLSelectNode* node = LLSelectMgr::getInstance()->mHoverObjects->getFirstNode(&func);
- if (node)
- {
- node->mValid = TRUE;
- node->mPermissions->init(LLUUID::null, owner_id,
- last_owner_id, group_id);
- node->mPermissions->initMasks(base_mask, owner_mask, everyone_mask, group_mask, next_owner_mask);
- node->mSaleInfo = sale_info;
- node->mCategory = category;
- node->mName.assign(name);
- node->mDescription.assign(desc);
- }
- dialog_refresh_all();
- }
- // static
- void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**)
- {
- BOOL reset_list;
- msg->getBOOL("Header", "ResetList", reset_list);
- if (reset_list)
- {
- LLSelectMgr::getInstance()->deselectAll();
- }
- LLUUID full_id;
- S32 local_id;
- LLViewerObject* object;
- std::vector<LLViewerObject*> objects;
- S32 i;
- S32 block_count = msg->getNumberOfBlocks("Data");
- for (i = 0; i < block_count; i++)
- {
- msg->getS32("Data", "LocalID", local_id, i);
- gObjectList.getUUIDFromLocal(full_id,
- local_id,
- msg->getSenderIP(),
- msg->getSenderPort());
- object = gObjectList.findObject(full_id);
- if (object)
- {
- objects.push_back(object);
- }
- }
- // Don't select, just highlight
- LLSelectMgr::getInstance()->highlightObjectAndFamily(objects);
- }
- extern LLGLdouble gGLModelView[16];
- void LLSelectMgr::updateSilhouettes()
- {
- S32 num_sils_genned = 0;
- LLVector3d cameraPos = gAgent.getCameraPositionGlobal();
- F32 currentCameraZoom = gAgent.getCurrentCameraBuildOffset();
- if (!mSilhouetteImagep)
- {
- mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLViewerTexture::BOOST_UI);
- }
- mHighlightedObjects->cleanupNodes();
- if((cameraPos - mLastCameraPos).magVecSquared() > SILHOUETTE_UPDATE_THRESHOLD_SQUARED * currentCameraZoom * currentCameraZoom)
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- object->setChanged(LLXform::SILHOUETTE);
- return true;
- }
- } func;
- getSelection()->applyToObjects(&func);
-
- mLastCameraPos = gAgent.getCameraPositionGlobal();
- }
-
- std::vector<LLViewerObject*> changed_objects;
- updateSelectionSilhouette(mSelectedObjects, num_sils_genned, changed_objects);
- if (mRectSelectedObjects.size() > 0)
- {
- //gGLSPipelineSelection.set();
- //mSilhouetteImagep->bindTexture();
- //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
- std::set<LLViewerObject*> roots;
- // sync mHighlightedObjects with mRectSelectedObjects since the latter is rebuilt every frame and former
- // persists from frame to frame to avoid regenerating object silhouettes
- // mHighlightedObjects includes all siblings of rect selected objects
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- // generate list of roots from current object selection
- for (std::set<LLPointer<LLViewerObject> >::iterator iter = mRectSelectedObjects.begin();
- iter != mRectSelectedObjects.end(); iter++)
- {
- LLViewerObject *objectp = *iter;
- if (select_linked_set)
- {
- LLViewerObject *rootp = (LLViewerObject*)objectp->getRoot();
- roots.insert(rootp);
- }
- else
- {
- roots.insert(objectp);
- }
- }
- // remove highlight nodes not in roots list
- std::vector<LLSelectNode*> remove_these_nodes;
- std::vector<LLViewerObject*> remove_these_roots;
- for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
- iter != mHighlightedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- if (objectp->isRoot() || !select_linked_set)
- {
- if (roots.count(objectp) == 0)
- {
- remove_these_nodes.push_back(node);
- }
- else
- {
- remove_these_roots.push_back(objectp);
- }
- }
- else
- {
- LLViewerObject* rootp = (LLViewerObject*)objectp->getRoot();
- if (roots.count(rootp) == 0)
- {
- remove_these_nodes.push_back(node);
- }
- }
- }
- // remove all highlight nodes no longer in rectangle selection
- for (std::vector<LLSelectNode*>::iterator iter = remove_these_nodes.begin();
- iter != remove_these_nodes.end(); ++iter)
- {
- LLSelectNode* nodep = *iter;
- mHighlightedObjects->removeNode(nodep);
- }
- // remove all root objects already being highlighted
- for (std::vector<LLViewerObject*>::iterator iter = remove_these_roots.begin();
- iter != remove_these_roots.end(); ++iter)
- {
- LLViewerObject* objectp = *iter;
- roots.erase(objectp);
- }
- // add all new objects in rectangle selection
- for (std::set<LLViewerObject*>::iterator iter = roots.begin();
- iter != roots.end(); iter++)
- {
- LLViewerObject* objectp = *iter;
- if (!canSelectObject(objectp))
- {
- continue;
- }
- LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
- rect_select_root_node->selectAllTEs(TRUE);
- if (!select_linked_set)
- {
- rect_select_root_node->mIndividualSelection = TRUE;
- }
- else
- {
- 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_objectp = *iter;
-
- if (!canSelectObject(child_objectp))
- {
- continue;
- }
- LLSelectNode* rect_select_node = new LLSelectNode(child_objectp, TRUE);
- rect_select_node->selectAllTEs(TRUE);
- mHighlightedObjects->addNodeAtEnd(rect_select_node);
- }
- }
- // Add the root last, to preserve order for link operations.
- mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
- }
- num_sils_genned = 0;
- // render silhouettes for highlighted objects
- //BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
- iter != mHighlightedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
-
- // do roots first, then children so that root flags are cleared ASAP
- BOOL roots_only = (pass == 0);
- BOOL is_root = objectp->isRootEdit();
- if (roots_only != is_root)
- {
- continue;
- }
- if (!node->mSilhouetteExists
- || objectp->isChanged(LLXform::SILHOUETTE)
- || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
- {
- if (num_sils_genned++ < MAX_SILS_PER_FRAME)
- {
- generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
- changed_objects.push_back(objectp);
- }
- else if (objectp->isAttachment() && objectp->getRootEdit()->mDrawable.notNull())
- {
- //RN: hack for orthogonal projection of HUD attachments
- LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
- if (attachment_pt && attachment_pt->getIsHUDAttachment())
- {
- LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
- generateSilhouette(node, camera_pos);
- }
- }
- }
- //LLColor4 highlight_color;
- //
- //if (subtracting_from_selection)
- //{
- // node->renderOneSilhouette(LLColor4::red);
- //}
- //else if (!objectp->isSelected())
- //{
- // highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
- // node->renderOneSilhouette(highlight_color);
- //}
- }
- }
- //mSilhouetteImagep->unbindTexture(0, GL_TEXTURE_2D);
- }
- else
- {
- mHighlightedObjects->deleteAllNodes();
- }
- for (std::vector<LLViewerObject*>::iterator iter = changed_objects.begin();
- iter != changed_objects.end(); ++iter)
- {
- // clear flags after traversing node list (as child objects need to refer to parent flags, etc)
- LLViewerObject* objectp = *iter;
- objectp->clearChanged(LLXform::MOVED | LLXform::SILHOUETTE);
- }
-
- //gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- }
- void LLSelectMgr::updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects)
- {
- if (object_handle->getNumNodes())
- {
- //gGLSPipelineSelection.set();
- //mSilhouetteImagep->bindTexture();
- //glAlphaFunc(GL_GREATER, sHighlightAlphaTest);
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = object_handle->begin();
- iter != object_handle->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- // do roots first, then children so that root flags are cleared ASAP
- BOOL roots_only = (pass == 0);
- BOOL is_root = (objectp->isRootEdit());
- if (roots_only != is_root || objectp->mDrawable.isNull())
- {
- continue;
- }
- if (!node->mSilhouetteExists
- || objectp->isChanged(LLXform::SILHOUETTE)
- || (objectp->getParent() && objectp->getParent()->isChanged(LLXform::SILHOUETTE)))
- {
- if (num_sils_genned++ < MAX_SILS_PER_FRAME)// && objectp->mDrawable->isVisible())
- {
- generateSilhouette(node, LLViewerCamera::getInstance()->getOrigin());
- changed_objects.push_back(objectp);
- }
- else if (objectp->isAttachment())
- {
- //RN: hack for orthogonal projection of HUD attachments
- LLViewerJointAttachment* attachment_pt = (LLViewerJointAttachment*)objectp->getRootEdit()->mDrawable->getParent();
- if (attachment_pt && attachment_pt->getIsHUDAttachment())
- {
- LLVector3 camera_pos = LLVector3(-10000.f, 0.f, 0.f);
- generateSilhouette(node, camera_pos);
- }
- }
- }
- }
- }
- }
- }
- void LLSelectMgr::renderSilhouettes(BOOL for_hud)
- {
- if (!mRenderSilhouettes)
- {
- return;
- }
- gGL.getTexUnit(0)->bind(mSilhouetteImagep);
- LLGLSPipelineSelection gls_select;
- gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLVOAvatar* avatar = gAgent.getAvatarObject();
- if (for_hud && avatar)
- {
- LLBBox hud_bbox = avatar->getHUDBBox();
- F32 cur_zoom = gAgent.mHUDCurZoom;
- // set up transform to encompass bounding box of HUD
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- F32 depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
- glOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, depth);
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- glLoadMatrixf(OGL_TO_CFR_ROTATION); // Load Cory's favorite reference frame
- glTranslatef(-hud_bbox.getCenterLocal().mV[VX] + (depth *0.5f), 0.f, 0.f);
- glScalef(cur_zoom, cur_zoom, cur_zoom);
- }
- if (mSelectedObjects->getNumNodes())
- {
- LLUUID inspect_item_id= LLUUID::null;
- #if 0
- LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
- if(inspect_instance)
- {
- inspect_item_id = inspect_instance->getSelectedUUID();
- }
- #endif
- LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
- if (panel_task_info)
- {
- inspect_item_id = panel_task_info->getSelectedUUID();
- }
- LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID();
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- if (objectp->isHUDAttachment() != for_hud)
- {
- continue;
- }
- if (objectp->getID() == focus_item_id)
- {
- node->renderOneSilhouette(gFocusMgr.getFocusColor());
- }
- else if(objectp->getID() == inspect_item_id)
- {
- node->renderOneSilhouette(sHighlightInspectColor);
- }
- else if (node->isTransient())
- {
- BOOL oldHidden = LLSelectMgr::sRenderHiddenSelections;
- LLSelectMgr::sRenderHiddenSelections = FALSE;
- node->renderOneSilhouette(sContextSilhouetteColor);
- LLSelectMgr::sRenderHiddenSelections = oldHidden;
- }
- else if (objectp->isRootEdit())
- {
- node->renderOneSilhouette(sSilhouetteParentColor);
- }
- else
- {
- node->renderOneSilhouette(sSilhouetteChildColor);
- }
- }
- }
- }
- if (mHighlightedObjects->getNumNodes())
- {
- // render silhouettes for highlighted objects
- BOOL subtracting_from_selection = (gKeyboard->currentMask(TRUE) == MASK_CONTROL);
- for (S32 pass = 0; pass < 2; pass++)
- {
- for (LLObjectSelection::iterator iter = mHighlightedObjects->begin();
- iter != mHighlightedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* objectp = node->getObject();
- if (!objectp)
- continue;
- if (objectp->isHUDAttachment() != for_hud)
- {
- continue;
- }
- if (subtracting_from_selection)
- {
- node->renderOneSilhouette(LLColor4::red);
- }
- else if (!objectp->isSelected())
- {
- LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor;
- node->renderOneSilhouette(highlight_color);
- }
- }
- }
- }
- if (for_hud && avatar)
- {
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- stop_glerror();
- }
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- }
- void LLSelectMgr::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point)
- {
- LLViewerObject* objectp = nodep->getObject();
- if (objectp && objectp->getPCode() == LL_PCODE_VOLUME)
- {
- ((LLVOVolume*)objectp)->generateSilhouette(nodep, view_point);
- }
- }
- //
- // Utility classes
- //
- LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow)
- : mObject(object),
- mIndividualSelection(FALSE),
- mTransient(FALSE),
- mValid(FALSE),
- mPermissions(new LLPermissions()),
- mInventorySerial(0),
- mSilhouetteExists(FALSE),
- mDuplicated(FALSE),
- mTESelectMask(0),
- mLastTESelected(0)
- {
- mObject = object;
- selectAllTEs(FALSE);
- mIndividualSelection = FALSE;
- mTransient = FALSE;
- mValid = FALSE;
- mPermissions = new LLPermissions();
- mInventorySerial = 0;
- mName = LLStringUtil::null;
- mDescription = LLStringUtil::null;
- mTouchName = LLStringUtil::null;
- mSitName = LLStringUtil::null;
- mSilhouetteExists = FALSE;
- mDuplicated = FALSE;
- mCreationDate = 0;
- saveColors();
- }
- LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
- {
- mTESelectMask = nodep.mTESelectMask;
- mLastTESelected = nodep.mLastTESelected;
- mIndividualSelection = nodep.mIndividualSelection;
- mValid = nodep.mValid;
- mTransient = nodep.mTransient;
- mPermissions = new LLPermissions(*nodep.mPermissions);
- mSaleInfo = nodep.mSaleInfo;;
- mAggregatePerm = nodep.mAggregatePerm;
- mAggregateTexturePerm = nodep.mAggregateTexturePerm;
- mAggregateTexturePermOwner = nodep.mAggregateTexturePermOwner;
- mName = nodep.mName;
- mDescription = nodep.mDescription;
- mCategory = nodep.mCategory;
- mInventorySerial = 0;
- mSavedPositionLocal = nodep.mSavedPositionLocal;
- mSavedPositionGlobal = nodep.mSavedPositionGlobal;
- mSavedScale = nodep.mSavedScale;
- mSavedRotation = nodep.mSavedRotation;
- mDuplicated = nodep.mDuplicated;
- mDuplicatePos = nodep.mDuplicatePos;
- mDuplicateRot = nodep.mDuplicateRot;
- mItemID = nodep.mItemID;
- mFolderID = nodep.mFolderID;
- mFromTaskID = nodep.mFromTaskID;
- mTouchName = nodep.mTouchName;
- mSitName = nodep.mSitName;
- mCreationDate = nodep.mCreationDate;
- mSilhouetteVertices = nodep.mSilhouetteVertices;
- mSilhouetteNormals = nodep.mSilhouetteNormals;
- mSilhouetteSegments = nodep.mSilhouetteSegments;
- mSilhouetteExists = nodep.mSilhouetteExists;
- mObject = nodep.mObject;
- std::vector<LLColor4>::const_iterator color_iter;
- mSavedColors.clear();
- for (color_iter = nodep.mSavedColors.begin(); color_iter != nodep.mSavedColors.end(); ++color_iter)
- {
- mSavedColors.push_back(*color_iter);
- }
-
- saveTextures(nodep.mSavedTextures);
- }
- LLSelectNode::~LLSelectNode()
- {
- delete mPermissions;
- mPermissions = NULL;
- }
- void LLSelectNode::selectAllTEs(BOOL b)
- {
- mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0;
- mLastTESelected = 0;
- }
- void LLSelectNode::selectTE(S32 te_index, BOOL selected)
- {
- if (te_index < 0 || te_index >= SELECT_MAX_TES)
- {
- return;
- }
- S32 mask = 0x1 << te_index;
- if(selected)
- {
- mTESelectMask |= mask;
- }
- else
- {
- mTESelectMask &= ~mask;
- }
- mLastTESelected = te_index;
- }
- BOOL LLSelectNode::isTESelected(S32 te_index)
- {
- if (te_index < 0 || te_index >= mObject->getNumTEs())
- {
- return FALSE;
- }
- return (mTESelectMask & (0x1 << te_index)) != 0;
- }
- S32 LLSelectNode::getLastSelectedTE()
- {
- if (!isTESelected(mLastTESelected))
- {
- return -1;
- }
- return mLastTESelected;
- }
- LLViewerObject* LLSelectNode::getObject()
- {
- if (!mObject)
- {
- return NULL;
- }
- else if (mObject->isDead())
- {
- mObject = NULL;
- }
- return mObject;
- }
- void LLSelectNode::setObject(LLViewerObject* object)
- {
- mObject = object;
- }
- void LLSelectNode::saveColors()
- {
- if (mObject.notNull())
- {
- mSavedColors.clear();
- for (S32 i = 0; i < mObject->getNumTEs(); i++)
- {
- const LLTextureEntry* tep = mObject->getTE(i);
- mSavedColors.push_back(tep->getColor());
- }
- }
- }
- void LLSelectNode::saveTextures(const std::vector<LLUUID>& textures)
- {
- if (mObject.notNull())
- {
- mSavedTextures.clear();
- for (std::vector<LLUUID>::const_iterator texture_it = textures.begin();
- texture_it != textures.end(); ++texture_it)
- {
- mSavedTextures.push_back(*texture_it);
- }
- }
- }
- void LLSelectNode::saveTextureScaleRatios()
- {
- mTextureScaleRatios.clear();
- if (mObject.notNull())
- {
- for (U8 i = 0; i < mObject->getNumTEs(); i++)
- {
- F32 s,t;
- const LLTextureEntry* tep = mObject->getTE(i);
- tep->getScale(&s,&t);
- U32 s_axis = 0;
- U32 t_axis = 0;
- LLPrimitive::getTESTAxes(i, &s_axis, &t_axis);
- LLVector3 v;
- LLVector3 scale = mObject->getScale();
- if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR)
- {
- v.mV[s_axis] = s*scale.mV[s_axis];
- v.mV[t_axis] = t*scale.mV[t_axis];
- }
- else
- {
- v.mV[s_axis] = s/scale.mV[s_axis];
- v.mV[t_axis] = t/scale.mV[t_axis];
- }
- mTextureScaleRatios.push_back(v);
- }
- }
- }
- // This implementation should be similar to LLTask::allowOperationOnTask
- BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const
- {
- // Extract ownership.
- BOOL object_is_group_owned = FALSE;
- LLUUID object_owner_id;
- mPermissions->getOwnership(object_owner_id, object_is_group_owned);
- // Operations on invalid or public objects is not allowed.
- if (!mObject || (mObject->isDead()) || !mPermissions->isOwned())
- {
- return FALSE;
- }
- // The transfer permissions can never be given through proxy.
- if (PERM_TRANSFER == op)
- {
- // The owner of an agent-owned object can transfer to themselves.
- if ( !object_is_group_owned
- && (gAgent.getID() == object_owner_id) )
- {
- return TRUE;
- }
- else
- {
- // Otherwise check aggregate permissions.
- return mObject->permTransfer();
- }
- }
- if (PERM_MOVE == op
- || PERM_MODIFY == op)
- {
- // only owners can move or modify their attachments
- // no proxy allowed.
- if (mObject->isAttachment() && object_owner_id != gAgent.getID())
- {
- return FALSE;
- }
- }
- // Calculate proxy_agent_id and group_id to use for permissions checks.
- // proxy_agent_id may be set to the object owner through group powers.
- // group_id can only be set to the object's group, if the agent is in that group.
- LLUUID group_id = LLUUID::null;
- LLUUID proxy_agent_id = gAgent.getID();
- // Gods can always operate.
- if (gAgent.isGodlike())
- {
- return TRUE;
- }
- // Check if the agent is in the same group as the object.
- LLUUID object_group_id = mPermissions->getGroup();
- if (object_group_id.notNull() &&
- gAgent.isInGroup(object_group_id))
- {
- // Assume the object's group during this operation.
- group_id = object_group_id;
- }
- // Only allow proxy powers for PERM_COPY if the actual agent can
- // receive the item (ie has PERM_TRANSFER permissions).
- // NOTE: op == PERM_TRANSFER has already been handled, but if
- // that ever changes we need to BLOCK proxy powers for PERM_TRANSFER. DK 03/28/06
- if (PERM_COPY != op || mPermissions->allowTransferTo(gAgent.getID()))
- {
- // Check if the agent can assume ownership through group proxy or agent-granted proxy.
- if ( ( object_is_group_owned
- && gAgent.hasPowerInGroup(object_owner_id, group_proxy_power))
- // Only allow proxy for move, modify, and copy.
- || ( (PERM_MOVE == op || PERM_MODIFY == op || PERM_COPY == op)
- && (!object_is_group_owned
- && gAgent.isGrantedProxy(*mPermissions))))
- {
- // This agent is able to assume the ownership role for this operation.
- proxy_agent_id = object_owner_id;
- }
- }
-
- // We now have max ownership information.
- if (PERM_OWNER == op)
- {
- // This this was just a check for ownership, we can now return the answer.
- return (proxy_agent_id == object_owner_id ? TRUE : FALSE);
- }
- // check permissions to see if the agent can operate
- return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id));
- }
- //-----------------------------------------------------------------------------
- // renderOneSilhouette()
- //-----------------------------------------------------------------------------
- void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
- {
- LLViewerObject* objectp = getObject();
- if (!objectp)
- {
- return;
- }
- LLDrawable* drawable = objectp->mDrawable;
- if(!drawable)
- {
- return;
- }
- if (!mSilhouetteExists)
- {
- return;
- }
- BOOL is_hud_object = objectp->isHUDAttachment();
-
- if (mSilhouetteVertices.size() == 0 || mSilhouetteNormals.size() != mSilhouetteVertices.size())
- {
- return;
- }
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- if (!is_hud_object)
- {
- glLoadIdentity();
- glMultMatrixd(gGLModelView);
- }
-
-
- if (drawable->isActive())
- {
- glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix);
- }
- LLVolume *volume = objectp->getVolume();
- if (volume)
- {
- F32 silhouette_thickness;
- if (is_hud_object && gAgent.getAvatarObject())
- {
- silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgent.mHUDCurZoom;
- }
- else
- {
- LLVector3 view_vector = LLViewerCamera::getInstance()->getOrigin() - objectp->getRenderPosition();
- silhouette_thickness = view_vector.magVec() * LLSelectMgr::sHighlightThickness * (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV());
- }
- F32 animationTime = (F32)LLFrameTimer::getElapsedSeconds();
- F32 u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
- F32 v_coord = 1.f - fmod(animationTime * LLSelectMgr::sHighlightVAnim, 1.f);
- F32 u_divisor = 1.f / ((F32)(mSilhouetteVertices.size() - 1));
- if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
- {
- gGL.flush();
- gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
- LLGLEnable fog(GL_FOG);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
- LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgent.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
- glFogf(GL_FOG_START, d);
- glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
- glFogfv(GL_FOG_COLOR, fogCol.mV);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- gGL.begin(LLRender::LINES);
- {
- S32 i = 0;
- for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++)
- {
- for(; i < mSilhouetteSegments[seg_num]; i++)
- {
- u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
- gGL.texCoord2f( u_coord, v_coord );
- gGL.vertex3fv( mSilhouetteVertices[i].mV );
- }
- }
- }
- gGL.end();
- u_coord = fmod(animationTime * LLSelectMgr::sHighlightUAnim, 1.f);
- }
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.begin(LLRender::TRIANGLES);
- {
- S32 i = 0;
- for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++)
- {
- S32 first_i = i;
- LLVector3 v;
- LLVector2 t;
- for(; i < mSilhouetteSegments[seg_num]; i++)
- {
- if (i == first_i) {
- LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness;
- vert += mSilhouetteVertices[i];
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha);
- gGL.texCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale );
- gGL.vertex3fv( vert.mV );
-
- u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
- gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
- gGL.texCoord2f( u_coord, v_coord );
- gGL.vertex3fv( mSilhouetteVertices[i].mV );
- v = mSilhouetteVertices[i];
- t = LLVector2(u_coord, v_coord);
- }
- else {
- LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness;
- vert += mSilhouetteVertices[i];
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha);
- gGL.texCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale );
- gGL.vertex3fv( vert.mV );
- gGL.vertex3fv( vert.mV );
-
- gGL.texCoord2fv(t.mV);
- u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
- gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
- gGL.vertex3fv(v.mV);
- gGL.texCoord2f( u_coord, v_coord );
- gGL.vertex3fv( mSilhouetteVertices[i].mV );
- }
- }
- }
- }
- gGL.end();
- gGL.flush();
- }
- glPopMatrix();
- }
- //
- // Utility Functions
- //
- // *DEPRECATED: See header comment.
- void dialog_refresh_all()
- {
- // This is the easiest place to fire the update signal, as it will
- // make cleaning up the functions below easier. Also, sometimes entities
- // outside the selection manager change properties of selected objects
- // and call into this function. Yuck.
- LLSelectMgr::getInstance()->mUpdateSignal();
- // *TODO: Eliminate all calls into outside classes below, make those
- // objects register with the update signal.
- gFloaterTools->dirty();
- gMenuObject->needsArrange();
- if( gMenuAttachmentSelf->getVisible() )
- {
- gMenuAttachmentSelf->arrange();
- }
- if( gMenuAttachmentOther->getVisible() )
- {
- gMenuAttachmentOther->arrange();
- }
- LLFloaterProperties::dirtyAll();
- #if 0
- LLFloaterInspect* inspect_instance = LLFloaterReg::getTypedInstance<LLFloaterInspect>("inspect");
- if(inspect_instance)
- {
- inspect_instance->dirty();
- }
- #endif
- LLSidepanelTaskInfo *panel_task_info = LLSidepanelTaskInfo::getActivePanel();
- if (panel_task_info)
- {
- panel_task_info->dirty();
- }
- }
- S32 get_family_count(LLViewerObject *parent)
- {
- if (!parent)
- {
- llwarns << "Trying to get_family_count on null parent!" << llendl;
- }
- S32 count = 1; // for this object
- LLViewerObject::const_child_list_t& child_list = parent->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* child = *iter;
- if (!child)
- {
- llwarns << "Family object has NULL child! Show Doug." << llendl;
- }
- else if (child->isDead())
- {
- llwarns << "Family object has dead child object. Show Doug." << llendl;
- }
- else
- {
- if (LLSelectMgr::getInstance()->canSelectObject(child))
- {
- count += get_family_count( child );
- }
- }
- }
- return count;
- }
- //-----------------------------------------------------------------------------
- // updateSelectionCenter
- //-----------------------------------------------------------------------------
- void LLSelectMgr::updateSelectionCenter()
- {
- const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
- // center (tractor beam)
- //override any object updates received
- //for selected objects
- overrideObjectUpdates();
- LLViewerObject* object = mSelectedObjects->getFirstObject();
- if (!object)
- {
- // nothing selected, probably grabbing
- // Ignore by setting to avatar origin.
- mSelectionCenterGlobal.clearVec();
- mShowSelection = FALSE;
- mSelectionBBox = LLBBox();
- mPauseRequest = NULL;
- resetAgentHUDZoom();
- }
- else
- {
- mSelectedObjects->mSelectType = getSelectTypeForObject(object);
- if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && gAgent.getAvatarObject())
- {
- mPauseRequest = gAgent.getAvatarObject()->requestPause();
- }
- else
- {
- mPauseRequest = NULL;
- }
- if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && gAgent.getAvatarObject())
- {
- // reset hud ZOOM
- gAgent.mHUDTargetZoom = 1.f;
- gAgent.mHUDCurZoom = 1.f;
- }
- mShowSelection = FALSE;
- LLBBox bbox;
- // have stuff selected
- LLVector3d select_center;
- // keep a list of jointed objects for showing the joint HUDEffects
- std::vector < LLViewerObject *> jointed_objects;
- for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
- iter != mSelectedObjects->end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (!object)
- continue;
- LLViewerObject *myAvatar = gAgent.getAvatarObject();
- LLViewerObject *root = object->getRootEdit();
- if (mSelectedObjects->mSelectType == SELECT_TYPE_WORLD && // not an attachment
- !root->isChild(myAvatar) && // not the object you're sitting on
- !object->isAvatar()) // not another avatar
- {
- mShowSelection = TRUE;
- }
- bbox.addBBoxAgent( object->getBoundingBoxAgent() );
- if (object->isJointChild())
- {
- jointed_objects.push_back(object);
- }
- }
-
- LLVector3 bbox_center_agent = bbox.getCenterAgent();
- mSelectionCenterGlobal = gAgent.getPosGlobalFromAgent(bbox_center_agent);
- mSelectionBBox = bbox;
- }
-
- if ( !(gAgentID == LLUUID::null))
- {
- LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
- if (mShowSelection)
- {
- LLVector3d select_center_global;
- if( tool->isEditing() )
- {
- select_center_global = tool->getEditingPointGlobal();
- }
- else
- {
- select_center_global = mSelectionCenterGlobal;
- }
- // Send selection center if moved beyond threshold (used to animate tractor beam)
- LLVector3d diff;
- diff = select_center_global - mLastSentSelectionCenterGlobal;
- if ( diff.magVecSquared() > MOVE_SELECTION_THRESHOLD*MOVE_SELECTION_THRESHOLD )
- {
- // Transmit updated selection center
- mLastSentSelectionCenterGlobal = select_center_global;
- }
- }
- }
- // give up edit menu if no objects selected
- if (gEditMenuHandler == this && mSelectedObjects->getObjectCount() == 0)
- {
- gEditMenuHandler = NULL;
- }
- }
- void LLSelectMgr::updatePointAt()
- {
- if (mShowSelection)
- {
- if (mSelectedObjects->getObjectCount())
- {
- LLVector3 select_offset;
- const LLPickInfo& pick = gViewerWindow->getLastPick();
- LLViewerObject *click_object = pick.getObject();
- if (click_object && click_object->isSelected())
- {
- // clicked on another object in our selection group, use that as target
- select_offset.setVec(pick.mObjectOffset);
- select_offset.rotVec(~click_object->getRenderRotation());
-
- gAgent.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset);
- gAgent.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset);
- }
- else
- {
- // didn't click on an object this time, revert to pointing at center of first object
- gAgent.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
- gAgent.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
- }
- }
- else
- {
- gAgent.setPointAt(POINTAT_TARGET_CLEAR);
- gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
- }
- }
- else
- {
- gAgent.setPointAt(POINTAT_TARGET_CLEAR);
- gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
- }
- }
- //-----------------------------------------------------------------------------
- // getBBoxOfSelection()
- //-----------------------------------------------------------------------------
- LLBBox LLSelectMgr::getBBoxOfSelection() const
- {
- return mSelectionBBox;
- }
- //-----------------------------------------------------------------------------
- // canUndo()
- //-----------------------------------------------------------------------------
- BOOL LLSelectMgr::canUndo() const
- {
- return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG
- }
- //-----------------------------------------------------------------------------
- // undo()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::undo()
- {
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- LLUUID group_id(gAgent.getGroupID());
- sendListToRegions("Undo", packAgentAndSessionAndGroupID, packObjectID, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
- }
- //-----------------------------------------------------------------------------
- // canRedo()
- //-----------------------------------------------------------------------------
- BOOL LLSelectMgr::canRedo() const
- {
- return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG
- }
- //-----------------------------------------------------------------------------
- // redo()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::redo()
- {
- BOOL select_linked_set = !gSavedSettings.getBOOL("EditLinkedParts");
- LLUUID group_id(gAgent.getGroupID());
- sendListToRegions("Redo", packAgentAndSessionAndGroupID, packObjectID, &group_id, select_linked_set ? SEND_ONLY_ROOTS : SEND_CHILDREN_FIRST);
- }
- //-----------------------------------------------------------------------------
- // canDoDelete()
- //-----------------------------------------------------------------------------
- BOOL LLSelectMgr::canDoDelete() const
- {
- bool can_delete = false;
- // This function is "logically const" - it does not change state in
- // a way visible outside the selection manager.
- LLSelectMgr* self = const_cast<LLSelectMgr*>(this);
- LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject();
- // Note: Can only delete root objects (see getFirstDeleteableObject() for more info)
- if (obj!= NULL)
- {
- // all the faces needs to be selected
- if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES ))
- {
- can_delete = true;
- }
- }
-
- return can_delete;
- }
- //-----------------------------------------------------------------------------
- // doDelete()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::doDelete()
- {
- selectDelete();
- }
- //-----------------------------------------------------------------------------
- // canDeselect()
- //-----------------------------------------------------------------------------
- BOOL LLSelectMgr::canDeselect() const
- {
- return !mSelectedObjects->isEmpty();
- }
- //-----------------------------------------------------------------------------
- // deselect()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::deselect()
- {
- deselectAll();
- }
- //-----------------------------------------------------------------------------
- // canDuplicate()
- //-----------------------------------------------------------------------------
- BOOL LLSelectMgr::canDuplicate() const
- {
- return const_cast<LLSelectMgr*>(this)->mSelectedObjects->getFirstCopyableObject() != NULL; // HACK: casting away constness - MG
- }
- //-----------------------------------------------------------------------------
- // duplicate()
- //-----------------------------------------------------------------------------
- void LLSelectMgr::duplicate()
- {
- LLVector3 offset(0.5f, 0.5f, 0.f);
- selectDuplicate(offset, TRUE);
- }
- ESelectType LLSelectMgr::getSelectTypeForObject(LLViewerObject* object)
- {
- if (!object)
- {
- return SELECT_TYPE_WORLD;
- }
- if (object->isHUDAttachment())
- {
- return SELECT_TYPE_HUD;
- }
- else if (object->isAttachment())
- {
- return SELECT_TYPE_ATTACHMENT;
- }
- else
- {
- return SELECT_TYPE_WORLD;
- }
- }
- void LLSelectMgr::validateSelection()
- {
- struct f : public LLSelectedObjectFunctor
- {
- virtual bool apply(LLViewerObject* object)
- {
- if (!LLSelectMgr::getInstance()->canSelectObject(object))
- {
- LLSelectMgr::getInstance()->deselectObjectOnly(object);
- }
- return true;
- }
- } func;
- getSelection()->applyToObjects(&func);
- }
- BOOL LLSelectMgr::canSelectObject(LLViewerObject* object)
- {
- // Never select dead objects
- if (!object || object->isDead())
- {
- return FALSE;
- }
-
- if (mForceSelection)
- {
- return TRUE;
- }
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) ||
- (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove()))
- {
- // only select my own objects
- return FALSE;
- }
- // Can't select orphans
- if (object->isOrphaned()) return FALSE;
-
- // Can't select avatars
- if (object->isAvatar()) return FALSE;
- // Can't select land
- if (object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) return FALSE;
- ESelectType selection_type = getSelectTypeForObject(object);
- if (mSelectedObjects->getObjectCount() > 0 && mSelectedObjects->mSelectType != selection_type) return FALSE;
- return TRUE;
- }
- BOOL LLSelectMgr::setForceSelection(BOOL force)
- {
- std::swap(mForceSelection,force);
- return force;
- }
- void LLSelectMgr::resetAgentHUDZoom()
- {
- gAgent.mHUDTargetZoom = 1.f;
- gAgent.mHUDCurZoom = 1.f;
- }
- void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 ¤t_zoom) const
- {
- target_zoom = gAgent.mHUDTargetZoom;
- current_zoom = gAgent.mHUDCurZoom;
- }
- void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
- {
- gAgent.mHUDTargetZoom = target_zoom;
- gAgent.mHUDCurZoom = current_zoom;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Object selection iterator helpers
- /////////////////////////////////////////////////////////////////////////////
- bool LLObjectSelection::is_root::operator()(LLSelectNode *node)
- {
- LLViewerObject* object = node->getObject();
- return (object != NULL) && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild());
- }
- bool LLObjectSelection::is_valid_root::operator()(LLSelectNode *node)
- {
- LLViewerObject* object = node->getObject();
- return (object != NULL) && node->mValid && !node->mIndividualSelection && (object->isRootEdit() || object->isJointChild());
- }
- bool LLObjectSelection::is_root_object::operator()(LLSelectNode *node)
- {
- LLViewerObject* object = node->getObject();
- return (object != NULL) && (object->isRootEdit() || object->isJointChild());
- }
- LLObjectSelection::LLObjectSelection() :
- LLRefCount(),
- mSelectType(SELECT_TYPE_WORLD)
- {
- }
- LLObjectSelection::~LLObjectSelection()
- {
- deleteAllNodes();
- }
- void LLObjectSelection::cleanupNodes()
- {
- for (list_t::iterator iter = mList.begin(); iter != mList.end(); )
- {
- list_t::iterator curiter = iter++;
- LLSelectNode* node = *curiter;
- if (node->getObject() == NULL || node->getObject()->isDead())
- {
- mList.erase(curiter);
- delete node;
- }
- }
- }
- void LLObjectSelection::updateEffects()
- {
- }
- S32 LLObjectSelection::getNumNodes()
- {
- return mList.size();
- }
- void LLObjectSelection::addNode(LLSelectNode *nodep)
- {
- llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
- mList.push_front(nodep);
- mSelectNodeMap[nodep->getObject()] = nodep;
- }
- void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep)
- {
- llassert_always(nodep->getObject() && !nodep->getObject()->isDead());
- mList.push_back(nodep);
- mSelectNodeMap[nodep->getObject()] = nodep;
- }
- void LLObjectSelection::moveNodeToFront(LLSelectNode *nodep)
- {
- mList.remove(nodep);
- mList.push_front(nodep);
- }
- void LLObjectSelection::removeNode(LLSelectNode *nodep)
- {
- mSelectNodeMap.erase(nodep->getObject());
- if (nodep->getObject() == mPrimaryObject)
- {
- mPrimaryObject = NULL;
- }
- nodep->setObject(NULL); // Will get erased in cleanupNodes()
- mList.remove(nodep);
- }
- void LLObjectSelection::deleteAllNodes()
- {
- std::for_each(mList.begin(), mList.end(), DeletePointer());
- mList.clear();
- mSelectNodeMap.clear();
- mPrimaryObject = NULL;
- }
- LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp)
- {
- std::map<LLPointer<LLViewerObject>, LLSelectNode*>::iterator found_it = mSelectNodeMap.find(objectp);
- if (found_it != mSelectNodeMap.end())
- {
- return found_it->second;
- }
- return NULL;
- }
- //-----------------------------------------------------------------------------
- // isEmpty()
- //-----------------------------------------------------------------------------
- BOOL LLObjectSelection::isEmpty() const
- {
- return (mList.size() == 0);
- }
- //-----------------------------------------------------------------------------
- // getObjectCount() - returns number of non null objects
- //-----------------------------------------------------------------------------
- S32 LLObjectSelection::getObjectCount()
- {
- cleanupNodes();
- S32 count = mList.size();
- return count;
- }
- //-----------------------------------------------------------------------------
- // getTECount()
- //-----------------------------------------------------------------------------
- S32 LLObjectSelection::getTECount()
- {
- S32 count = 0;
- for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* object = node->getObject();
- if (!object)
- continue;
- S32 num_tes = object->getNumTEs();
- for (S32 te = 0; te < num_tes; te++)
- {
- if (node->isTESelected(te))
- {
- ++count;
- }
- }
- }
- return count;
- }
- //-----------------------------------------------------------------------------
- // getRootObjectCount()
- //-----------------------------------------------------------------------------
- S32 LLObjectSelection::getRootObjectCount()
- {
- S32 count = 0;
- for (LLObjectSelection::root_iterator iter = root_begin(); iter != root_end(); iter++)
- {
- ++count;
- }
- return count;
- }
- bool LLObjectSelection::applyToObjects(LLSelectedObjectFunctor* func)
- {
- bool result = true;
- for (iterator iter = begin(); iter != end(); )
- {
- iterator nextiter = iter++;
- LLViewerObject* object = (*nextiter)->getObject();
- if (!object)
- continue;
- bool r = func->apply(object);
- result = result && r;
- }
- return result;
- }
- bool LLObjectSelection::applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly)
- {
- bool result = firstonly ? false : true;
- for (root_iterator iter = root_begin(); iter != root_end(); )
- {
- root_iterator nextiter = iter++;
- LLViewerObject* object = (*nextiter)->getObject();
- if (!object)
- continue;
- bool r = func->apply(object);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- return result;
- }
- bool LLObjectSelection::applyToTEs(LLSelectedTEFunctor* func, bool firstonly)
- {
- bool result = firstonly ? false : true;
- for (iterator iter = begin(); iter != end(); )
- {
- iterator nextiter = iter++;
- LLSelectNode* node = *nextiter;
- LLViewerObject* object = (*nextiter)->getObject();
- if (!object)
- continue;
- S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces()); // avatars have TEs but no faces
- for (S32 te = 0; te < num_tes; ++te)
- {
- if (node->isTESelected(te))
- {
- bool r = func->apply(object, te);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- }
- }
- return result;
- }
- bool LLObjectSelection::applyToNodes(LLSelectedNodeFunctor *func, bool firstonly)
- {
- bool result = firstonly ? false : true;
- for (iterator iter = begin(); iter != end(); )
- {
- iterator nextiter = iter++;
- LLSelectNode* node = *nextiter;
- bool r = func->apply(node);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- return result;
- }
- bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool firstonly)
- {
- bool result = firstonly ? false : true;
- for (root_iterator iter = root_begin(); iter != root_end(); )
- {
- root_iterator nextiter = iter++;
- LLSelectNode* node = *nextiter;
- bool r = func->apply(node);
- if (firstonly && r)
- return true;
- else
- result = result && r;
- }
- return result;
- }
- BOOL LLObjectSelection::isMultipleTESelected()
- {
- BOOL te_selected = FALSE;
- // ...all faces
- for (LLObjectSelection::iterator iter = begin();
- iter != end(); iter++)
- {
- LLSelectNode* nodep = *iter;
- for (S32 i = 0; i < SELECT_MAX_TES; i++)
- {
- if(nodep->isTESelected(i))
- {
- if(te_selected)
- {
- return TRUE;
- }
- te_selected = TRUE;
- }
- }
- }
- return FALSE;
- }
- //-----------------------------------------------------------------------------
- // contains()
- //-----------------------------------------------------------------------------
- BOOL LLObjectSelection::contains(LLViewerObject* object)
- {
- return findNode(object) != NULL;
- }
- //-----------------------------------------------------------------------------
- // contains()
- //-----------------------------------------------------------------------------
- BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te)
- {
- if (te == SELECT_ALL_TES)
- {
- // ...all faces
- for (LLObjectSelection::iterator iter = begin();
- iter != end(); iter++)
- {
- LLSelectNode* nodep = *iter;
- if (nodep->getObject() == object)
- {
- // Optimization
- if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL)
- {
- return TRUE;
- }
- BOOL all_selected = TRUE;
- for (S32 i = 0; i < object->getNumTEs(); i++)
- {
- all_selected = all_selected && nodep->isTESelected(i);
- }
- return all_selected;
- }
- }
- return FALSE;
- }
- else
- {
- // ...one face
- for (LLObjectSelection::iterator iter = begin(); iter != end(); iter++)
- {
- LLSelectNode* nodep = *iter;
- if (nodep->getObject() == object && nodep->isTESelected(te))
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- }
- // returns TRUE is any node is currenly worn as an attachment
- BOOL LLObjectSelection::isAttachment()
- {
- return (mSelectType == SELECT_TYPE_ATTACHMENT || mSelectType == SELECT_TYPE_HUD);
- }
- //-----------------------------------------------------------------------------
- // getSelectedParentObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* getSelectedParentObject(LLViewerObject *object)
- {
- LLViewerObject *parent;
- while (object && (parent = (LLViewerObject*)object->getParent()))
- {
- if (parent->isSelected())
- {
- object = parent;
- }
- else
- {
- break;
- }
- }
- return object;
- }
- //-----------------------------------------------------------------------------
- // getFirstNode
- //-----------------------------------------------------------------------------
- LLSelectNode* LLObjectSelection::getFirstNode(LLSelectedNodeFunctor* func)
- {
- for (iterator iter = begin(); iter != end(); ++iter)
- {
- LLSelectNode* node = *iter;
- if (func == NULL || func->apply(node))
- {
- return node;
- }
- }
- return NULL;
- }
- LLSelectNode* LLObjectSelection::getFirstRootNode(LLSelectedNodeFunctor* func, BOOL non_root_ok)
- {
- for (root_iterator iter = root_begin(); iter != root_end(); ++iter)
- {
- LLSelectNode* node = *iter;
- if (func == NULL || func->apply(node))
- {
- return node;
- }
- }
- if (non_root_ok)
- {
- // Get non root
- return getFirstNode(func);
- }
- return NULL;
- }
- //-----------------------------------------------------------------------------
- // getFirstSelectedObject
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent)
- {
- LLSelectNode* res = getFirstNode(func);
- if (res && get_parent)
- {
- return getSelectedParentObject(res->getObject());
- }
- else if (res)
- {
- return res->getObject();
- }
- return NULL;
- }
- //-----------------------------------------------------------------------------
- // getFirstObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstObject()
- {
- LLSelectNode* res = getFirstNode(NULL);
- return res ? res->getObject() : NULL;
- }
- //-----------------------------------------------------------------------------
- // getFirstRootObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstRootObject(BOOL non_root_ok)
- {
- LLSelectNode* res = getFirstRootNode(NULL, non_root_ok);
- return res ? res->getObject() : NULL;
- }
- //-----------------------------------------------------------------------------
- // getFirstMoveableNode()
- //-----------------------------------------------------------------------------
- LLSelectNode* LLObjectSelection::getFirstMoveableNode(BOOL get_root_first)
- {
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permMove();
- }
- } func;
- LLSelectNode* res = get_root_first ? getFirstRootNode(&func, TRUE) : getFirstNode(&func);
- return res;
- }
- //-----------------------------------------------------------------------------
- // getFirstCopyableObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstCopyableObject(BOOL get_parent)
- {
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permCopy() && !obj->isAttachment();
- }
- } func;
- return getFirstSelectedObject(&func, get_parent);
- }
- //-----------------------------------------------------------------------------
- // getFirstDeleteableObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstDeleteableObject()
- {
- //RN: don't currently support deletion of child objects, as that requires separating them first
- // then derezzing to trash
-
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- // you can delete an object if you are the owner
- // or you have permission to modify it.
- if( obj && ( (obj->permModify()) ||
- (obj->permYouOwner()) ||
- (!obj->permAnyOwner()) )) // public
- {
- if( !obj->isAttachment() )
- {
- return true;
- }
- }
- return false;
- }
- } func;
- LLSelectNode* node = getFirstNode(&func);
- return node ? node->getObject() : NULL;
- }
- //-----------------------------------------------------------------------------
- // getFirstEditableObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstEditableObject(BOOL get_parent)
- {
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permModify();
- }
- } func;
- return getFirstSelectedObject(&func, get_parent);
- }
- //-----------------------------------------------------------------------------
- // getFirstMoveableObject()
- //-----------------------------------------------------------------------------
- LLViewerObject* LLObjectSelection::getFirstMoveableObject(BOOL get_parent)
- {
- struct f : public LLSelectedNodeFunctor
- {
- bool apply(LLSelectNode* node)
- {
- LLViewerObject* obj = node->getObject();
- return obj && obj->permMove();
- }
- } func;
- return getFirstSelectedObject(&func, get_parent);
- }
- //-----------------------------------------------------------------------------
- // Position + Rotation update methods called from LLViewerJoystick
- //-----------------------------------------------------------------------------
- bool LLSelectMgr::selectionMove(const LLVector3& displ,
- F32 roll, F32 pitch, F32 yaw, U32 update_type)
- {
- if (update_type == UPD_NONE)
- {
- return false;
- }
-
- LLVector3 displ_global;
- bool update_success = true;
- bool update_position = update_type & UPD_POSITION;
- bool update_rotation = update_type & UPD_ROTATION;
- const bool noedit_linked_parts = !gSavedSettings.getBOOL("EditLinkedParts");
-
- if (update_position)
- {
- // calculate the distance of the object closest to the camera origin
- F32 min_dist = 1e+30f;
- LLVector3 obj_pos;
- for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
- it != getSelection()->root_end(); ++it)
- {
- obj_pos = (*it)->getObject()->getPositionEdit();
-
- F32 obj_dist = dist_vec(obj_pos, LLViewerCamera::getInstance()->getOrigin());
- if (obj_dist < min_dist)
- {
- min_dist = obj_dist;
- }
- }
-
- // factor the distance inside the displacement vector. This will get us
- // equally visible movements for both close and far away selections.
- min_dist = sqrt(min_dist) / 2;
- displ_global.setVec(displ.mV[0]*min_dist,
- displ.mV[1]*min_dist,
- displ.mV[2]*min_dist);
- // equates to: Displ_global = Displ * M_cam_axes_in_global_frame
- displ_global = LLViewerCamera::getInstance()->rotateToAbsolute(displ_global);
- }
- LLQuaternion new_rot;
- if (update_rotation)
- {
- // let's calculate the rotation around each camera axes
- LLQuaternion qx(roll, LLViewerCamera::getInstance()->getAtAxis());
- LLQuaternion qy(pitch, LLViewerCamera::getInstance()->getLeftAxis());
- LLQuaternion qz(yaw, LLViewerCamera::getInstance()->getUpAxis());
- new_rot.setQuat(qx * qy * qz);
- }
-
- LLViewerObject *obj;
- S32 obj_count = getSelection()->getObjectCount();
- for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
- it != getSelection()->root_end(); ++it )
- {
- obj = (*it)->getObject();
- bool enable_pos = false, enable_rot = false;
- bool perm_move = obj->permMove();
- bool perm_mod = obj->permModify();
-
- LLVector3d sel_center(getSelectionCenterGlobal());
-
- if (update_rotation)
- {
- enable_rot = perm_move
- && ((perm_mod && !obj->isAttachment()) || noedit_linked_parts);
- if (enable_rot)
- {
- int children_count = obj->getChildren().size();
- if (obj_count > 1 && children_count > 0)
- {
- // for linked sets, rotate around the group center
- const LLVector3 t(obj->getPositionGlobal() - sel_center);
- // Ra = T x R x T^-1
- LLMatrix4 mt; mt.setTranslation(t);
- const LLMatrix4 mnew_rot(new_rot);
- LLMatrix4 mt_1; mt_1.setTranslation(-t);
- mt *= mnew_rot;
- mt *= mt_1;
-
- // Rfin = Rcur * Ra
- obj->setRotation(obj->getRotationEdit() * mt.quaternion());
- displ_global += mt.getTranslation();
- }
- else
- {
- obj->setRotation(obj->getRotationEdit() * new_rot);
- }
- }
- else
- {
- update_success = false;
- }
- }
- if (update_position)
- {
- // establish if object can be moved or not
- enable_pos = perm_move && !obj->isAttachment()
- && (perm_mod || noedit_linked_parts);
-
- if (enable_pos)
- {
- obj->setPosition(obj->getPositionEdit() + displ_global);
- }
- else
- {
- update_success = false;
- }
- }
-
- if (enable_pos && enable_rot && obj->mDrawable.notNull())
- {
- gPipeline.markMoved(obj->mDrawable, TRUE);
- }
- }
-
- if (update_position && update_success && obj_count > 1)
- {
- updateSelectionCenter();
- }
-
- return update_success;
- }
- void LLSelectMgr::sendSelectionMove()
- {
- LLSelectNode *node = mSelectedObjects->getFirstRootNode();
- if (node == NULL)
- {
- return;
- }
-
- //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
-
- U32 update_type = UPD_POSITION | UPD_ROTATION;
- LLViewerRegion *last_region, *curr_region = node->getObject()->getRegion();
- S32 objects_in_this_packet = 0;
- // apply to linked objects if unable to select their individual parts
- if (!gSavedSettings.getBOOL("EditLinkedParts") && !getTEMode())
- {
- // tell simulator to apply to whole linked sets
- update_type |= UPD_LINKED_SETS;
- }
- // prepare first bulk message
- gMessageSystem->newMessage("MultipleObjectUpdate");
- packAgentAndSessionID(&update_type);
- LLViewerObject *obj = NULL;
- for (LLObjectSelection::root_iterator it = getSelection()->root_begin();
- it != getSelection()->root_end(); ++it)
- {
- obj = (*it)->getObject();
- // note: following code adapted from sendListToRegions() (@3924)
- last_region = curr_region;
- curr_region = obj->getRegion();
- // if not simulator or message too big
- if (curr_region != last_region
- || gMessageSystem->isSendFull(NULL)
- || objects_in_this_packet >= MAX_OBJECTS_PER_PACKET)
- {
- // send sim the current message and start new one
- gMessageSystem->sendReliable(last_region->getHost());
- objects_in_this_packet = 0;
- gMessageSystem->newMessage("MultipleObjectUpdate");
- packAgentAndSessionID(&update_type);
- }
- // add another instance of the body of data
- packMultipleUpdate(*it, &update_type);
- ++objects_in_this_packet;
- }
- // flush remaining messages
- if (gMessageSystem->getCurrentSendTotal() > 0)
- {
- gMessageSystem->sendReliable(curr_region->getHost());
- }
- else
- {
- gMessageSystem->clearMessage();
- }
- //saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
- }