summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerobjectlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerobjectlist.cpp')
-rw-r--r--indra/newview/llviewerobjectlist.cpp361
1 files changed, 278 insertions, 83 deletions
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index e6f1d8e728..0b64b204ee 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -2,31 +2,25 @@
* @file llviewerobjectlist.cpp
* @brief Implementation of LLViewerObjectList class.
*
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -53,7 +47,7 @@
#include "lltooltip.h"
#include "llworld.h"
#include "llstring.h"
-#include "llhudtext.h"
+#include "llhudnametag.h"
#include "lldrawable.h"
#include "xform.h"
#include "llsky.h"
@@ -681,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;
@@ -697,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()
@@ -728,7 +722,10 @@ public:
F32 object_cost =
content[iter->asString()]["resource_cost"].asReal();
- gObjectList.updateObjectCost(object_id, object_cost, link_cost);
+ F32 physics_cost = content[iter->asString()]["physics_cost"].asReal();
+ F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal();
+
+ gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost);
}
else
{
@@ -742,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);
@@ -838,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;
@@ -959,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)
@@ -1187,7 +1340,7 @@ void LLViewerObjectList::updateObjectCost(LLViewerObject* object)
mStaleObjectCost.insert(object->getID());
}
-void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 object_cost, F32 link_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);
@@ -1196,14 +1349,56 @@ void LLViewerObjectList::updateObjectCost(LLUUID object_id, F32 object_cost, F32
{
object->setObjectCost(object_cost);
object->setLinksetCost(link_cost);
+ object->setPhysicsCost(physics_cost);
+ object->setLinksetPhysicsCost(link_physics_cost);
}
}
-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...
@@ -1366,7 +1561,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
}
}
- LLHUDText::addPickable(mSelectPickList);
+ LLHUDNameTag::addPickable(mSelectPickList);
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)