summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llagentlistener.cpp153
-rw-r--r--indra/newview/llagentlistener.h5
-rw-r--r--indra/newview/llinventorylistener.cpp6
-rw-r--r--indra/newview/scripts/lua/require/LLAgent.lua45
-rw-r--r--indra/newview/scripts/lua/require/UI.lua6
-rw-r--r--indra/newview/scripts/lua/test_animation.lua18
-rw-r--r--indra/newview/scripts/lua/test_nearby_avatars.lua25
-rw-r--r--indra/newview/scripts/lua/test_screen_position.lua8
8 files changed, 252 insertions, 14 deletions
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
index 14e443ec4e..9255a850e5 100644
--- a/indra/newview/llagentlistener.cpp
+++ b/indra/newview/llagentlistener.cpp
@@ -32,11 +32,14 @@
#include "llagent.h"
#include "llagentcamera.h"
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
#include "llvoavatar.h"
#include "llcommandhandler.h"
#include "llinventorymodel.h"
#include "llslurl.h"
#include "llurldispatcher.h"
+#include "llviewercontrol.h"
#include "llviewernetwork.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
@@ -46,7 +49,8 @@
#include "llsdutil_math.h"
#include "lltoolgrab.h"
#include "llhudeffectlookat.h"
-#include "llagentcamera.h"
+#include "llviewercamera.h"
+#include "resultset.h"
#include <functional>
static const F64 PLAY_ANIM_THROTTLE_PERIOD = 1.f;
@@ -176,6 +180,32 @@ LLAgentListener::LLAgentListener(LLAgent &agent)
"Return information about [\"item_id\"] animation",
&LLAgentListener::getAnimationInfo,
llsd::map("item_id", LLSD(), "reply", LLSD()));
+
+ add("getID",
+ "Return your own avatar ID",
+ &LLAgentListener::getID,
+ llsd::map("reply", LLSD()));
+
+ add("getNearbyAvatarsList",
+ "Return result set key [\"result\"] for nearby avatars in a range of [\"dist\"]\n"
+ "if [\"dist\"] is not specified, 'RenderFarClip' setting is used\n"
+ "reply contains \"result\" table with \"id\", \"name\", \"global_pos\", \"region_pos\" fields",
+ &LLAgentListener::getNearbyAvatarsList,
+ llsd::map("reply", LLSD()));
+
+ add("getNearbyObjectsList",
+ "Return result set key [\"result\"] for nearby objects in a range of [\"dist\"]\n"
+ "if [\"dist\"] is not specified, 'RenderFarClip' setting is used\n"
+ "reply contains \"result\" table with \"id\", \"global_pos\", \"region_pos\" fields",
+ &LLAgentListener::getNearbyObjectsList,
+ llsd::map("reply", LLSD()));
+
+ add("getAgentScreenPos",
+ "Return screen position of the [\"avatar_id\"] avatar or own avatar if not specified\n"
+ "reply contains \"x\", \"y\" coordinates and \"onscreen\" flag to indicate if it's actually in within the current window\n"
+ "avatar render position is used as the point",
+ &LLAgentListener::getAgentScreenPos,
+ llsd::map("reply", LLSD()));
}
void LLAgentListener::requestTeleport(LLSD const & event_data) const
@@ -693,3 +723,124 @@ void LLAgentListener::getAnimationInfo(LLSD const &event_data)
"priority", motion->getPriority());
}
}
+
+void LLAgentListener::getID(LLSD const& event_data)
+{
+ Response response(llsd::map("id", gAgentID), event_data);
+}
+
+struct AvResultSet : public LL::ResultSet
+{
+ AvResultSet() : LL::ResultSet("nearby_avatars") {}
+ std::vector<LLCharacter*> mAvatars;
+
+ int getLength() const override { return narrow(mAvatars.size()); }
+ LLSD getSingle(int index) const override
+ {
+ auto av = mAvatars[index];
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(av->getID(), &av_name);
+ LLVector3 region_pos = av->getCharacterPosition();
+ return llsd::map("id", av->getID(),
+ "global_pos", ll_sd_from_vector3d(av->getPosGlobalFromAgent(region_pos)),
+ "region_pos", ll_sd_from_vector3(region_pos),
+ "name", av_name.getUserName());
+ }
+};
+
+struct ObjResultSet : public LL::ResultSet
+{
+ ObjResultSet() : LL::ResultSet("nearby_objects") {}
+ std::vector<LLViewerObject*> mObjects;
+
+ int getLength() const override { return narrow(mObjects.size()); }
+ LLSD getSingle(int index) const override
+ {
+ auto obj = mObjects[index];
+ return llsd::map("id", obj->getID(),
+ "global_pos", ll_sd_from_vector3d(obj->getPositionGlobal()),
+ "region_pos", ll_sd_from_vector3(obj->getPositionRegion()));
+ }
+};
+
+
+F32 get_search_radius(LLSD const& event_data)
+{
+ static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
+ F32 dist = render_far_clip;
+ if (event_data.has("dist"))
+ {
+ dist = llclamp((F32)event_data["dist"].asReal(), 1, 512);
+ }
+ return dist * dist;
+}
+
+void LLAgentListener::getNearbyAvatarsList(LLSD const& event_data)
+{
+ Response response(LLSD(), event_data);
+ auto avresult = new AvResultSet;
+
+ F32 radius = get_search_radius(event_data);
+ LLVector3d agent_pos = gAgent.getPositionGlobal();
+ for (LLCharacter* character : LLCharacter::sInstances)
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*)character;
+ if (!avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf())
+ {
+ if ((dist_vec_squared(avatar->getPositionGlobal(), agent_pos) <= radius))
+ {
+ avresult->mAvatars.push_back(avatar);
+ }
+ }
+ }
+ response["result"] = avresult->getKeyLength();
+}
+
+void LLAgentListener::getNearbyObjectsList(LLSD const& event_data)
+{
+ Response response(LLSD(), event_data);
+ auto objresult = new ObjResultSet;
+
+ F32 radius = get_search_radius(event_data);
+ S32 num_objects = gObjectList.getNumObjects();
+ LLVector3d agent_pos = gAgent.getPositionGlobal();
+ for (S32 i = 0; i < num_objects; ++i)
+ {
+ LLViewerObject* object = gObjectList.getObject(i);
+ if (object && object->getVolume() && !object->isAttachment())
+ {
+ if ((dist_vec_squared(object->getPositionGlobal(), agent_pos) <= radius))
+ {
+ objresult->mObjects.push_back(object);
+ }
+ }
+ }
+ response["result"] = objresult->getKeyLength();
+}
+
+void LLAgentListener::getAgentScreenPos(LLSD const& event_data)
+{
+ Response response(LLSD(), event_data);
+ LLVector3 render_pos;
+ if (event_data.has("avatar_id"))
+ {
+ LLUUID avatar_id(event_data["avatar_id"]);
+ for (LLCharacter* character : LLCharacter::sInstances)
+ {
+ LLVOAvatar* avatar = (LLVOAvatar*)character;
+ if (!avatar->isDead() && (avatar->getID() == avatar_id))
+ {
+ render_pos = avatar->getRenderPosition();
+ break;
+ }
+ }
+ }
+ else if (gAgentAvatarp.notNull() && gAgentAvatarp->isValid())
+ {
+ render_pos = gAgentAvatarp->getRenderPosition();
+ }
+ LLCoordGL screen_pos;
+ response["onscreen"] = LLViewerCamera::getInstance()->projectPosAgentToScreen(render_pos, screen_pos, false);
+ response["x"] = screen_pos.mX;
+ response["y"] = screen_pos.mY;
+}
diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h
index 05724ff443..8801c9f7ea 100644
--- a/indra/newview/llagentlistener.h
+++ b/indra/newview/llagentlistener.h
@@ -67,6 +67,11 @@ private:
void stopAnimation(LLSD const &event_data);
void getAnimationInfo(LLSD const &event_data);
+ void getID(LLSD const& event_data);
+ void getNearbyAvatarsList(LLSD const& event_data);
+ void getNearbyObjectsList(LLSD const& event_data);
+ void getAgentScreenPos(LLSD const& event_data);
+
LLViewerObject * findObjectClosestTo( const LLVector3 & position, bool sit_target = false ) const;
private:
diff --git a/indra/newview/llinventorylistener.cpp b/indra/newview/llinventorylistener.cpp
index 79726c3e0b..88b07c0b0b 100644
--- a/indra/newview/llinventorylistener.cpp
+++ b/indra/newview/llinventorylistener.cpp
@@ -116,7 +116,8 @@ struct CatResultSet: public LL::ResultSet
LLSD getSingle(int index) const override
{
auto cat = mCategories[index];
- return llsd::map("name", cat->getName(),
+ return llsd::map("id", cat->getUUID(),
+ "name", cat->getName(),
"parent_id", cat->getParentUUID(),
"type", LLFolderType::lookup(cat->getPreferredType()));
}
@@ -133,7 +134,8 @@ struct ItemResultSet: public LL::ResultSet
LLSD getSingle(int index) const override
{
auto item = mItems[index];
- return llsd::map("name", item->getName(),
+ return llsd::map("id", item->getUUID(),
+ "name", item->getName(),
"parent_id", item->getParentUUID(),
"desc", item->getDescription(),
"inv_type", LLInventoryType::lookup(item->getInventoryType()),
diff --git a/indra/newview/scripts/lua/require/LLAgent.lua b/indra/newview/scripts/lua/require/LLAgent.lua
index 4a1132fe7e..b2be69dcdf 100644
--- a/indra/newview/scripts/lua/require/LLAgent.lua
+++ b/indra/newview/scripts/lua/require/LLAgent.lua
@@ -1,8 +1,26 @@
local leap = require 'leap'
local mapargs = require 'mapargs'
+local result_view = require 'result_view'
+
+local function result(keys)
+ local result_table = {
+ result=result_view(keys.result),
+ -- call result_table:close() to release result sets before garbage
+ -- collection or script completion
+ close = function(self)
+ result_view.close(keys.result[1])
+ end
+ }
+ -- When the result_table is destroyed, close its result_views.
+ return LL.setdtor('LLAgent result', result_table, result_table.close)
+end
local LLAgent = {}
+function LLAgent.getID()
+ return leap.request('LLAgent', {op = 'getID'}).id
+end
+
function LLAgent.getRegionPosition()
return leap.request('LLAgent', {op = 'getPosition'}).region
end
@@ -95,6 +113,33 @@ function LLAgent.requestStand()
leap.send('LLAgent', {op = 'requestStand'})
end
+-- Get the nearby avatars in a range of provided "dist",
+-- if "dist" is not specified, "RenderFarClip" setting is used
+-- reply will contain "result" table with following fields:
+-- "id", "global_pos", "region_pos", "name"
+function LLAgent.getNearbyAvatarsList(...)
+ local args = mapargs('dist', ...)
+ args.op = 'getNearbyAvatarsList'
+ return result(leap.request('LLAgent', args))
+end
+
+-- reply will contain "result" table with following fields:
+-- "id", "global_pos", "region_pos"
+function LLAgent.getNearbyObjectsList(...)
+ local args = mapargs('dist', ...)
+ args.op = 'getNearbyObjectsList'
+ return result(leap.request('LLAgent', args))
+end
+
+-- Get screen position of your own avatar or any other (if "avatar_id is specified)
+-- reply contains "x", "y" coordinates and "onscreen" flag to indicate if it's actually in within the current window
+-- avatar render position is used as the point
+function LLAgent.getAgentScreenPos(...)
+ local args = mapargs('avatar_id', ...)
+ args.op = 'getAgentScreenPos'
+ return leap.request('LLAgent', args)
+end
+
-- ***************************************************************************
-- Autopilot
-- ***************************************************************************
diff --git a/indra/newview/scripts/lua/require/UI.lua b/indra/newview/scripts/lua/require/UI.lua
index cf2695917e..34f3fb75eb 100644
--- a/indra/newview/scripts/lua/require/UI.lua
+++ b/indra/newview/scripts/lua/require/UI.lua
@@ -222,8 +222,10 @@ function UI.hideFloater(floater_name)
leap.send("LLFloaterReg", {op = "hideInstance", name = floater_name})
end
-function UI.toggleFloater(floater_name)
- leap.send("LLFloaterReg", {op = "toggleInstance", name = floater_name})
+function UI.toggleFloater(...)
+ local args = mapargs('name,key', ...)
+ args.op = 'toggleInstance'
+ leap.send("LLFloaterReg", args)
end
function UI.isFloaterVisible(floater_name)
diff --git a/indra/newview/scripts/lua/test_animation.lua b/indra/newview/scripts/lua/test_animation.lua
index 37e7254a6c..ae5eabe148 100644
--- a/indra/newview/scripts/lua/test_animation.lua
+++ b/indra/newview/scripts/lua/test_animation.lua
@@ -7,8 +7,8 @@ animations_id = LLInventory.getBasicFolderID('animatn')
anims = LLInventory.collectDescendentsIf{folder_id=animations_id, type="animatn"}.items
local anim_ids = {}
-for key in pairs(anims) do
- table.insert(anim_ids, key)
+for _, key in pairs(anims) do
+ table.insert(anim_ids, {id = key.id, name = key.name})
end
if #anim_ids == 0 then
@@ -16,17 +16,17 @@ if #anim_ids == 0 then
else
-- Start playing a random animation
math.randomseed(os.time())
- local random_id = anim_ids[math.random(#anim_ids)]
- local anim_info = LLAgent.getAnimationInfo(random_id)
+ local random_anim = anim_ids[math.random(#anim_ids)]
+ local anim_info = LLAgent.getAnimationInfo(random_anim.id)
- print("Starting animation locally: " .. anims[random_id].name)
- print("Loop: " .. anim_info.is_loop .. " Joints: " .. anim_info.num_joints .. " Duration " .. tonumber(string.format("%.2f", anim_info.duration)))
- LLAgent.playAnimation{item_id=random_id}
+ print("Starting animation locally: " .. random_anim.name)
+ print("Loop: " .. tostring(anim_info.is_loop) .. " Joints: " .. anim_info.num_joints .. " Duration " .. tonumber(string.format("%.2f", anim_info.duration)))
+ LLAgent.playAnimation{item_id=random_anim.id}
-- Stop animation after 3 sec if it's looped or longer than 3 sec
- if anim_info.is_loop == 1 or anim_info.duration > 3 then
+ if anim_info.is_loop or anim_info.duration > 3 then
LL.sleep(3)
print("Stop animation.")
- LLAgent.stopAnimation(random_id)
+ LLAgent.stopAnimation(random_anim.id)
end
end
diff --git a/indra/newview/scripts/lua/test_nearby_avatars.lua b/indra/newview/scripts/lua/test_nearby_avatars.lua
new file mode 100644
index 0000000000..c7fa686076
--- /dev/null
+++ b/indra/newview/scripts/lua/test_nearby_avatars.lua
@@ -0,0 +1,25 @@
+inspect = require 'inspect'
+LLAgent = require 'LLAgent'
+
+-- Get the list of nearby avatars and print the info
+local nearby_avatars = LLAgent.getNearbyAvatarsList()
+if nearby_avatars.result.length == 0 then
+ print("No avatars nearby")
+else
+ print("Nearby avatars:")
+ for _, av in pairs(nearby_avatars.result) do
+ print(av.name ..' ID: ' .. av.id ..' Global pos:' .. inspect(av.global_pos))
+ end
+end
+
+-- Get the list of nearby objects in 3m range and print the info
+local nearby_objects = LLAgent.getNearbyObjectsList(3)
+if nearby_objects.result.length == 0 then
+ print("No objects nearby")
+else
+ print("Nearby objects:")
+ local pos={}
+ for _, obj in pairs(nearby_objects.result) do
+ print('ID: ' .. obj.id ..' Global pos:' .. inspect(obj.global_pos))
+ end
+end
diff --git a/indra/newview/scripts/lua/test_screen_position.lua b/indra/newview/scripts/lua/test_screen_position.lua
new file mode 100644
index 0000000000..94d57339b1
--- /dev/null
+++ b/indra/newview/scripts/lua/test_screen_position.lua
@@ -0,0 +1,8 @@
+LLAgent = require 'LLAgent'
+
+local screen_pos = LLAgent.getAgentScreenPos()
+if screen_pos.onscreen then
+ print("Avatar screen coordinates X: " .. screen_pos.x .. " Y: " .. screen_pos.y)
+else
+ print("Avatar is not on the screen")
+end