diff options
author | Don Kjer <don@lindenlab.com> | 2011-03-15 04:19:16 +0000 |
---|---|---|
committer | Don Kjer <don@lindenlab.com> | 2011-03-15 04:19:16 +0000 |
commit | bc0833d5db9e887f72ea6e7a630781203ad6ad77 (patch) | |
tree | bd2eea5d4dc8020296cf7cd5324c4127bba7b901 /indra/newview | |
parent | 6258f8d2e263e586b58d655bb32804f9079ace1d (diff) |
ER-612: Add LLEventAPI access to LLAgent auto pilot
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llagent.cpp | 51 | ||||
-rw-r--r-- | indra/newview/llagent.h | 10 | ||||
-rw-r--r-- | indra/newview/llagentlistener.cpp | 183 | ||||
-rw-r--r-- | indra/newview/llagentlistener.h | 21 |
4 files changed, 191 insertions, 74 deletions
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; @@ -1295,12 +1287,36 @@ 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; diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 896408c0dd..0fc77bd3a1 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -467,6 +467,14 @@ public: public: BOOL getAutoPilot() const { return mAutoPilot; } LLVector3d getAutoPilotTargetGlobal() const { return mAutoPilotTargetGlobal; } + LLUUID getAutoPilotLeaderID() const { return mLeaderID; } + F32 getAutoPilotStopDistance() const { return mAutoPilotStopDistance; } + F32 getAutoPilotTargetDist() const { return mAutoPilotTargetDist; } + BOOL getAutoPilotUseRotation() const { return mAutoPilotUseRotation; } + LLVector3 getAutoPilotTargetFacing() const { return mAutoPilotTargetFacing; } + F32 getAutoPilotRotationThreshold() const { return mAutoPilotRotationThreshold; } + std::string getAutoPilotBehaviorName() const { return mAutoPilotBehaviorName; } + void startAutoPilotGlobal(const LLVector3d &pos_global, const std::string& behavior_name = std::string(), const LLQuaternion *target_rotation = NULL, @@ -474,7 +482,7 @@ public: F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f); void startFollowPilot(const LLUUID &leader_id); void stopAutoPilot(BOOL user_cancel = FALSE); - void setAutoPilotGlobal(const LLVector3d &pos_global); + void setAutoPilotTargetGlobal(const LLVector3d &target_global); void autoPilot(F32 *delta_yaw); // Autopilot walking action, angles in radians void renderAutoPilotTarget(); private: 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"]); +} + diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 6f087fc3da..40225c9c63 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -38,18 +38,23 @@ class LLSD; class LLAgentListener : public LLEventAPI { public: - LLAgentListener(LLAgent &agent); + LLAgentListener(LLAgent &agent); private: - void requestTeleport(LLSD const & event_data) const; - void requestSit(LLSD const & event_data) const; - void requestStand(LLSD const & event_data) const; - void resetAxes(const LLSD& event) const; - void getAxes(const LLSD& event) const; - void getPosition(const LLSD& event) const; + void requestTeleport(LLSD const & event_data) const; + void requestSit(LLSD const & event_data) const; + void requestStand(LLSD const & event_data) const; + 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 getAutoPilot(const LLSD& event) const; + void startFollowPilot(const LLSD& event) const; + void setAutoPilotTarget(const LLSD& event) const; + void stopAutoPilot(const LLSD& event) const; private: - LLAgent & mAgent; + LLAgent & mAgent; }; #endif // LL_LLAGENTLISTENER_H |