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/llagent.cpp | 51 +++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'indra/newview/llagent.cpp') diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7d491a7774..9025982310 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1214,6 +1214,12 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s return; } + // Are there any pending callbacks from previous auto pilot requests? + if (mAutoPilotFinishedCallback) + { + mAutoPilotFinishedCallback(dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); + } + mAutoPilotFinishedCallback = finish_callback; mAutoPilotCallbackData = callback_data; mAutoPilotRotationThreshold = rot_threshold; @@ -1262,22 +1268,8 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s } mAutoPilot = TRUE; - mAutoPilotTargetGlobal = target_global; - - // trace ray down to find height of destination from ground - LLVector3d traceEndPt = target_global; - traceEndPt.mdV[VZ] -= 20.f; - - LLVector3d targetOnGround; - LLVector3 groundNorm; - LLViewerObject *obj; + setAutoPilotTargetGlobal(target_global); - LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); - F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); - - // clamp z value of target to minimum height above ground - mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; - mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal); if (target_rotation) { mAutoPilotUseRotation = TRUE; @@ -1294,13 +1286,37 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s } +//----------------------------------------------------------------------------- +// setAutoPilotTargetGlobal +//----------------------------------------------------------------------------- +void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) +{ + if (mAutoPilot) + { + mAutoPilotTargetGlobal = target_global; + + // trace ray down to find height of destination from ground + LLVector3d traceEndPt = target_global; + traceEndPt.mdV[VZ] -= 20.f; + + LLVector3d targetOnGround; + LLVector3 groundNorm; + LLViewerObject *obj; + + LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj); + F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]); + + // clamp z value of target to minimum height above ground + mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height; + mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal); + } +} + //----------------------------------------------------------------------------- // startFollowPilot() //----------------------------------------------------------------------------- void LLAgent::startFollowPilot(const LLUUID &leader_id) { - if (!mAutoPilot) return; - mLeaderID = leader_id; if ( mLeaderID.isNull() ) return; @@ -1338,6 +1354,7 @@ void LLAgent::stopAutoPilot(BOOL user_cancel) if (mAutoPilotFinishedCallback) { mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); + mAutoPilotFinishedCallback = NULL; } mLeaderID = LLUUID::null; -- cgit v1.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/llagent.cpp | 21 ++++++++++--- indra/newview/llagent.h | 4 ++- indra/newview/llagentlistener.cpp | 66 ++++++++++++++++++++++++--------------- 3 files changed, 60 insertions(+), 31 deletions(-) (limited to 'indra/newview/llagent.cpp') diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 9025982310..75acd1a0be 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -198,6 +198,7 @@ LLAgent::LLAgent() : mAutoPilot(FALSE), mAutoPilotFlyOnStop(FALSE), + mAutoPilotAllowFlying(TRUE), mAutoPilotTargetGlobal(), mAutoPilotStopDistance(1.f), mAutoPilotUseRotation(FALSE), @@ -1207,7 +1208,7 @@ BOOL LLAgent::getBusy() const //----------------------------------------------------------------------------- // startAutoPilotGlobal() //----------------------------------------------------------------------------- -void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *), void *callback_data, F32 stop_distance, F32 rot_threshold) +void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *), void *callback_data, F32 stop_distance, F32 rot_threshold, BOOL allow_flying) { if (!isAgentAvatarValid()) { @@ -1224,6 +1225,7 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s mAutoPilotCallbackData = callback_data; mAutoPilotRotationThreshold = rot_threshold; mAutoPilotBehaviorName = behavior_name; + mAutoPilotAllowFlying = allow_flying; LLVector3d delta_pos( target_global ); delta_pos -= getPositionGlobal(); @@ -1251,14 +1253,23 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s } } - mAutoPilotFlyOnStop = getFlying(); + if (mAutoPilotAllowFlying) + { + mAutoPilotFlyOnStop = getFlying(); + } + else + { + mAutoPilotFlyOnStop = FALSE; + } - if (distance > 30.0) + if (distance > 30.0 && mAutoPilotAllowFlying) { setFlying(TRUE); } - if ( distance > 1.f && heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f)) + if ( distance > 1.f && + mAutoPilotAllowFlying && + heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f)) { setFlying(TRUE); // Do not force flying for "Sit" behavior to prevent flying after pressing "Stand" @@ -1394,7 +1405,7 @@ void LLAgent::autoPilot(F32 *delta_yaw) if (!isAgentAvatarValid()) return; - if (gAgentAvatarp->mInAir) + if (gAgentAvatarp->mInAir && mAutoPilotAllowFlying) { setFlying(TRUE); } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 0fc77bd3a1..a45f55f27a 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -479,7 +479,8 @@ public: const std::string& behavior_name = std::string(), const LLQuaternion *target_rotation = NULL, void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL, - F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f); + F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f, + BOOL allow_flying = TRUE); void startFollowPilot(const LLUUID &leader_id); void stopAutoPilot(BOOL user_cancel = FALSE); void setAutoPilotTargetGlobal(const LLVector3d &target_global); @@ -488,6 +489,7 @@ public: private: BOOL mAutoPilot; BOOL mAutoPilotFlyOnStop; + BOOL mAutoPilotAllowFlying; LLVector3d mAutoPilotTargetGlobal; F32 mAutoPilotStopDistance; BOOL mAutoPilotUseRotation; 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.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/llagent.cpp | 11 +++- indra/newview/llagent.h | 2 +- indra/newview/llagentlistener.cpp | 109 ++++++++++++++++++++++++++++++++++---- indra/newview/llagentlistener.h | 7 +-- 4 files changed, 113 insertions(+), 16 deletions(-) (limited to 'indra/newview/llagent.cpp') diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 75acd1a0be..fd5cee2772 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1326,7 +1326,7 @@ void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global) //----------------------------------------------------------------------------- // startFollowPilot() //----------------------------------------------------------------------------- -void LLAgent::startFollowPilot(const LLUUID &leader_id) +void LLAgent::startFollowPilot(const LLUUID &leader_id, BOOL allow_flying, F32 stop_distance) { mLeaderID = leader_id; if ( mLeaderID.isNull() ) return; @@ -1338,7 +1338,14 @@ void LLAgent::startFollowPilot(const LLUUID &leader_id) return; } - startAutoPilotGlobal(object->getPositionGlobal()); + startAutoPilotGlobal(object->getPositionGlobal(), + std::string(), // behavior_name + NULL, // target_rotation + NULL, // finish_callback + NULL, // callback_data + stop_distance, + 0.03f, // rotation_threshold + allow_flying); } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index a45f55f27a..33c05816e2 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -481,7 +481,7 @@ public: void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL, F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f, BOOL allow_flying = TRUE); - void startFollowPilot(const LLUUID &leader_id); + void startFollowPilot(const LLUUID &leader_id, BOOL allow_flying = TRUE, F32 stop_distance = 0.5f); void stopAutoPilot(BOOL user_cancel = FALSE); void setAutoPilotTargetGlobal(const LLVector3d &target_global); void autoPilot(F32 *delta_yaw); // Autopilot walking action, angles in radians 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); } diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 40225c9c63..aadb87db12 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -47,14 +47,15 @@ private: void resetAxes(const LLSD& event) const; void getAxes(const LLSD& event) const; void getPosition(const LLSD& event) const; - void startAutoPilot(const LLSD& event) const; + void startAutoPilot(const LLSD& event); void getAutoPilot(const LLSD& event) const; - void startFollowPilot(const LLSD& event) const; + void startFollowPilot(const LLSD& event); void setAutoPilotTarget(const LLSD& event) const; void stopAutoPilot(const LLSD& event) const; private: - LLAgent & mAgent; + LLAgent & mAgent; + LLUUID mFollowTarget; }; #endif // LL_LLAGENTLISTENER_H -- cgit v1.3