diff options
Diffstat (limited to 'indra/newview/llviewermenu.cpp')
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 258 |
1 files changed, 244 insertions, 14 deletions
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ce4c32e34e..86e3fe6eca 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -33,6 +33,7 @@ #include "llviewermenu.h" // linden library includes +#include "indra_constants.h" #include "llavatarnamecache.h" // IDEVO (I Are Not Men!) #include "llcombobox.h" #include "llcoros.h" @@ -56,6 +57,7 @@ // [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0 #include "llattachmentsmgr.h" // [/SL:KB] +#include "llavataractions.h" #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" @@ -75,6 +77,7 @@ #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" +#include "llfloaterpreference.h" #include "llfloaterreporter.h" #include "llfloatersearch.h" #include "llfloaterscriptdebug.h" @@ -83,9 +86,8 @@ #include "llfloatertools.h" #include "llfloaterworldmap.h" #include "llfloaterbuildoptions.h" -#include "llavataractions.h" -#include "lllandmarkactions.h" #include "llgroupmgr.h" +#include "lllandmarkactions.h" #include "lltooltip.h" #include "lltoolface.h" #include "llhints.h" @@ -1009,17 +1011,36 @@ class LLAdvancedToggleFeature : public view_listener_t class LLAdvancedCheckFeature : public view_listener_t { bool handleEvent(const LLSD& userdata) -{ - U32 feature = feature_from_string( userdata.asString() ); - bool new_value = false; + { + U32 feature = feature_from_string( userdata.asString() ); + bool new_value = false; - if ( feature != 0 ) + if ( feature != 0 ) + { + new_value = LLPipeline::toggleRenderDebugFeatureControl( feature ); + } + + return new_value; + } +}; + +class LLAdvancedToggleExperiment : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) { - new_value = LLPipeline::toggleRenderDebugFeatureControl( feature ); + std::string feature = userdata.asString(); + return false; } +}; - return new_value; -} +class LLAdvancedCheckExperiment : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool value = false; + std::string feature = userdata.asString(); + return value; + } }; class LLAdvancedCheckDisplayTextureDensity : public view_listener_t @@ -3409,6 +3430,161 @@ bool enable_attachment_touch(const LLUUID& inv_item_id) return false; } +static void copy_text_to_clipboard(const std::string& text) +{ + if (text.empty() || !gViewerWindow || !gViewerWindow->getWindow()) + { + return; + } + gViewerWindow->getWindow()->copyTextToClipboard(utf8str_to_wstring(text)); +} + +static LLViewerObject* selected_pick_object() +{ + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + return selection ? selection->getPrimaryObject() : nullptr; +} + +// Root first, then each non-avatar child in child-list order. That is the +// same order the viewer uses for link numbers (root is link 1). +static void collect_linkset_objects(LLViewerObject* object, std::vector<LLViewerObject*>& links) +{ + links.clear(); + if (!object || object->isAvatar()) + { + return; + } + LLViewerObject* root = object->getRootEdit(); + if (!root || root->isAvatar()) + { + return; + } + root->addThisAndNonJointChildren(links); +} + +static bool object_is_linkset() +{ + std::vector<LLViewerObject*> links; + collect_linkset_objects(selected_pick_object(), links); + return links.size() > 1; +} + +static void handle_object_copy_uuid() +{ + LLViewerObject* object = selected_pick_object(); + if (!object || object->isAvatar()) + { + return; + } + copy_text_to_clipboard(object->getID().asString()); +} + +static void handle_object_copy_linkset_uuids() +{ + std::vector<LLViewerObject*> links; + collect_linkset_objects(selected_pick_object(), links); + if (links.size() < 2) + { + return; + } + + std::string text; + for (LLViewerObject* link : links) + { + if (!link) + { + continue; + } + if (!text.empty()) + { + text += ", "; + } + text += link->getID().asString(); + } + copy_text_to_clipboard(text); +} + +static void append_unique_selected_object(std::vector<LLViewerObject*>& objects, LLViewerObject* object) +{ + if (!object || object->isAvatar()) + { + return; + } + for (LLViewerObject* existing : objects) + { + if (existing == object) + { + return; + } + } + objects.push_back(object); +} + +// Family roots cover shift-selected objects. Individual nodes cover +// Edit Linked Parts, where each prim is selected on its own. +static void collect_multi_selected_objects(std::vector<LLViewerObject*>& objects) +{ + objects.clear(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (!selection) + { + return; + } + + for (LLObjectSelection::root_iterator it = selection->root_begin(); it != selection->root_end(); ++it) + { + append_unique_selected_object(objects, (*it)->getObject()); + } + for (LLObjectSelection::iterator it = selection->begin(); it != selection->end(); ++it) + { + LLSelectNode* node = *it; + if (!node || !node->mIndividualSelection) + { + continue; + } + append_unique_selected_object(objects, node->getObject()); + } +} + +static bool selection_has_multiple_objects() +{ + std::vector<LLViewerObject*> objects; + collect_multi_selected_objects(objects); + return objects.size() > 1; +} + +static void handle_object_copy_selected_uuids() +{ + std::vector<LLViewerObject*> objects; + collect_multi_selected_objects(objects); + if (objects.size() < 2) + { + return; + } + + std::string text; + for (LLViewerObject* object : objects) + { + if (!text.empty()) + { + text += ", "; + } + text += object->getID().asString(); + } + copy_text_to_clipboard(text); +} + +static void handle_avatar_copy_uuid() +{ + LLUUID id = gAgent.getID(); + LLViewerObject* object = selected_pick_object(); + if (object && object->isAvatar()) + { + id = object->getID(); + } + copy_text_to_clipboard(id.asString()); +} + void handle_object_inspect() { LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); @@ -4708,6 +4884,51 @@ void handle_object_sit(const LLUUID& object_id) handle_object_sit(obj, offset); } +// Looks for the nearest sittable object -- one whose click-action is set to +// CLICK_ACTION_SIT, the flag content creators set (usually alongside a custom +// llSetSitText() label) to mark a prim as a seat -- within a hard-coded +// multiple of the avatar's height. Used by the game-control "toggle sit" +// action to find something to sit on before falling back to sitting on the +// ground. Returns NULL if nothing qualifies. +LLViewerObject* find_nearby_seat() +{ + if (!isAgentAvatarValid()) + { + return NULL; + } + + constexpr F32 SEAT_SEARCH_RANGE_HEIGHTS = 2.f; + const F32 max_dist = SEAT_SEARCH_RANGE_HEIGHTS * gAgentAvatarp->mBodySize.mV[VZ]; + const LLVector3 agent_pos = gAgentAvatarp->getPositionAgent(); + + LLViewerObject* nearest_seat = NULL; + F32 nearest_dist_squared = max_dist * max_dist; + + S32 num_objects = gObjectList.getNumObjects(); + for (S32 i = 0; i < num_objects; ++i) + { + LLViewerObject* object = gObjectList.getObject(i); + if (!object || object->isDead() || object->isAttachment()) + { + continue; + } + + if (object->getPCode() != LL_PCODE_VOLUME || object->getClickAction() != CLICK_ACTION_SIT) + { + continue; + } + + F32 dist_squared = dist_vec_squared(agent_pos, object->getPositionAgent()); + if (dist_squared <= nearest_dist_squared) + { + nearest_seat = object; + nearest_dist_squared = dist_squared; + } + } + + return nearest_seat; +} + void near_sit_down_point(bool success, void*) { if (success) @@ -6993,8 +7214,8 @@ class LLAvatarResetSkeleton : public view_listener_t } else { - avatar->resetSkeleton(false); - } + avatar->resetSkeleton(false); + } } return true; } @@ -7059,9 +7280,9 @@ class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t effectp->setSourceObject(gAgentAvatarp); effectp->setTargetObject((LLViewerObject*)avatar); effectp->setResetAnimations(true); - } - else - { + } + else + { avatar->resetSkeleton(true); } } @@ -10310,6 +10531,9 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature"); view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature"); + view_listener_t::addMenu(new LLAdvancedToggleExperiment(), "Advanced.ToggleExperiment"); + view_listener_t::addMenu(new LLAdvancedCheckExperiment(), "Advanced.CheckExperiment"); + view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity"); view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity"); @@ -10577,6 +10801,12 @@ void initialize_menus() commit.add("Object.Edit", boost::bind(&handle_object_edit)); commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material)); commit.add("Object.Inspect", boost::bind(&handle_object_inspect)); + commit.add("Object.CopyUUID", boost::bind(&handle_object_copy_uuid)); + commit.add("Object.CopyLinksetUUIDs", boost::bind(&handle_object_copy_linkset_uuids)); + enable.add("Object.VisibleCopyLinksetUUIDs", boost::bind(&object_is_linkset)); + commit.add("Object.CopySelectedUUIDs", boost::bind(&handle_object_copy_selected_uuids)); + enable.add("Object.VisibleCopySelectedUUIDs", boost::bind(&selection_has_multiple_objects)); + commit.add("Avatar.CopyUUID", boost::bind(&handle_avatar_copy_uuid)); commit.add("Object.Open", boost::bind(&handle_object_open)); commit.add("Object.Take", boost::bind(&handle_take, false)); commit.add("Object.TakeSeparate", boost::bind(&handle_take, true)); |
