diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llagentlistener.cpp | 59 | ||||
-rw-r--r-- | indra/newview/llagentlistener.h | 4 | ||||
-rw-r--r-- | indra/newview/scripts/lua/require/LLAgent.lua | 4 | ||||
-rw-r--r-- | indra/newview/scripts/lua/test_animation.lua | 28 |
4 files changed, 70 insertions, 25 deletions
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 95b7ebd5db..4980c7075f 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -49,9 +49,12 @@ #include "llagentcamera.h" #include <functional> +static const F64 PLAY_ANIM_THROTTLE_PERIOD = 1.f; + LLAgentListener::LLAgentListener(LLAgent &agent) : LLEventAPI("LLAgent", "LLAgent listener to (e.g.) teleport, sit, stand, etc."), + mPlayAnimThrottle("playAnimation", &LLAgentListener::playAnimation_, this, PLAY_ANIM_THROTTLE_PERIOD), mAgent(agent) { add("requestTeleport", @@ -607,53 +610,59 @@ void LLAgentListener::removeFollowCamParams(LLSD const & event) const LLFollowCamMgr::getInstance()->removeFollowCamParams(gAgentID); } -void LLAgentListener::playAnimation(LLSD const &event_data) +LLViewerInventoryItem* get_anim_item(LLEventAPI::Response &response, const LLSD &event_data) { - Response response(LLSD(), event_data); LLViewerInventoryItem* item = gInventory.getItem(event_data["item_id"].asUUID()); if (!item || (item->getInventoryType() != LLInventoryType::IT_ANIMATION)) { - return response.error(stringize("Item ", std::quoted(event_data["item_id"].asString()), " was not found")); + response.error(stringize("Animation item ", std::quoted(event_data["item_id"].asString()), " was not found")); + return NULL; + } + return item; +} + +void LLAgentListener::playAnimation(LLSD const &event_data) +{ + Response response(LLSD(), event_data); + if (LLViewerInventoryItem* item = get_anim_item(response, event_data)) + { + mPlayAnimThrottle(item->getAssetUUID(), event_data["inworld"].asBoolean()); } - LLUUID assset_id = item->getAssetUUID(); - if(event_data["inworld"].asBoolean()) +} + +void LLAgentListener::playAnimation_(const LLUUID& asset_id, const bool inworld) +{ + if (inworld) { - gAgent.sendAnimationRequest(assset_id, ANIM_REQUEST_START); + mAgent.sendAnimationRequest(asset_id, ANIM_REQUEST_START); } else { - gAgentAvatarp->startMotion(assset_id); + gAgentAvatarp->startMotion(asset_id); } } void LLAgentListener::stopAnimation(LLSD const &event_data) { Response response(LLSD(), event_data); - LLViewerInventoryItem* item = gInventory.getItem(event_data["item_id"].asUUID()); - if (!item || (item->getInventoryType() != LLInventoryType::IT_ANIMATION)) + if (LLViewerInventoryItem* item = get_anim_item(response, event_data)) { - return response.error(stringize("Item ", std::quoted(event_data["item_id"].asString()), " was not found")); + gAgentAvatarp->stopMotion(item->getAssetUUID()); + mAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP); } - LLUUID assset_id = item->getAssetUUID(); - gAgentAvatarp->stopMotion(assset_id); - gAgent.sendAnimationRequest(assset_id, ANIM_REQUEST_STOP); } void LLAgentListener::getAnimationInfo(LLSD const &event_data) { Response response(LLSD(), event_data); - LLUUID item_id(event_data["item_id"].asUUID()); - LLViewerInventoryItem* item = gInventory.getItem(item_id); - if (!item || (item->getInventoryType() != LLInventoryType::IT_ANIMATION)) + if (LLViewerInventoryItem* item = get_anim_item(response, event_data)) { - return response.error(stringize("Item ", std::quoted(item_id.asString()), " was not found")); + // if motion exists, will return existing one + LLMotion* motion = gAgentAvatarp->createMotion(item->getAssetUUID()); + response["anim_info"] = llsd::map("duration", motion->getDuration(), + "is_loop", motion->getLoop(), + "num_joints", motion->getNumJointMotions(), + "asset_id", item->getAssetUUID(), + "priority", motion->getPriority()); } - // if motion exists, will return existing one - LLMotion* motion = gAgentAvatarp->createMotion(item->getAssetUUID()); - response["anim_info"].insert(item_id.asString(), - llsd::map("duration", motion->getDuration(), - "is_loop", motion->getLoop(), - "num_joints", motion->getNumJointMotions(), - "asset_id", item->getAssetUUID(), - "priority", motion->getPriority())); } diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index cf914a17d0..c77d1b3fc9 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -31,6 +31,7 @@ #define LL_LLAGENTLISTENER_H #include "lleventapi.h" +#include "throttle.h" class LLAgent; class LLSD; @@ -62,6 +63,7 @@ private: void removeFollowCamParams(LLSD const & event_data) const; void playAnimation(LLSD const &event_data); + void playAnimation_(const LLUUID& asset_id, const bool inworld); void stopAnimation(LLSD const &event_data); void getAnimationInfo(LLSD const &event_data); @@ -70,6 +72,8 @@ private: private: LLAgent & mAgent; LLUUID mFollowTarget; + + LogThrottle<LLError::LEVEL_DEBUG, void(const LLUUID &, const bool)> mPlayAnimThrottle; }; #endif // LL_LLAGENTLISTENER_H diff --git a/indra/newview/scripts/lua/require/LLAgent.lua b/indra/newview/scripts/lua/require/LLAgent.lua index 56907f53cd..07ef1e0b0b 100644 --- a/indra/newview/scripts/lua/require/LLAgent.lua +++ b/indra/newview/scripts/lua/require/LLAgent.lua @@ -53,6 +53,8 @@ function LLAgent.removeCamParams() leap.send('LLAgent', {op = 'removeCameraParams'}) end +-- Play specified animation by "item_id" locally +-- if "inworld" is specified as true, animation will be played inworld instead function LLAgent.playAnimation(...) local args = mapargs('item_id,inworld', ...) args.op = 'playAnimation' @@ -63,6 +65,8 @@ function LLAgent.stopAnimation(item_id) return leap.request('LLAgent', {op = 'stopAnimation', item_id=item_id}) end +-- Get animation info by "item_id" +-- reply contains "duration", "is_loop", "num_joints", "asset_id", "priority" function LLAgent.getAnimationInfo(item_id) return leap.request('LLAgent', {op = 'getAnimationInfo', item_id=item_id}).anim_info end diff --git a/indra/newview/scripts/lua/test_animation.lua b/indra/newview/scripts/lua/test_animation.lua new file mode 100644 index 0000000000..c16fef4918 --- /dev/null +++ b/indra/newview/scripts/lua/test_animation.lua @@ -0,0 +1,28 @@ +LLInventory = require 'LLInventory' +LLAgent = require 'LLAgent' + +-- Get 'Animations' folder id (you can see all folder types via LLInventory.getFolderTypeNames()) +animations_id = LLInventory.getBasicFolderID('animatn') +-- Get animations from the 'Animation' folder (you can see all folder types via LLInventory.getAssetTypeNames()) +anims = LLInventory.collectDescendentsIf{folder_id=animations_id, type="animatn"}.items + +local anim_ids = {} +for key in pairs(anims) do + table.insert(anim_ids, key) +end + +-- 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) + +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} + +-- 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 + LL.sleep(3) + print("Stop animation.") + LLAgent.stopAnimation(random_id) +end |