summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llmessage/llcurl.cpp62
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl6
-rw-r--r--indra/newview/llmeshrepository.cpp8
-rw-r--r--indra/newview/llmeshrepository.h2
-rw-r--r--indra/newview/llspatialpartition.cpp25
-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
10 files changed, 370 insertions, 84 deletions
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 708745239e..66f1ffd41b 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -85,6 +85,22 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
std::string LLCurl::sCAPath;
std::string LLCurl::sCAFile;
+void check_curl_code(CURLcode code)
+{
+ if (code != CURLE_OK)
+ {
+ llerrs << "curl error detected: " << curl_easy_strerror(code) << llendl;
+ }
+}
+
+void check_curl_multi_code(CURLMcode code)
+{
+ if (code != CURLM_OK)
+ {
+ llerrs << "curl multi error detected: " << curl_multi_strerror(code) << llendl;
+ }
+}
+
//static
void LLCurl::setCAPath(const std::string& path)
{
@@ -333,8 +349,9 @@ LLCurl::Easy* LLCurl::Easy::getEasy()
// set no DNS caching as default for all easy handles. This prevents them adopting a
// multi handles cache if they are added to one.
- curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
-
+ CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
+ check_curl_code(result);
+
++gCurlEasyCount;
return easy;
}
@@ -400,9 +417,9 @@ void LLCurl::Easy::setHeaders()
void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info)
{
- curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload);
- curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime);
- curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload);
+ check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload));
+ check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime));
+ check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload));
}
U32 LLCurl::Easy::report(CURLcode code)
@@ -412,7 +429,7 @@ U32 LLCurl::Easy::report(CURLcode code)
if (code == CURLE_OK)
{
- curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode);
+ check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode));
//*TODO: get reason from first line of mHeaderOutput
}
else
@@ -435,17 +452,20 @@ U32 LLCurl::Easy::report(CURLcode code)
// Note: these all assume the caller tracks the value (i.e. keeps it persistant)
void LLCurl::Easy::setopt(CURLoption option, S32 value)
{
- curl_easy_setopt(mCurlEasyHandle, option, value);
+ CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value);
+ check_curl_code(result);
}
void LLCurl::Easy::setopt(CURLoption option, void* value)
{
- curl_easy_setopt(mCurlEasyHandle, option, value);
+ CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value);
+ check_curl_code(result);
}
void LLCurl::Easy::setopt(CURLoption option, char* value)
{
- curl_easy_setopt(mCurlEasyHandle, option, value);
+ CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value);
+ check_curl_code(result);
}
// Note: this copies the string so that the caller does not have to keep it around
@@ -454,7 +474,8 @@ void LLCurl::Easy::setoptString(CURLoption option, const std::string& value)
char* tstring = new char[value.length()+1];
strcpy(tstring, value.c_str());
mStrings.push_back(tstring);
- curl_easy_setopt(mCurlEasyHandle, option, tstring);
+ CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, tstring);
+ check_curl_code(result);
}
void LLCurl::Easy::slist_append(const char* str)
@@ -593,12 +614,12 @@ LLCurl::Multi::Multi()
mErrorCount(0)
{
mCurlMultiHandle = curl_multi_init();
-
if (!mCurlMultiHandle)
{
llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
mCurlMultiHandle = curl_multi_init();
}
+
llassert_always(mCurlMultiHandle);
++gCurlMultiCount;
}
@@ -610,7 +631,7 @@ LLCurl::Multi::~Multi()
iter != mEasyActiveList.end(); ++iter)
{
Easy* easy = *iter;
- curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle());
+ check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
delete easy;
}
mEasyActiveList.clear();
@@ -620,7 +641,7 @@ LLCurl::Multi::~Multi()
for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
mEasyFreeList.clear();
- curl_multi_cleanup(mCurlMultiHandle);
+ check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
--gCurlMultiCount;
}
@@ -641,8 +662,10 @@ S32 LLCurl::Multi::perform()
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
{
+ check_curl_multi_code(code);
break;
}
+
}
mQueued = q;
return q;
@@ -709,11 +732,12 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()
bool LLCurl::Multi::addEasy(Easy* easy)
{
CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle());
- if (mcode != CURLM_OK)
- {
- llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl;
- return false;
- }
+ check_curl_multi_code(mcode);
+ //if (mcode != CURLM_OK)
+ //{
+ // llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl;
+ // return false;
+ //}
return true;
}
@@ -734,7 +758,7 @@ void LLCurl::Multi::easyFree(Easy* easy)
void LLCurl::Multi::removeEasy(Easy* easy)
{
- curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle());
+ check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
easyFree(easy);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
index 1626e21cd8..5ae41cb730 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file diffuseSkinnedV.glsl
+ * @file attachmentShadowV.glsl
*
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
* $License$
@@ -21,5 +21,7 @@ void main()
gl_FrontColor = gl_Color;
- gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0);
+ vec4 p = gl_ProjectionMatrix * vec4(pos, 1.0);
+ p.z = max(p.z, -p.w+0.01);
+ gl_Position = p;
}
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 72019d8de8..1885b48812 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -645,7 +645,7 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id)
if (gAgent.getRegion())
{
- http_url = gAgent.getRegion()->getCapability("GetMesh");
+ http_url = gMeshRepo.mGetMeshCapability;
scrub_host_name(http_url, gAgent.getRegionHost());
}
@@ -2275,6 +2275,12 @@ void LLMeshRepository::notifyLoadedMeshes()
return;
}
+ if (gAgent.getRegion())
+ { //update capability url
+ //TODO: only do this when region changes
+ mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh");
+ }
+
LLFastTimer t(FTM_MESH_UPDATE);
{
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 427bcb8a75..df00c6c7aa 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -526,6 +526,8 @@ public:
void uploadError(LLSD& args);
void updateInventory(inventory_data data);
+ std::string mGetMeshCapability;
+
};
extern LLMeshRepository gMeshRepo;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index e763f92fab..c23756611d 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3195,6 +3195,31 @@ void renderPhysicsShapes(LLSpatialGroup* group)
renderPhysicsShape(drawable, volume);
}
}
+ else
+ {
+ LLViewerObject* object = drawable->getVObj();
+ if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+ {
+ //push face vertices for terrain
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ LLFace* face = drawable->getFace(i);
+ LLVertexBuffer* buff = face->mVertexBuffer;
+ if (buff)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glColor3f(0.2f, 0.5f, 0.3f);
+ buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0);
+
+ glColor3f(0.2f, 1.f, 0.3f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0);
+ }
+ }
+ }
+ }
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 870dd74fc5..9dc3cb9ce1 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -238,6 +238,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)
@@ -5186,6 +5187,7 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state)
void LLViewerObject::setPhysicsShapeType(U8 type)
{
+ mPhysicsShapeUnknown = false;
mPhysicsShapeType = type;
}
@@ -5209,6 +5211,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 bd0d831d91..59510bff1a 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 2caf984f94..0b64b204ee 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 22a17d5b7e..6deaca3819 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1383,6 +1383,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");