summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-10-19 23:19:55 -0500
committerDave Parks <davep@lindenlab.com>2010-10-19 23:19:55 -0500
commit30b44b238ba6ff8ff6dc29161f3ff6ee85a27f06 (patch)
treead0894cb9e503872b688271006cb94e9a077a07c
parent94c1670934bc3a00e45823784cb8c25dea7908f0 (diff)
First stab at using GetObjectPhysicsData
-rw-r--r--indra/newview/llviewerobject.cpp13
-rw-r--r--indra/newview/llviewerobject.h3
-rw-r--r--indra/newview/llviewerobjectlist.cpp314
-rw-r--r--indra/newview/llviewerobjectlist.h20
-rw-r--r--indra/newview/llviewerregion.cpp1
5 files changed, 289 insertions, 62 deletions
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index ee8e2cebbf..e0b56767cd 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -237,6 +237,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mPhysicsCost(0.f),
mLinksetPhysicsCost(0.f),
mCostStale(true),
+ mPhysicsShapeUnknown(true),
mAttachmentItemID(LLUUID::null)
{
if (!is_global)
@@ -5185,6 +5186,7 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
void LLViewerObject::setPhysicsShapeType(U8 type)
{
+ mPhysicsShapeUnknown = false;
mPhysicsShapeType = type;
}
@@ -5208,6 +5210,17 @@ void LLViewerObject::setPhysicsRestitution(F32 restitution)
mPhysicsRestitution = restitution;
}
+U8 LLViewerObject::getPhysicsShapeType() const
+{
+ if (mPhysicsShapeUnknown)
+ {
+ mPhysicsShapeUnknown = false;
+ gObjectList.updatePhysicsFlags(this);
+ }
+
+ return mPhysicsShapeType;
+}
+
void LLViewerObject::applyAngularVelocity(F32 dt)
{
//do target omega here
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index d622d37ee8..1109386cbe 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -470,7 +470,7 @@ public:
inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); }
inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); }
- inline U8 getPhysicsShapeType() const { return mPhysicsShapeType; }
+ U8 getPhysicsShapeType() const;
inline F32 getPhysicsGravity() const { return mPhysicsGravity; }
inline F32 getPhysicsFriction() const { return mPhysicsFriction; }
inline F32 getPhysicsDensity() const { return mPhysicsDensity; }
@@ -703,6 +703,7 @@ protected:
F32 mLinksetPhysicsCost;
bool mCostStale;
+ mutable bool mPhysicsShapeUnknown;
static U32 sNumZombieObjects; // Objects which are dead, but not deleted
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 87df037662..c1d179fa40 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -675,7 +675,7 @@ public:
void error(U32 statusNum, const std::string& reason)
{
- lldebugs
+ llwarns
<< "Transport error requesting object cost "
<< "HTTP status: " << statusNum << ", reason: "
<< reason << "." << llendl;
@@ -691,7 +691,7 @@ public:
{
// Improper response or the request had an error,
// show an error to the user?
- lldebugs
+ llwarns
<< "Application level error when fetching object "
<< "cost. Message: " << content["error"]["message"].asString()
<< ", identifier: " << content["error"]["identifier"].asString()
@@ -739,6 +739,102 @@ private:
LLSD mObjectIDs;
};
+
+class LLPhysicsFlagsResponder : public LLCurl::Responder
+{
+public:
+ LLPhysicsFlagsResponder(const LLSD& object_ids)
+ : mObjectIDs(object_ids)
+ {
+ }
+
+ // Clear's the global object list's pending
+ // request list for all objects requested
+ void clear_object_list_pending_requests()
+ {
+ // TODO*: No more hard coding
+ for (
+ LLSD::array_iterator iter = mObjectIDs.beginArray();
+ iter != mObjectIDs.endArray();
+ ++iter)
+ {
+ gObjectList.onPhysicsFlagsFetchFailure(iter->asUUID());
+ }
+ }
+
+ void error(U32 statusNum, const std::string& reason)
+ {
+ llwarns
+ << "Transport error requesting object physics flags "
+ << "HTTP status: " << statusNum << ", reason: "
+ << reason << "." << llendl;
+
+ // TODO*: Error message to user
+ // For now just clear the request from the pending list
+ clear_object_list_pending_requests();
+ }
+
+ void result(const LLSD& content)
+ {
+ if ( !content.isMap() || content.has("error") )
+ {
+ // Improper response or the request had an error,
+ // show an error to the user?
+ llwarns
+ << "Application level error when fetching object "
+ << "physics flags. Message: " << content["error"]["message"].asString()
+ << ", identifier: " << content["error"]["identifier"].asString()
+ << llendl;
+
+ // TODO*: Adaptively adjust request size if the
+ // service says we've requested too many and retry
+
+ // TODO*: Error message if not retrying
+ clear_object_list_pending_requests();
+ return;
+ }
+
+ // Success, grab the resource cost and linked set costs
+ // for an object if one was returned
+ for (
+ LLSD::array_iterator iter = mObjectIDs.beginArray();
+ iter != mObjectIDs.endArray();
+ ++iter)
+ {
+ LLUUID object_id = iter->asUUID();
+
+ // Check to see if the request contains data for the object
+ if ( content.has(iter->asString()) )
+ {
+ const LLSD& data = content[iter->asString()];
+
+ S32 shape_type = data["PhysicsShapeType"].asInteger();
+
+ gObjectList.updatePhysicsShapeType(object_id, shape_type);
+
+ if (data.has("Density"))
+ {
+ F32 density = data["Density"].asReal();
+ F32 friction = data["Friction"].asReal();
+ F32 restitution = data["Restitution"].asReal();
+ F32 gravity_multiplier = data["GravityMultiplier"].asReal();
+
+ gObjectList.updatePhysicsProperties(object_id,
+ density, friction, restitution, gravity_multiplier);
+ }
+ }
+ else
+ {
+ // TODO*: Give user feedback about the missing data?
+ gObjectList.onPhysicsFlagsFetchFailure(object_id);
+ }
+ }
+ }
+
+private:
+ LLSD mObjectIDs;
+};
+
void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
{
LLMemType mt(LLMemType::MTYPE_OBJECT);
@@ -835,61 +931,8 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
}
}
- // issue http request for stale object physics costs
- if (!mStaleObjectCost.empty())
- {
- LLViewerRegion* regionp = gAgent.getRegion();
-
- if (regionp)
- {
- std::string url = regionp->getCapability("GetObjectCost");
-
- if (!url.empty())
- {
- LLSD id_list;
- U32 object_index = 0;
-
- for (
- std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
- iter != mStaleObjectCost.end();
- ++iter)
- {
- // Check to see if a request for this object
- // has already been made.
- if ( mPendingObjectCost.find(*iter) ==
- mPendingObjectCost.end() )
- {
- // Why is this line here if
- // we set mPendingObjectCost to be
- // mStaleObjectCost below?
- mPendingObjectCost.insert(*iter);
- id_list[object_index++] = *iter;
- }
- }
-
- // id_list should now contain all
- // requests in mStaleObjectCost before, so clear
- // it now
- mStaleObjectCost.clear();
-
- if ( id_list.size() > 0 )
- {
- LLSD post_data = LLSD::emptyMap();
-
- post_data["object_ids"] = id_list;
- LLHTTPClient::post(
- url,
- post_data,
- new LLObjectCostResponder(id_list));
- }
- }
- else
- {
- mStaleObjectCost.clear();
- mPendingObjectCost.clear();
- }
- }
- }
+ fetchObjectCosts();
+ fetchPhysicsFlags();
mNumSizeCulled = 0;
mNumVisCulled = 0;
@@ -956,6 +999,119 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
}
+void LLViewerObjectList::fetchObjectCosts()
+{
+ // issue http request for stale object physics costs
+ if (!mStaleObjectCost.empty())
+ {
+ LLViewerRegion* regionp = gAgent.getRegion();
+
+ if (regionp)
+ {
+ std::string url = regionp->getCapability("GetObjectCost");
+
+ if (!url.empty())
+ {
+ LLSD id_list;
+ U32 object_index = 0;
+
+ for (
+ std::set<LLUUID>::iterator iter = mStaleObjectCost.begin();
+ iter != mStaleObjectCost.end();
+ ++iter)
+ {
+ // Check to see if a request for this object
+ // has already been made.
+ if ( mPendingObjectCost.find(*iter) ==
+ mPendingObjectCost.end() )
+ {
+ mPendingObjectCost.insert(*iter);
+ id_list[object_index++] = *iter;
+ }
+ }
+
+ // id_list should now contain all
+ // requests in mStaleObjectCost before, so clear
+ // it now
+ mStaleObjectCost.clear();
+
+ if ( id_list.size() > 0 )
+ {
+ LLSD post_data = LLSD::emptyMap();
+
+ post_data["object_ids"] = id_list;
+ LLHTTPClient::post(
+ url,
+ post_data,
+ new LLObjectCostResponder(id_list));
+ }
+ }
+ else
+ {
+ mStaleObjectCost.clear();
+ mPendingObjectCost.clear();
+ }
+ }
+ }
+}
+
+void LLViewerObjectList::fetchPhysicsFlags()
+{
+ // issue http request for stale object physics flags
+ if (!mStalePhysicsFlags.empty())
+ {
+ LLViewerRegion* regionp = gAgent.getRegion();
+
+ if (regionp)
+ {
+ std::string url = regionp->getCapability("GetObjectPhysicsData");
+
+ if (!url.empty())
+ {
+ LLSD id_list;
+ U32 object_index = 0;
+
+ for (
+ std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin();
+ iter != mStalePhysicsFlags.end();
+ ++iter)
+ {
+ // Check to see if a request for this object
+ // has already been made.
+ if ( mPendingPhysicsFlags.find(*iter) ==
+ mPendingPhysicsFlags.end() )
+ {
+ mPendingPhysicsFlags.insert(*iter);
+ id_list[object_index++] = *iter;
+ }
+ }
+
+ // id_list should now contain all
+ // requests in mStalePhysicsFlags before, so clear
+ // it now
+ mStalePhysicsFlags.clear();
+
+ if ( id_list.size() > 0 )
+ {
+ LLSD post_data = LLSD::emptyMap();
+
+ post_data["object_ids"] = id_list;
+ LLHTTPClient::post(
+ url,
+ post_data,
+ new LLPhysicsFlagsResponder(id_list));
+ }
+ }
+ else
+ {
+ mStalePhysicsFlags.clear();
+ mPendingPhysicsFlags.clear();
+ }
+ }
+ }
+}
+
+
void LLViewerObjectList::clearDebugText()
{
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
@@ -1184,7 +1340,7 @@ void LLViewerObjectList::updateObjectCost(LLViewerObject* object)
mStaleObjectCost.insert(object->getID());
}
-void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost)
+void LLViewerObjectList::updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost)
{
mPendingObjectCost.erase(object_id);
@@ -1198,11 +1354,51 @@ void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 object_cost, F32
}
}
-void LLViewerObjectList::onObjectCostFetchFailure(LLUUID object_id)
+void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)
{
+ llwarns << "Failed to fetch object cost for object: " << object_id << llendl;
mPendingObjectCost.erase(object_id);
}
+void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object)
+{
+ mStalePhysicsFlags.insert(object->getID());
+}
+
+void LLViewerObjectList::updatePhysicsShapeType(const LLUUID& object_id, S32 type)
+{
+ mPendingPhysicsFlags.erase(object_id);
+ LLViewerObject* object = findObject(object_id);
+ if (object)
+ {
+ object->setPhysicsShapeType(type);
+ }
+}
+
+void LLViewerObjectList::updatePhysicsProperties(const LLUUID& object_id,
+ F32 density,
+ F32 friction,
+ F32 restitution,
+ F32 gravity_multiplier)
+{
+ mPendingPhysicsFlags.erase(object_id);
+
+ LLViewerObject* object = findObject(object_id);
+ if (object)
+ {
+ object->setPhysicsDensity(density);
+ object->setPhysicsFriction(friction);
+ object->setPhysicsGravity(gravity_multiplier);
+ object->setPhysicsRestitution(restitution);
+ }
+}
+
+void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id)
+{
+ llwarns << "Failed to fetch physics flags for object: " << object_id << llendl;
+ mPendingPhysicsFlags.erase(object_id);
+}
+
void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
{
// This is called when we shift our origin when we cross region boundaries...
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 2881ba6f8f..64034091d3 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -85,9 +85,21 @@ public:
void updateApparentAngles(LLAgent &agent);
void update(LLAgent &agent, LLWorld &world);
+ void fetchObjectCosts();
+ void fetchPhysicsFlags();
+
void updateObjectCost(LLViewerObject* object);
- void updateObjectCost(LLUUID object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost);
- void onObjectCostFetchFailure(LLUUID object_id);
+ void updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost);
+ void onObjectCostFetchFailure(const LLUUID& object_id);
+
+ void updatePhysicsFlags(const LLViewerObject* object);
+ void onPhysicsFlagsFetchFailure(const LLUUID& object_id);
+ void updatePhysicsShapeType(const LLUUID& object_id, S32 type);
+ void updatePhysicsProperties(const LLUUID& object_id,
+ F32 density,
+ F32 friction,
+ F32 restitution,
+ F32 gravity_multiplier);
void shiftObjects(const LLVector3 &offset);
@@ -194,6 +206,10 @@ protected:
std::set<LLUUID> mStaleObjectCost;
std::set<LLUUID> mPendingObjectCost;
+ //set of objects that need to update their physics flags
+ std::set<LLUUID> mStalePhysicsFlags;
+ std::set<LLUUID> mPendingPhysicsFlags;
+
std::vector<LLDebugBeacon> mDebugBeacons;
S32 mCurLazyUpdateIndex;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 45690c0b8e..f229f19a0b 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1376,6 +1376,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("GetTexture");
capabilityNames.append("GetMesh");
capabilityNames.append("GetObjectCost");
+ capabilityNames.append("GetObjectPhysicsData");
capabilityNames.append("GroupProposalBallot");
capabilityNames.append("HomeLocation");
capabilityNames.append("LandResources");