diff options
author | Dave Parks <davep@lindenlab.com> | 2010-10-19 23:19:55 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2010-10-19 23:19:55 -0500 |
commit | 30b44b238ba6ff8ff6dc29161f3ff6ee85a27f06 (patch) | |
tree | ad0894cb9e503872b688271006cb94e9a077a07c /indra | |
parent | 94c1670934bc3a00e45823784cb8c25dea7908f0 (diff) |
First stab at using GetObjectPhysicsData
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llviewerobject.cpp | 13 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 3 | ||||
-rw-r--r-- | indra/newview/llviewerobjectlist.cpp | 314 | ||||
-rw-r--r-- | indra/newview/llviewerobjectlist.h | 20 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 1 |
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"); |