summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2011-03-15 04:19:16 +0000
committerDon Kjer <don@lindenlab.com>2011-03-15 04:19:16 +0000
commitbc0833d5db9e887f72ea6e7a630781203ad6ad77 (patch)
treebd2eea5d4dc8020296cf7cd5324c4127bba7b901 /indra/newview
parent6258f8d2e263e586b58d655bb32804f9079ace1d (diff)
ER-612: Add LLEventAPI access to LLAgent auto pilot
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llagent.cpp51
-rw-r--r--indra/newview/llagent.h10
-rw-r--r--indra/newview/llagentlistener.cpp183
-rw-r--r--indra/newview/llagentlistener.h21
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