From 1558cb30d2e6009fa43a4838b746259298279ef0 Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Fri, 11 Mar 2011 14:45:15 -0800 Subject: Added 'getPosition' function to LLAgent control in llEventHost. Reviewed by Kelly. --- indra/newview/llagentlistener.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index c453fe91f4..ef39fed587 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -59,11 +59,20 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "Set the agent to a fixed orientation (optionally specify [\"lookat\"] = array of [x, y, z])", &LLAgentListener::resetAxes); add("getAxes", + "Obsolete - use getPosition instead\n" "Send information about the agent's orientation on [\"reply\"]:\n" "[\"euler\"]: map of {roll, pitch, yaw}\n" "[\"quat\"]: array of [x, y, z, w] quaternion values", &LLAgentListener::getAxes, LLSDMap("reply", LLSD())); + add("getPosition", + "Send information about the agent's position and orientation on [\"reply\"]:\n" + "[\"region\"]: array of region {x, y, z} position\n" + "[\"global\"]: array of global {x, y, z} position\n" + "[\"euler\"]: map of {roll, pitch, yaw}\n" + "[\"quat\"]: array of [x, y, z, w] quaternion values", + &LLAgentListener::getPosition, + LLSDMap("reply", LLSD())); } void LLAgentListener::requestTeleport(LLSD const & event_data) const @@ -140,3 +149,21 @@ void LLAgentListener::getAxes(const LLSD& event) const ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), event); } + + +void LLAgentListener::getPosition(const LLSD& event) const +{ + LLVector3 region_pos(mAgent.getPositionAgent()); + LLVector3 global_pos(mAgent.getPositionGlobal()); + LLQuaternion quat(mAgent.getQuat()); + F32 roll, pitch, yaw; + quat.getEulerAngles(&roll, &pitch, &yaw); + // The official query API for LLQuaternion's [x, y, z, w] values is its + // public member mQ... + sendReply(LLSDMap + ("region", llsd_copy_array(boost::begin(region_pos.mV), boost::end(region_pos.mV))) + ("global", llsd_copy_array(boost::begin(global_pos.mV), boost::end(global_pos.mV))) + ("quat", llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ))) + ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), + event); +} -- cgit v1.2.3 From 18ae6c639e58c4c996d4c3b2a4b34ef41deab970 Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Mon, 14 Mar 2011 17:33:33 -0700 Subject: Added warning if llEventHost LLAgent requestSit() can't find the sit target --- indra/newview/llagentlistener.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index ef39fed587..da5bf59e74 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -117,6 +117,11 @@ void LLAgentListener::requestSit(LLSD const & event_data) const object->getRegion()->sendReliableMessage(); } + else + { + llwarns << "LLAgent requestSit could not find the sit target " + << event_data["obj_uuid"].asUUID() << llendl; + } } void LLAgentListener::requestStand(LLSD const & event_data) const -- cgit v1.2.3 From bc0833d5db9e887f72ea6e7a630781203ad6ad77 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Tue, 15 Mar 2011 04:19:16 +0000 Subject: ER-612: Add LLEventAPI access to LLAgent auto pilot --- indra/newview/llagentlistener.cpp | 183 ++++++++++++++++++++++++++++---------- 1 file changed, 135 insertions(+), 48 deletions(-) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index ef39fed587..8377a66286 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -45,14 +45,14 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "LLAgent listener to (e.g.) teleport, sit, stand, etc."), mAgent(agent) { - add("requestTeleport", + add("requestTeleport", "Teleport: [\"regionname\"], [\"x\"], [\"y\"], [\"z\"]\n" "If [\"skip_confirmation\"] is true, use LLURLDispatcher rather than LLCommandDispatcher.", &LLAgentListener::requestTeleport); - add("requestSit", + add("requestSit", "Ask to sit on the object specified in [\"obj_uuid\"]", &LLAgentListener::requestSit); - add("requestStand", + add("requestStand", "Ask to stand up", &LLAgentListener::requestStand); add("resetAxes", @@ -73,55 +73,90 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "[\"quat\"]: array of [x, y, z, w] quaternion values", &LLAgentListener::getPosition, LLSDMap("reply", LLSD())); + add("startAutoPilot", + "Start the autopilot system using the following parameters:\n" + "[\"target_global\"]: array of target global {x, y, z} position\n" + "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]\n" + "[\"target_rotation\"]: array of [x, y, z, w] quaternion values [default: no target]\n" + "[\"rotation_threshold\"]: target maximum angle from target facing rotation [default: 0.03 radians]\n" + "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]", + //"[\"callback_pump\"]: pump to send success/failure and callback data to [default: none]\n" + //"[\"callback_data\"]: data to send back during a callback [default: none]", + &LLAgentListener::startAutoPilot); + add("getAutoPilot", + "Send information about current state of the autopilot system to [\"reply\"]:\n" + "[\"enabled\"]: boolean indicating whether or not autopilot is enabled\n" + "[\"target_global\"]: array of target global {x, y, z} position\n" + "[\"leader_id\"]: uuid of target autopilot is following\n" + "[\"stop_distance\"]: target maximum distance from target\n" + "[\"target_distance\"]: last known distance from target\n" + "[\"use_rotation\"]: boolean indicating if autopilot has a target facing rotation\n" + "[\"target_facing\"]: array of {x, y} target direction to face\n" + "[\"rotation_threshold\"]: target maximum angle from target facing rotation\n" + "[\"behavior_name\"]: name of the autopilot behavior", + &LLAgentListener::getAutoPilot, + LLSDMap("reply", LLSD())); + add("startFollowPilot", + "Follow [\"leader_id\"] using the autopilot system.", + &LLAgentListener::startFollowPilot); + add("setAutoPilotTarget", + "Update target for currently running autopilot:\n" + "[\"target_global\"]: array of target global {x, y, z} position", + &LLAgentListener::setAutoPilotTarget); + add("stopAutoPilot", + "Stop the autopilot system:\n" + "[\"user_cancel\"] indicates whether or not to act as though user canceled autopilot [default: false]", + &LLAgentListener::stopAutoPilot); + } void LLAgentListener::requestTeleport(LLSD const & event_data) const { - if(event_data["skip_confirmation"].asBoolean()) - { - LLSD params(LLSD::emptyArray()); - params.append(event_data["regionname"]); - params.append(event_data["x"]); - params.append(event_data["y"]); - params.append(event_data["z"]); - LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true); - // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" - // should we just compose LLCommandHandler and LLDispatchListener? - } - else - { - std::string url = LLSLURL(event_data["regionname"], - LLVector3(event_data["x"].asReal(), - event_data["y"].asReal(), - event_data["z"].asReal())).getSLURLString(); - LLURLDispatcher::dispatch(url, NULL, false); - } + if(event_data["skip_confirmation"].asBoolean()) + { + LLSD params(LLSD::emptyArray()); + params.append(event_data["regionname"]); + params.append(event_data["x"]); + params.append(event_data["y"]); + params.append(event_data["z"]); + LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true); + // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "parcel", "login", login_refresh", "balance", "chat" + // should we just compose LLCommandHandler and LLDispatchListener? + } + else + { + std::string url = LLSLURL(event_data["regionname"], + LLVector3(event_data["x"].asReal(), + event_data["y"].asReal(), + event_data["z"].asReal())).getSLURLString(); + LLURLDispatcher::dispatch(url, NULL, false); + } } void LLAgentListener::requestSit(LLSD const & event_data) const { - //mAgent.getAvatarObject()->sitOnObject(); - // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() - // *TODO - find a permanent place to share this code properly. - LLViewerObject *object = gObjectList.findObject(event_data["obj_uuid"]); - - if (object && object->getPCode() == LL_PCODE_VOLUME) - { - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_TargetObject); - gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); - gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0)); - - object->getRegion()->sendReliableMessage(); - } + //mAgent.getAvatarObject()->sitOnObject(); + // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() + // *TODO - find a permanent place to share this code properly. + LLViewerObject *object = gObjectList.findObject(event_data["obj_uuid"]); + + if (object && object->getPCode() == LL_PCODE_VOLUME) + { + gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_TargetObject); + gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID); + gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0)); + + object->getRegion()->sendReliableMessage(); + } } void LLAgentListener::requestStand(LLSD const & event_data) const { - mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); } void LLAgentListener::resetAxes(const LLSD& event) const @@ -153,17 +188,69 @@ void LLAgentListener::getAxes(const LLSD& event) const void LLAgentListener::getPosition(const LLSD& event) const { - LLVector3 region_pos(mAgent.getPositionAgent()); - LLVector3 global_pos(mAgent.getPositionGlobal()); - LLQuaternion quat(mAgent.getQuat()); F32 roll, pitch, yaw; + LLQuaternion quat(mAgent.getQuat()); quat.getEulerAngles(&roll, &pitch, &yaw); - // The official query API for LLQuaternion's [x, y, z, w] values is its - // public member mQ... sendReply(LLSDMap - ("region", llsd_copy_array(boost::begin(region_pos.mV), boost::end(region_pos.mV))) - ("global", llsd_copy_array(boost::begin(global_pos.mV), boost::end(global_pos.mV))) - ("quat", llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ))) + ("region", ll_sd_from_vector3(mAgent.getPositionAgent())) + ("global", ll_sd_from_vector3d(mAgent.getPositionGlobal())) + ("quat", ll_sd_from_quaternion(quat)) ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), event); } + + +void LLAgentListener::startAutoPilot(LLSD const & event) const +{ + LLQuaternion target_rotation_value; + LLQuaternion* target_rotation = NULL; + if (event.has("target_rotation")) + { + target_rotation_value = ll_quaternion_from_sd(event["target_rotation"]); + target_rotation = &target_rotation_value; + } + // *TODO: Use callback_pump and callback_data + F32 rotation_threshold = 0.03f; + if (event.has("rotation_threshold")) + { + rotation_threshold = event["rotation_threshold"].asReal(); + } + mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event["target_global"]), + event["behavior_name"], + target_rotation, + NULL, NULL, + event["stop_distance"].asReal(), + rotation_threshold); +} + +void LLAgentListener::getAutoPilot(const LLSD& event) const +{ + sendReply(LLSDMap + ("enabled", (LLSD::Boolean) mAgent.getAutoPilot()) + ("target_global", ll_sd_from_vector3d(mAgent.getAutoPilotTargetGlobal())) + ("leader_id", mAgent.getAutoPilotLeaderID()) + ("stop_distance", mAgent.getAutoPilotStopDistance()) + ("target_distance", mAgent.getAutoPilotTargetDist()) + ("use_rotation", (LLSD::Boolean) mAgent.getAutoPilotUseRotation()) + ("target_facing", ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing())) + ("rotation_threshold", mAgent.getAutoPilotRotationThreshold()) + ("behavior_name", mAgent.getAutoPilotBehaviorName()), + event); +} + +void LLAgentListener::startFollowPilot(LLSD const & event) const +{ + mAgent.startFollowPilot(event["leader_id"]); +} + +void LLAgentListener::setAutoPilotTarget(LLSD const & event) const +{ + LLVector3d target_global(ll_vector3d_from_sd(event["target_global"])); + mAgent.setAutoPilotTargetGlobal(target_global); +} + +void LLAgentListener::stopAutoPilot(LLSD const & event) const +{ + mAgent.stopAutoPilot(event["user_cancel"]); +} + -- cgit v1.2.3 From 034cf7273fab18a7c6ad1fda1b0d2dd600f31825 Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Thu, 17 Mar 2011 11:37:20 -0700 Subject: Added optional 'fly' property to LLEventHost "LLAgent" setAutoPilot and getAutoPilot functions. Reviewed by Kelly. --- indra/newview/llagentlistener.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index d0361bf768..8476c4847a 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -220,6 +220,11 @@ void LLAgentListener::startAutoPilot(LLSD const & event) const { rotation_threshold = event["rotation_threshold"].asReal(); } + if (event.has("fly")) + { + mAgent.setFlying(event["fly"].asBoolean()); + } + mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event["target_global"]), event["behavior_name"], target_rotation, @@ -240,6 +245,7 @@ void LLAgentListener::getAutoPilot(const LLSD& event) const ("target_facing", ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing())) ("rotation_threshold", mAgent.getAutoPilotRotationThreshold()) ("behavior_name", mAgent.getAutoPilotBehaviorName()), + ("fly", (LLSD::Boolean) mAgent.getFlying()), event); } -- cgit v1.2.3 From 1c34f5caff0f074e983a8ef4d89fd08f1210f526 Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Thu, 17 Mar 2011 16:22:54 -0700 Subject: ER-612: Add LLEventAPI access to LLAgent auto pilot. Follow-on work to allow blocking of flying during autopilot. Reviewed by Kelly. --- indra/newview/llagentlistener.cpp | 66 ++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 25 deletions(-) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 8476c4847a..6b12853547 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -184,10 +184,13 @@ void LLAgentListener::getAxes(const LLSD& event) const quat.getEulerAngles(&roll, &pitch, &yaw); // The official query API for LLQuaternion's [x, y, z, w] values is its // public member mQ... - sendReply(LLSDMap - ("quat", llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ))) - ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), - event); + LLSD reply = LLSD::emptyMap(); + reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); + reply["euler"] = LLSD::emptyMap(); + reply["euler"]["roll"] = roll; + reply["euler"]["pitch"] = pitch; + reply["euler"]["yaw"] = yaw; + sendReply(reply, event); } @@ -196,12 +199,17 @@ void LLAgentListener::getPosition(const LLSD& event) const F32 roll, pitch, yaw; LLQuaternion quat(mAgent.getQuat()); quat.getEulerAngles(&roll, &pitch, &yaw); - sendReply(LLSDMap - ("region", ll_sd_from_vector3(mAgent.getPositionAgent())) - ("global", ll_sd_from_vector3d(mAgent.getPositionGlobal())) - ("quat", ll_sd_from_quaternion(quat)) - ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), - event); + + LLSD reply = LLSD::emptyMap(); + reply["quat"] = llsd_copy_array(boost::begin(quat.mQ), boost::end(quat.mQ)); + reply["euler"] = LLSD::emptyMap(); + reply["euler"]["roll"] = roll; + reply["euler"]["pitch"] = pitch; + reply["euler"]["yaw"] = yaw; + reply["region"] = ll_sd_from_vector3(mAgent.getPositionAgent()); + reply["global"] = ll_sd_from_vector3d(mAgent.getPositionGlobal()); + + sendReply(reply, event); } @@ -220,9 +228,15 @@ void LLAgentListener::startAutoPilot(LLSD const & event) const { rotation_threshold = event["rotation_threshold"].asReal(); } - if (event.has("fly")) + + BOOL allow_flying = TRUE; + if (event.has("allow_flying")) { - mAgent.setFlying(event["fly"].asBoolean()); + allow_flying = (BOOL) event["allow_flying"].asBoolean(); + if (!allow_flying) + { + mAgent.setFlying(FALSE); + } } mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event["target_global"]), @@ -230,23 +244,25 @@ void LLAgentListener::startAutoPilot(LLSD const & event) const target_rotation, NULL, NULL, event["stop_distance"].asReal(), - rotation_threshold); + rotation_threshold, + allow_flying); } void LLAgentListener::getAutoPilot(const LLSD& event) const { - sendReply(LLSDMap - ("enabled", (LLSD::Boolean) mAgent.getAutoPilot()) - ("target_global", ll_sd_from_vector3d(mAgent.getAutoPilotTargetGlobal())) - ("leader_id", mAgent.getAutoPilotLeaderID()) - ("stop_distance", mAgent.getAutoPilotStopDistance()) - ("target_distance", mAgent.getAutoPilotTargetDist()) - ("use_rotation", (LLSD::Boolean) mAgent.getAutoPilotUseRotation()) - ("target_facing", ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing())) - ("rotation_threshold", mAgent.getAutoPilotRotationThreshold()) - ("behavior_name", mAgent.getAutoPilotBehaviorName()), - ("fly", (LLSD::Boolean) mAgent.getFlying()), - event); + LLSD reply = LLSD::emptyMap(); + reply["enabled"] = (LLSD::Boolean) mAgent.getAutoPilot(); + reply["target_global"] = ll_sd_from_vector3d(mAgent.getAutoPilotTargetGlobal()); + reply["leader_id"] = mAgent.getAutoPilotLeaderID(); + reply["stop_distance"] = mAgent.getAutoPilotStopDistance(); + reply["target_distance"] = mAgent.getAutoPilotTargetDist(); + reply["use_rotation"] = (LLSD::Boolean) mAgent.getAutoPilotUseRotation(); + reply["target_facing"] = ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing()); + reply["rotation_threshold"] = mAgent.getAutoPilotRotationThreshold(); + reply["behavior_name"] = mAgent.getAutoPilotBehaviorName(); + reply["fly"] = (LLSD::Boolean) mAgent.getFlying(); + + sendReply(reply, event); } void LLAgentListener::startFollowPilot(LLSD const & event) const -- cgit v1.2.3 From becc9d09970755f9cc0d95c46b9f2d81d5b856b5 Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Tue, 22 Mar 2011 15:44:02 -0700 Subject: Improve LLEventHost API for autopilot and following avatars. Reviewed by Kelly. --- indra/newview/llagentlistener.cpp | 109 ++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 10 deletions(-) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 6b12853547..0d30b95074 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -31,6 +31,7 @@ #include "llagentlistener.h" #include "llagent.h" +#include "llvoavatar.h" #include "llcommandhandler.h" #include "llslurl.h" #include "llurldispatcher.h" @@ -79,7 +80,8 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]\n" "[\"target_rotation\"]: array of [x, y, z, w] quaternion values [default: no target]\n" "[\"rotation_threshold\"]: target maximum angle from target facing rotation [default: 0.03 radians]\n" - "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]", + "[\"behavior_name\"]: name of the autopilot behavior [default: \"\"]" + "[\"allow_flying\"]: allow flying during autopilot [default: True]", //"[\"callback_pump\"]: pump to send success/failure and callback data to [default: none]\n" //"[\"callback_data\"]: data to send back during a callback [default: none]", &LLAgentListener::startAutoPilot); @@ -97,7 +99,10 @@ LLAgentListener::LLAgentListener(LLAgent &agent) &LLAgentListener::getAutoPilot, LLSDMap("reply", LLSD())); add("startFollowPilot", - "Follow [\"leader_id\"] using the autopilot system.", + "[\"leader_id\"]: uuid of target to follow using the autopilot system (optional with avatar_name)\n" + "[\"avatar_name\"]: avatar name to follow using the autopilot system (optional with leader_id)\n" + "[\"allow_flying\"]: allow flying during autopilot [default: True]\n" + "[\"stop_distance\"]: target maxiumum distance from target [default: autopilot guess]", &LLAgentListener::startFollowPilot); add("setAutoPilotTarget", "Update target for currently running autopilot:\n" @@ -213,7 +218,7 @@ void LLAgentListener::getPosition(const LLSD& event) const } -void LLAgentListener::startAutoPilot(LLSD const & event) const +void LLAgentListener::startAutoPilot(LLSD const & event) { LLQuaternion target_rotation_value; LLQuaternion* target_rotation = NULL; @@ -239,11 +244,20 @@ void LLAgentListener::startAutoPilot(LLSD const & event) const } } + F32 stop_distance = 0.f; + if (event.has("stop_distance")) + { + stop_distance = event["stop_distance"].asReal(); + } + + // Clear follow target, this is doing a path + mFollowTarget.setNull(); + mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event["target_global"]), event["behavior_name"], target_rotation, NULL, NULL, - event["stop_distance"].asReal(), + stop_distance, rotation_threshold, allow_flying); } @@ -251,11 +265,29 @@ void LLAgentListener::startAutoPilot(LLSD const & event) const void LLAgentListener::getAutoPilot(const LLSD& event) const { LLSD reply = LLSD::emptyMap(); - reply["enabled"] = (LLSD::Boolean) mAgent.getAutoPilot(); + + LLSD::Boolean enabled = mAgent.getAutoPilot(); + reply["enabled"] = enabled; + reply["target_global"] = ll_sd_from_vector3d(mAgent.getAutoPilotTargetGlobal()); + reply["leader_id"] = mAgent.getAutoPilotLeaderID(); + reply["stop_distance"] = mAgent.getAutoPilotStopDistance(); + reply["target_distance"] = mAgent.getAutoPilotTargetDist(); + if (!enabled && + mFollowTarget.notNull()) + { // Get an actual distance from the target object we were following + LLViewerObject * target = gObjectList.findObject(mFollowTarget); + if (target) + { // Found the target AV, return the actual distance to them as well as their ID + LLVector3 difference = target->getPositionRegion() - mAgent.getPositionAgent(); + reply["target_distance"] = difference.length(); + reply["leader_id"] = mFollowTarget; + } + } + reply["use_rotation"] = (LLSD::Boolean) mAgent.getAutoPilotUseRotation(); reply["target_facing"] = ll_sd_from_vector3(mAgent.getAutoPilotTargetFacing()); reply["rotation_threshold"] = mAgent.getAutoPilotRotationThreshold(); @@ -265,19 +297,76 @@ void LLAgentListener::getAutoPilot(const LLSD& event) const sendReply(reply, event); } -void LLAgentListener::startFollowPilot(LLSD const & event) const +void LLAgentListener::startFollowPilot(LLSD const & event) { - mAgent.startFollowPilot(event["leader_id"]); + LLUUID target_id; + + BOOL allow_flying = TRUE; + if (event.has("allow_flying")) + { + allow_flying = (BOOL) event["allow_flying"].asBoolean(); + } + + if (event.has("leader_id")) + { + target_id = event["leader_id"]; + } + else if (event.has("avatar_name")) + { // Find the avatar with matching name + std::string target_name = event["avatar_name"].asString(); + + if (target_name.length() > 0) + { + S32 num_objects = gObjectList.getNumObjects(); + S32 cur_index = 0; + while (cur_index < num_objects) + { + LLViewerObject * cur_object = gObjectList.getObject(cur_index++); + if (cur_object && + cur_object->asAvatar() && + cur_object->asAvatar()->getFullname() == target_name) + { // Found avatar with matching name, extract id and break out of loop + target_id = cur_object->getID(); + break; + } + } + } + } + + F32 stop_distance = 0.f; + if (event.has("stop_distance")) + { + stop_distance = event["stop_distance"].asReal(); + } + + if (target_id.notNull()) + { + if (!allow_flying) + { + mAgent.setFlying(FALSE); + } + mFollowTarget = target_id; // Save follow target so we can report distance later + + mAgent.startFollowPilot(target_id, allow_flying, stop_distance); + } } void LLAgentListener::setAutoPilotTarget(LLSD const & event) const { - LLVector3d target_global(ll_vector3d_from_sd(event["target_global"])); - mAgent.setAutoPilotTargetGlobal(target_global); + if (event.has("target_global")) + { + LLVector3d target_global(ll_vector3d_from_sd(event["target_global"])); + mAgent.setAutoPilotTargetGlobal(target_global); + } } void LLAgentListener::stopAutoPilot(LLSD const & event) const { - mAgent.stopAutoPilot(event["user_cancel"]); + BOOL user_cancel = FALSE; + if (event.has("user_cancel")) + { + user_cancel = event["user_cancel"].asBoolean(); + } + mAgent.stopAutoPilot(user_cancel); } -- cgit v1.2.3 From 7517f25c4322c858cc7a60d62532dfb654a805dc Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Thu, 24 Mar 2011 10:39:22 -0700 Subject: ER-650: touch events. Added 'requestTouch' API for LLAgent operations via llEventHost. Re-factored some message sending code for grabs. Reviewed by Kelly --- indra/newview/llagentlistener.cpp | 75 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 0d30b95074..0a13644911 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -40,6 +40,7 @@ #include "llviewerregion.h" #include "llsdutil.h" #include "llsdutil_math.h" +#include "lltoolgrab.h" LLAgentListener::LLAgentListener(LLAgent &agent) : LLEventAPI("LLAgent", @@ -56,6 +57,11 @@ LLAgentListener::LLAgentListener(LLAgent &agent) add("requestStand", "Ask to stand up", &LLAgentListener::requestStand); + add("requestTouch", + "[\"obj_uuid\"]: id of object to touch, use this or [\"position\"] to indicate the object to touch" + "[\"position\"]: region position {x, y, z} where to find closest object to touch" + "[\"face\"]: optional object face number to touch[Default: 0]", + &LLAgentListener::requestTouch); add("resetAxes", "Set the agent to a fixed orientation (optionally specify [\"lookat\"] = array of [x, y, z])", &LLAgentListener::resetAxes); @@ -169,6 +175,75 @@ void LLAgentListener::requestStand(LLSD const & event_data) const mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); } +void LLAgentListener::requestTouch(LLSD const & event_data) const +{ + LLViewerObject *object = NULL; + + if (event_data.has("obj_uuid")) + { + object = gObjectList.findObject(event_data["obj_uuid"]); + } + else if (event_data.has("position")) + { + LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); + + // Find the object closest to that position + F32 min_distance = 10000.0f; // Start big + S32 num_objects = gObjectList.getNumObjects(); + S32 cur_index = 0; + while (cur_index < num_objects) + { + LLViewerObject * cur_object = gObjectList.getObject(cur_index++); + if (cur_object) + { // Calculate distance from the target position + LLVector3 target_diff = cur_object->getPositionRegion() - target_position; + F32 distance_to_target = target_diff.length(); + if (distance_to_target < min_distance) + { // Found an object closer + min_distance = distance_to_target; + object = cur_object; + } + } + } + } + + S32 face = 0; + if (event_data.has("face")) + { + face = event_data["face"].asInteger(); + } + + if (object && object->getPCode() == LL_PCODE_VOLUME) + { + // Fake enough pick info to get it to (hopefully) work + LLPickInfo pick; + pick.mObjectFace = face; + + /* + These values are sent to the simulator, but face seems to be easiest to use + + pick.mUVCoords "UVCoord" + pick.mSTCoords "STCoord" + pick.mObjectFace "FaceIndex" + pick.mIntersection "Position" + pick.mNormal "Normal" + pick.mBinormal "Binormal" + */ + + // A touch is a sketchy message sequence ... send a grab, immediately + // followed by un-grabbing, crossing fingers and hoping packets arrive in + // the correct order + send_ObjectGrab_message(object, pick, LLVector3::zero); + send_ObjectDeGrab_message(object, pick); + } + else + { + llwarns << "LLAgent requestTouch could not find the touch target " + << event_data["obj_uuid"].asUUID() << llendl; + } +} + + void LLAgentListener::resetAxes(const LLSD& event) const { if (event.has("lookat")) -- cgit v1.2.3 From 0642000a12785bc4e17b334751f386bd1ec6c702 Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Mon, 28 Mar 2011 10:27:52 -0700 Subject: Added optional 'position' property to 'requestSit' LLEventHost function, re-factored code into new findObjectClosestTo() function. Reviewed by Kelly --- indra/newview/llagentlistener.cpp | 67 +++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 23 deletions(-) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 0a13644911..c1edcef4c0 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -52,7 +52,8 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "If [\"skip_confirmation\"] is true, use LLURLDispatcher rather than LLCommandDispatcher.", &LLAgentListener::requestTeleport); add("requestSit", - "Ask to sit on the object specified in [\"obj_uuid\"]", + "[\"obj_uuid\"]: id of object to sit on, use this or [\"position\"] to indicate the sit target" + "[\"position\"]: region position {x, y, z} where to find closest object to sit on", &LLAgentListener::requestSit); add("requestStand", "Ask to stand up", @@ -149,7 +150,17 @@ void LLAgentListener::requestSit(LLSD const & event_data) const //mAgent.getAvatarObject()->sitOnObject(); // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand() // *TODO - find a permanent place to share this code properly. - LLViewerObject *object = gObjectList.findObject(event_data["obj_uuid"]); + + LLViewerObject *object = NULL; + if (event_data.has("obj_uuid")) + { + object = gObjectList.findObject(event_data["obj_uuid"]); + } + else if (event_data.has("position")) + { + LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); + object = findObjectClosestTo(target_position); + } if (object && object->getPCode() == LL_PCODE_VOLUME) { @@ -165,8 +176,8 @@ void LLAgentListener::requestSit(LLSD const & event_data) const } else { - llwarns << "LLAgent requestSit could not find the sit target " - << event_data["obj_uuid"].asUUID() << llendl; + llwarns << "LLAgent requestSit could not find the sit target: " + << event_data << llendl; } } @@ -175,6 +186,34 @@ void LLAgentListener::requestStand(LLSD const & event_data) const mAgent.setControlFlags(AGENT_CONTROL_STAND_UP); } + +LLViewerObject * LLAgentListener::findObjectClosestTo( const LLVector3 & position ) const +{ + LLViewerObject *object = NULL; + + // Find the object closest to that position + F32 min_distance = 10000.0f; // Start big + S32 num_objects = gObjectList.getNumObjects(); + S32 cur_index = 0; + while (cur_index < num_objects) + { + LLViewerObject * cur_object = gObjectList.getObject(cur_index++); + if (cur_object) + { // Calculate distance from the target position + LLVector3 target_diff = cur_object->getPositionRegion() - position; + F32 distance_to_target = target_diff.length(); + if (distance_to_target < min_distance) + { // Found an object closer + min_distance = distance_to_target; + object = cur_object; + } + } + } + + return object; +} + + void LLAgentListener::requestTouch(LLSD const & event_data) const { LLViewerObject *object = NULL; @@ -186,25 +225,7 @@ void LLAgentListener::requestTouch(LLSD const & event_data) const else if (event_data.has("position")) { LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); - - // Find the object closest to that position - F32 min_distance = 10000.0f; // Start big - S32 num_objects = gObjectList.getNumObjects(); - S32 cur_index = 0; - while (cur_index < num_objects) - { - LLViewerObject * cur_object = gObjectList.getObject(cur_index++); - if (cur_object) - { // Calculate distance from the target position - LLVector3 target_diff = cur_object->getPositionRegion() - target_position; - F32 distance_to_target = target_diff.length(); - if (distance_to_target < min_distance) - { // Found an object closer - min_distance = distance_to_target; - object = cur_object; - } - } - } + object = findObjectClosestTo(target_position); } S32 face = 0; -- cgit v1.2.3 From ebe0c8204df30a85b8228e81acbcf7945c15220c Mon Sep 17 00:00:00 2001 From: Dave SIMmONs Date: Fri, 15 Apr 2011 15:52:52 -0700 Subject: ER-710: Viewer effects. Added 'lookAt' command for LLAgent event host API. Also changed a bunch of parameters named 'event' to 'event_host' since VS highlights them as keywords. Reviewed by Kelly. --- indra/newview/llagentlistener.cpp | 102 ++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 36 deletions(-) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index c1edcef4c0..2dc6764f51 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -41,6 +41,8 @@ #include "llsdutil.h" #include "llsdutil_math.h" #include "lltoolgrab.h" +#include "llhudeffectlookat.h" +#include "llagentcamera.h" LLAgentListener::LLAgentListener(LLAgent &agent) : LLEventAPI("LLAgent", @@ -119,7 +121,11 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "Stop the autopilot system:\n" "[\"user_cancel\"] indicates whether or not to act as though user canceled autopilot [default: false]", &LLAgentListener::stopAutoPilot); - + add("lookAt", + "[\"type\"]: number to indicate the lookAt type, 0 to clear\n" + "[\"obj_uuid\"]: id of object to look at, use this or [\"position\"] to indicate the target\n" + "[\"position\"]: region position {x, y, z} where to find closest object or avatar to look at", + &LLAgentListener::lookAt); } void LLAgentListener::requestTeleport(LLSD const & event_data) const @@ -265,11 +271,11 @@ void LLAgentListener::requestTouch(LLSD const & event_data) const } -void LLAgentListener::resetAxes(const LLSD& event) const +void LLAgentListener::resetAxes(const LLSD& event_data) const { - if (event.has("lookat")) + if (event_data.has("lookat")) { - mAgent.resetAxes(ll_vector3_from_sd(event["lookat"])); + mAgent.resetAxes(ll_vector3_from_sd(event_data["lookat"])); } else { @@ -278,7 +284,7 @@ void LLAgentListener::resetAxes(const LLSD& event) const } } -void LLAgentListener::getAxes(const LLSD& event) const +void LLAgentListener::getAxes(const LLSD& event_data) const { LLQuaternion quat(mAgent.getQuat()); F32 roll, pitch, yaw; @@ -291,11 +297,11 @@ void LLAgentListener::getAxes(const LLSD& event) const reply["euler"]["roll"] = roll; reply["euler"]["pitch"] = pitch; reply["euler"]["yaw"] = yaw; - sendReply(reply, event); + sendReply(reply, event_data); } -void LLAgentListener::getPosition(const LLSD& event) const +void LLAgentListener::getPosition(const LLSD& event_data) const { F32 roll, pitch, yaw; LLQuaternion quat(mAgent.getQuat()); @@ -310,30 +316,30 @@ void LLAgentListener::getPosition(const LLSD& event) const reply["region"] = ll_sd_from_vector3(mAgent.getPositionAgent()); reply["global"] = ll_sd_from_vector3d(mAgent.getPositionGlobal()); - sendReply(reply, event); + sendReply(reply, event_data); } -void LLAgentListener::startAutoPilot(LLSD const & event) +void LLAgentListener::startAutoPilot(LLSD const & event_data) { LLQuaternion target_rotation_value; LLQuaternion* target_rotation = NULL; - if (event.has("target_rotation")) + if (event_data.has("target_rotation")) { - target_rotation_value = ll_quaternion_from_sd(event["target_rotation"]); + target_rotation_value = ll_quaternion_from_sd(event_data["target_rotation"]); target_rotation = &target_rotation_value; } // *TODO: Use callback_pump and callback_data F32 rotation_threshold = 0.03f; - if (event.has("rotation_threshold")) + if (event_data.has("rotation_threshold")) { - rotation_threshold = event["rotation_threshold"].asReal(); + rotation_threshold = event_data["rotation_threshold"].asReal(); } BOOL allow_flying = TRUE; - if (event.has("allow_flying")) + if (event_data.has("allow_flying")) { - allow_flying = (BOOL) event["allow_flying"].asBoolean(); + allow_flying = (BOOL) event_data["allow_flying"].asBoolean(); if (!allow_flying) { mAgent.setFlying(FALSE); @@ -341,16 +347,16 @@ void LLAgentListener::startAutoPilot(LLSD const & event) } F32 stop_distance = 0.f; - if (event.has("stop_distance")) + if (event_data.has("stop_distance")) { - stop_distance = event["stop_distance"].asReal(); + stop_distance = event_data["stop_distance"].asReal(); } // Clear follow target, this is doing a path mFollowTarget.setNull(); - mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event["target_global"]), - event["behavior_name"], + mAgent.startAutoPilotGlobal(ll_vector3d_from_sd(event_data["target_global"]), + event_data["behavior_name"], target_rotation, NULL, NULL, stop_distance, @@ -358,7 +364,7 @@ void LLAgentListener::startAutoPilot(LLSD const & event) allow_flying); } -void LLAgentListener::getAutoPilot(const LLSD& event) const +void LLAgentListener::getAutoPilot(const LLSD& event_data) const { LLSD reply = LLSD::emptyMap(); @@ -390,26 +396,26 @@ void LLAgentListener::getAutoPilot(const LLSD& event) const reply["behavior_name"] = mAgent.getAutoPilotBehaviorName(); reply["fly"] = (LLSD::Boolean) mAgent.getFlying(); - sendReply(reply, event); + sendReply(reply, event_data); } -void LLAgentListener::startFollowPilot(LLSD const & event) +void LLAgentListener::startFollowPilot(LLSD const & event_data) { LLUUID target_id; BOOL allow_flying = TRUE; - if (event.has("allow_flying")) + if (event_data.has("allow_flying")) { - allow_flying = (BOOL) event["allow_flying"].asBoolean(); + allow_flying = (BOOL) event_data["allow_flying"].asBoolean(); } - if (event.has("leader_id")) + if (event_data.has("leader_id")) { - target_id = event["leader_id"]; + target_id = event_data["leader_id"]; } - else if (event.has("avatar_name")) + else if (event_data.has("avatar_name")) { // Find the avatar with matching name - std::string target_name = event["avatar_name"].asString(); + std::string target_name = event_data["avatar_name"].asString(); if (target_name.length() > 0) { @@ -430,9 +436,9 @@ void LLAgentListener::startFollowPilot(LLSD const & event) } F32 stop_distance = 0.f; - if (event.has("stop_distance")) + if (event_data.has("stop_distance")) { - stop_distance = event["stop_distance"].asReal(); + stop_distance = event_data["stop_distance"].asReal(); } if (target_id.notNull()) @@ -447,22 +453,46 @@ void LLAgentListener::startFollowPilot(LLSD const & event) } } -void LLAgentListener::setAutoPilotTarget(LLSD const & event) const +void LLAgentListener::setAutoPilotTarget(LLSD const & event_data) const { - if (event.has("target_global")) + if (event_data.has("target_global")) { - LLVector3d target_global(ll_vector3d_from_sd(event["target_global"])); + LLVector3d target_global(ll_vector3d_from_sd(event_data["target_global"])); mAgent.setAutoPilotTargetGlobal(target_global); } } -void LLAgentListener::stopAutoPilot(LLSD const & event) const +void LLAgentListener::stopAutoPilot(LLSD const & event_data) const { BOOL user_cancel = FALSE; - if (event.has("user_cancel")) + if (event_data.has("user_cancel")) { - user_cancel = event["user_cancel"].asBoolean(); + user_cancel = event_data["user_cancel"].asBoolean(); } mAgent.stopAutoPilot(user_cancel); } +void LLAgentListener::lookAt(LLSD const & event_data) const +{ + LLViewerObject *object = NULL; + if (event_data.has("obj_uuid")) + { + object = gObjectList.findObject(event_data["obj_uuid"]); + } + else if (event_data.has("position")) + { + LLVector3 target_position = ll_vector3_from_sd(event_data["position"]); + object = findObjectClosestTo(target_position); + } + + S32 look_at_type = (S32) LOOKAT_TARGET_NONE; + if (event_data.has("type")) + { + look_at_type = event_data["type"].asInteger(); + } + if (look_at_type >= (S32) LOOKAT_TARGET_NONE && + look_at_type < (S32) LOOKAT_NUM_TARGETS) + { + gAgentCamera.setLookAt((ELookAtType) look_at_type, object); + } +} -- cgit v1.2.3 From c62ef53863bd01cb96de55e0250c8a8193b6c72b Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Fri, 13 May 2011 21:22:54 +0000 Subject: eventhost autopilot system should now set agent to flying when allow_flying= True --- indra/newview/llagentlistener.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'indra/newview/llagentlistener.cpp') diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 706851e7ff..591594d12c 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -339,10 +339,7 @@ void LLAgentListener::startAutoPilot(LLSD const & event_data) if (event_data.has("allow_flying")) { allow_flying = (BOOL) event_data["allow_flying"].asBoolean(); - if (!allow_flying) - { - mAgent.setFlying(FALSE); - } + mAgent.setFlying(allow_flying); } F32 stop_distance = 0.f; @@ -442,10 +439,7 @@ void LLAgentListener::startFollowPilot(LLSD const & event_data) if (target_id.notNull()) { - if (!allow_flying) - { - mAgent.setFlying(FALSE); - } + mAgent.setFlying(allow_flying); mFollowTarget = target_id; // Save follow target so we can report distance later mAgent.startFollowPilot(target_id, allow_flying, stop_distance); -- cgit v1.2.3