summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llagentwearables.cpp15
-rw-r--r--indra/newview/llagentwearablesfetch.cpp2
-rw-r--r--indra/newview/llappearancemgr.cpp127
-rw-r--r--indra/newview/llappearancemgr.h8
-rw-r--r--indra/newview/llfloatergroups.cpp31
-rw-r--r--indra/newview/llinventorybridge.cpp46
-rw-r--r--indra/newview/llsidepanelappearance.cpp6
-rw-r--r--indra/newview/llviewerjointattachment.cpp37
-rw-r--r--indra/newview/llviewermenu.cpp98
-rw-r--r--indra/newview/llviewerobject.cpp25
-rw-r--r--indra/newview/llviewerobject.h10
-rw-r--r--indra/newview/llviewertexture.cpp13
-rw-r--r--indra/newview/llvoavatar.cpp236
-rw-r--r--indra/newview/llvoavatarself.cpp79
-rw-r--r--indra/newview/llvoavatarself.h8
15 files changed, 455 insertions, 286 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 337878cf96..25456f7e26 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -388,9 +388,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
const std::string new_name)
{
LLWearable* old_wearable = getWearable(type, index);
- if(!old_wearable) return;
- bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());
- if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion())
+ if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()))
{
LLUUID old_item_id = old_wearable->getItemID();
LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
@@ -406,10 +404,12 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
if (item)
{
std::string item_name = item->getName();
- if (name_changed)
+ bool name_changed = false;
+ if (!new_name.empty() && (new_name != item->getName()))
{
llinfos << "saveWearable changing name from " << item->getName() << " to " << new_name << llendl;
item_name = new_name;
+ name_changed = true;
}
// Update existing inventory item
LLPointer<LLViewerInventoryItem> template_item =
@@ -1756,7 +1756,7 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
LLViewerObject *objectp = (*attachment_iter);
if (objectp)
{
- LLUUID object_item_id = objectp->getItemID();
+ LLUUID object_item_id = objectp->getAttachmentItemID();
if (requested_item_ids.find(object_item_id) != requested_item_ids.end())
{
// Object currently worn, was requested.
@@ -1885,7 +1885,10 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
msg->nextBlockFast(_PREHASH_ObjectData );
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
- msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
+ if (gSavedSettings.getBOOL("MultipleAttachments"))
+ msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD );
+ else
+ msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
msg->addStringFast(_PREHASH_Name, item->getName());
msg->addStringFast(_PREHASH_Description, item->getDescription());
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index d911d123f4..f6bb1b9bc9 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -215,7 +215,7 @@ void LLInitialWearablesFetch::processWearablesMessage()
{
LLViewerObject* attached_object = (*attachment_iter);
if (!attached_object) continue;
- const LLUUID& item_id = attached_object->getItemID();
+ const LLUUID& item_id = attached_object->getAttachmentItemID();
if (item_id.isNull()) continue;
ids.push_back(item_id);
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 6fdd71bfbf..3c3894d1f5 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1600,46 +1600,56 @@ void item_array_diff(LLInventoryModel::item_array_t& full_list,
}
}
-void LLAppearanceMgr::enforceItemCountLimits()
+S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,
+ LLAssetType::EType type,
+ S32 max_items,
+ LLInventoryModel::item_array_t& items_to_kill)
{
- S32 purge_count = 0;
-
- LLInventoryModel::item_array_t body_items;
- getDescendentsOfAssetType(getCOF(), body_items, LLAssetType::AT_BODYPART, false);
- LLInventoryModel::item_array_t curr_body_items = body_items;
- removeDuplicateItems(body_items);
- filterWearableItems(body_items, 1);
- LLInventoryModel::item_array_t kill_body_items;
- item_array_diff(curr_body_items,body_items,kill_body_items);
- for (LLInventoryModel::item_array_t::iterator it = kill_body_items.begin();
- it != kill_body_items.end();
- ++it)
+ S32 to_kill_count = 0;
+
+ LLInventoryModel::item_array_t items;
+ getDescendentsOfAssetType(cat_id, items, type, false);
+ LLInventoryModel::item_array_t curr_items = items;
+ removeDuplicateItems(items);
+ if (max_items > 0)
{
- LLViewerInventoryItem *item = *it;
- llinfos << "purging dup body part " << item->getName() << llendl;
- gInventory.purgeObject(item->getUUID());
- purge_count++;
+ filterWearableItems(items, max_items);
}
-
- LLInventoryModel::item_array_t wear_items;
- getDescendentsOfAssetType(getCOF(), wear_items, LLAssetType::AT_CLOTHING, false);
- LLInventoryModel::item_array_t curr_wear_items = wear_items;
- removeDuplicateItems(wear_items);
- filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_PER_TYPE);
- LLInventoryModel::item_array_t kill_wear_items;
- item_array_diff(curr_wear_items,wear_items,kill_wear_items);
- for (LLInventoryModel::item_array_t::iterator it = kill_wear_items.begin();
- it != kill_wear_items.end();
+ LLInventoryModel::item_array_t kill_items;
+ item_array_diff(curr_items,items,kill_items);
+ for (LLInventoryModel::item_array_t::iterator it = kill_items.begin();
+ it != kill_items.end();
++it)
{
- LLViewerInventoryItem *item = *it;
- llinfos << "purging excess clothing item " << item->getName() << llendl;
- gInventory.purgeObject(item->getUUID());
- purge_count++;
+ items_to_kill.push_back(*it);
+ to_kill_count++;
}
+ return to_kill_count;
+}
+
+
+void LLAppearanceMgr::enforceItemRestrictions()
+{
+ S32 purge_count = 0;
+ LLInventoryModel::item_array_t items_to_kill;
+
+ purge_count += findExcessOrDuplicateItems(getCOF(),LLAssetType::AT_BODYPART,
+ 1, items_to_kill);
+ purge_count += findExcessOrDuplicateItems(getCOF(),LLAssetType::AT_CLOTHING,
+ LLAgentWearables::MAX_CLOTHING_PER_TYPE, items_to_kill);
+ purge_count += findExcessOrDuplicateItems(getCOF(),LLAssetType::AT_OBJECT,
+ -1, items_to_kill);
- if (purge_count>0)
+ if (items_to_kill.size()>0)
{
+ for (LLInventoryModel::item_array_t::iterator it = items_to_kill.begin();
+ it != items_to_kill.end();
+ ++it)
+ {
+ LLViewerInventoryItem *item = *it;
+ llinfos << "purging duplicate or excess item " << item->getName() << llendl;
+ gInventory.purgeObject(item->getUUID());
+ }
gInventory.notifyObservers();
}
}
@@ -1662,7 +1672,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
// Remove duplicate or excess wearables. Should normally be enforced at the UI level, but
// this should catch anything that gets through.
- enforceItemCountLimits();
+ enforceItemRestrictions();
// update dirty flag to see if the state of the COF matches
// the saved outfit stored as a folder link
@@ -2496,29 +2506,17 @@ void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
switch (item_to_remove->getType())
{
- case LLAssetType::AT_CLOTHING:
- if (get_is_item_worn(id_to_remove))
- {
- //*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
- LLWearableBridge::removeItemFromAvatar(item_to_remove);
- }
- break;
- case LLAssetType::AT_OBJECT:
- gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_to_remove->getLinkedUUID());
- gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
-
- {
- // this object might have been selected, so let the selection manager know it's gone now
- LLViewerObject *found_obj = gObjectList.findObject(item_to_remove->getLinkedUUID());
- if (found_obj)
+ case LLAssetType::AT_CLOTHING:
+ if (get_is_item_worn(id_to_remove))
{
- LLSelectMgr::getInstance()->remove(found_obj);
- };
- }
- default: break;
+ //*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
+ LLWearableBridge::removeItemFromAvatar(item_to_remove);
+ }
+ break;
+ case LLAssetType::AT_OBJECT:
+ LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
+ default:
+ break;
}
// *HACK: Force to remove garbage from COF.
@@ -2658,7 +2656,6 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
mAttachmentInvLinkEnabled = val;
}
-// BAP TODO - mRegisteredAttachments is currently maintained but not used for anything. Consider yanking.
void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
{
llinfos << msg << llendl;
@@ -2678,7 +2675,6 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
{
- mRegisteredAttachments.insert(item_id);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
if (mAttachmentInvLinkEnabled)
@@ -2696,7 +2692,6 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
{
- mRegisteredAttachments.erase(item_id);
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
if (mAttachmentInvLinkEnabled)
@@ -2709,18 +2704,6 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
}
}
-void LLAppearanceMgr::linkRegisteredAttachments()
-{
- for (std::set<LLUUID>::iterator it = mRegisteredAttachments.begin();
- it != mRegisteredAttachments.end();
- ++it)
- {
- LLUUID item_id = *it;
- addCOFItemLink(item_id, false);
- }
- mRegisteredAttachments.clear();
-}
-
BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
{
return gInventory.isObjectDescendentOf(obj_id, getCOF());
@@ -2733,8 +2716,8 @@ bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id)
LLInventoryModel::item_array_t items;
LLLinkedItemIDMatches find_links(gInventory.getLinkedItemID(obj_id));
gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
- cats,
- items,
+ cats,
+ items,
LLInventoryModel::EXCLUDE_TRASH,
find_links);
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index eb495bd274..67c74e0343 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -66,7 +66,11 @@ public:
void renameOutfit(const LLUUID& outfit_id);
void takeOffOutfit(const LLUUID& cat_id);
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
- void enforceItemCountLimits();
+ S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
+ LLAssetType::EType type,
+ S32 max_items,
+ LLInventoryModel::item_array_t& items_to_kill);
+ void enforceItemRestrictions();
// Copy all items and the src category itself.
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
@@ -119,7 +123,6 @@ public:
void unregisterAttachment(const LLUUID& item_id);
void registerAttachment(const LLUUID& item_id);
void setAttachmentInvLinkEnable(bool val);
- void linkRegisteredAttachments();
// utility function for bulk linking.
void linkAll(const LLUUID& category,
@@ -206,7 +209,6 @@ private:
void setOutfitLocked(bool locked);
- std::set<LLUUID> mRegisteredAttachments;
bool mAttachmentInvLinkEnabled;
bool mOutfitIsDirty;
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 0bd8215e5c..307c937f6e 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -47,7 +47,6 @@
#include "llbutton.h"
#include "llgroupactions.h"
#include "llscrolllistctrl.h"
-#include "llselectmgr.h"
#include "lltextbox.h"
#include "lluictrlfactory.h"
#include "lltrans.h"
@@ -90,15 +89,13 @@ BOOL LLFloaterGroupPicker::postBuild()
list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP);
}
- LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterGroupPicker::onBtnCancel, this));
-
childSetAction("OK", onBtnOK, this);
childSetAction("Cancel", onBtnCancel, this);
setDefaultBtn("OK");
- getChildView("OK")->setEnabled(TRUE);
+ childEnable("OK");
return TRUE;
}
@@ -179,8 +176,8 @@ void LLPanelGroups::reset()
{
group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
}
- getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
- getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",MAX_AGENT_GROUPS));
+ childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
+ childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
enableButtons();
@@ -190,8 +187,8 @@ BOOL LLPanelGroups::postBuild()
{
childSetCommitCallback("group list", onGroupList, this);
- getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
- getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",MAX_AGENT_GROUPS));
+ childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
+ childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
LLScrollListCtrl *list = getChild<LLScrollListCtrl>("group list");
if (list)
@@ -231,25 +228,25 @@ void LLPanelGroups::enableButtons()
if(group_id != gAgent.getGroupID())
{
- getChildView("Activate")->setEnabled(TRUE);
+ childEnable("Activate");
}
else
{
- getChildView("Activate")->setEnabled(FALSE);
+ childDisable("Activate");
}
if (group_id.notNull())
{
- getChildView("Info")->setEnabled(TRUE);
- getChildView("IM")->setEnabled(TRUE);
- getChildView("Leave")->setEnabled(TRUE);
+ childEnable("Info");
+ childEnable("IM");
+ childEnable("Leave");
}
else
{
- getChildView("Info")->setEnabled(FALSE);
- getChildView("IM")->setEnabled(FALSE);
- getChildView("Leave")->setEnabled(FALSE);
+ childDisable("Info");
+ childDisable("IM");
+ childDisable("Leave");
}
- getChildView("Create")->setEnabled(gAgent.canJoinGroups());
+ childSetEnabled("Create", gAgent.canJoinGroups());
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 4e1274645f..cdabbf2ddc 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3963,18 +3963,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
LLInventoryItem* item = gInventory.getItem(mUUID);
if(item)
{
- gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
- gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
-
- // this object might have been selected, so let the selection manager know it's gone now
- LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID());
- if (found_obj)
- {
- LLSelectMgr::getInstance()->remove(found_obj);
- }
+ LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID());
}
}
else LLItemBridge::performAction(model, action);
@@ -4011,8 +4000,17 @@ std::string LLObjectBridge::getLabelSuffix() const
void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment)
{
- LLSD payload;
- payload["item_id"] = item->getLinkedUUID(); // Wear the base object in case this is a link.
+ const LLUUID& item_id = item->getLinkedUUID();
+
+ // Check for duplicate request.
+ if (isAgentAvatarValid() &&
+ (gAgentAvatarp->attachmentWasRequested(item_id) ||
+ gAgentAvatarp->isWearingAttachment(item_id)))
+ {
+ llwarns << "duplicate attachment request, ignoring" << llendl;
+ return;
+ }
+ gAgentAvatarp->addAttachmentRequest(item_id);
S32 attach_pt = 0;
if (isAgentAvatarValid() && attachment)
@@ -4028,6 +4026,8 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
}
}
+ LLSD payload;
+ payload["item_id"] = item_id; // Wear the base object in case this is a link.
payload["attachment_point"] = attach_pt;
if (!gSavedSettings.getBOOL("MultipleAttachments") &&
@@ -4054,11 +4054,13 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0/*YES*/)
{
- LLViewerInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+ LLUUID item_id = notification["payload"]["item_id"].asUUID();
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
if (itemp)
{
U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
+
if (gSavedSettings.getBOOL("MultipleAttachments"))
attachment_pt |= ATTACHMENT_ADD;
@@ -4327,19 +4329,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
LLViewerInventoryItem *obj_item = obj_item_array.get(i);
if (get_is_item_worn(obj_item->getUUID()))
{
- gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
- gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
- gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() );
-
- gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
-
- // this object might have been selected, so let the selection manager know it's gone now
- LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID());
- if (found_obj)
- {
- LLSelectMgr::getInstance()->remove(found_obj);
- }
+ LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
}
}
}
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index adfd457664..83329ebccf 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -473,7 +473,7 @@ void LLSidepanelAppearance::fetchInventory()
{
LLViewerObject* attached_object = (*attachment_iter);
if (!attached_object) continue;
- const LLUUID& item_id = attached_object->getItemID();
+ const LLUUID& item_id = attached_object->getAttachmentItemID();
if (item_id.isNull()) continue;
ids.push_back(item_id);
}
@@ -501,8 +501,8 @@ void LLSidepanelAppearance::inventoryFetched()
void LLSidepanelAppearance::setWearablesLoading(bool val)
{
- getChildView("wearables_loading_indicator")->setVisible( val);
- getChildView("edit_outfit_btn")->setVisible( !val);
+ childSetVisible("wearables_loading_indicator", val);
+ childSetVisible("edit_outfit_btn", !val);
if (!val)
{
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 2b4b78d82d..c9335366cd 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -35,12 +35,11 @@
#include "llviewerjointattachment.h"
#include "llagentconstants.h"
-
#include "llviewercontrol.h"
#include "lldrawable.h"
#include "llgl.h"
#include "llrender.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
#include "llvolume.h"
#include "pipeline.h"
#include "llspatialpartition.h"
@@ -164,6 +163,9 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
//-----------------------------------------------------------------------------
BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
{
+ object->extractAttachmentItemID();
+
+ // Same object reattached
if (isObjectAttached(object))
{
llinfos << "(same object re-attached)" << llendl;
@@ -171,20 +173,19 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
// Pass through anyway to let setupDrawable()
// re-connect object to the joint correctly
}
-
- // Find the inventory item ID of the attached object
- LLNameValue* item_id_nv = object->getNVPair("AttachItemID");
- if( item_id_nv )
+
+ // Two instances of the same inventory item attached --
+ // Request detach, and kill the object in the meantime.
+ if (getAttachedObject(object->getAttachmentItemID()))
{
- const char* s = item_id_nv->getString();
- if( s )
- {
- LLUUID item_id;
- item_id.set(s);
- object->setItemID(item_id);
- lldebugs << "getNVPair( AttachItemID ) = " << item_id << llendl;
- }
+ llinfos << "(same object re-attached)" << llendl;
+ object->markDead();
+
+ // If this happens to be attached to self, then detach.
+ LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
+ return FALSE;
}
+
mAttachedObjects.push_back(object);
setupDrawable(object);
@@ -207,7 +208,7 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
}
calcLOD();
mUpdateXform = TRUE;
-
+
return TRUE;
}
@@ -303,7 +304,7 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
{
mUpdateXform = FALSE;
}
- object->setItemID(LLUUID::null);
+ object->setAttachmentItemID(LLUUID::null);
}
//-----------------------------------------------------------------------------
@@ -429,7 +430,7 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o
++iter)
{
const LLViewerObject* attached_object = (*iter);
- if (attached_object->getItemID() == object_id)
+ if (attached_object->getAttachmentItemID() == object_id)
{
return attached_object;
}
@@ -444,7 +445,7 @@ LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_
++iter)
{
LLViewerObject* attached_object = (*iter);
- if (attached_object->getItemID() == object_id)
+ if (attached_object->getAttachmentItemID() == object_id)
{
return attached_object;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 40bf62acc9..e58f0c9aec 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1083,8 +1083,6 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
- LLPipeline::updateRenderDeferred();
- gPipeline.resetVertexBuffers();
return true;
}
};
@@ -2056,9 +2054,9 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t
};
/////////////////////////////////////
-// Enable Deferred Rendering sub-options
+// Enable Global Illumination ///
/////////////////////////////////////
-class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
+class LLAdvancedEnableRenderDeferredGI: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
@@ -5854,7 +5852,6 @@ void handle_buy_land()
class LLObjectAttachToAvatar : public view_listener_t
{
public:
- LLObjectAttachToAvatar(bool replace) : mReplace(replace) {}
static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
private:
@@ -5868,38 +5865,22 @@ private:
LLViewerJointAttachment* attachment_point = NULL;
if (index > 0)
attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL);
- confirmReplaceAttachment(0, attachment_point);
+ confirm_replace_attachment(0, attachment_point);
}
return true;
}
- static void onNearAttachObject(BOOL success, void *user_data);
- void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
-
- struct CallbackData
- {
- CallbackData(LLViewerJointAttachment* point, bool replace) : mAttachmentPoint(point), mReplace(replace) {}
-
- LLViewerJointAttachment* mAttachmentPoint;
- bool mReplace;
- };
-
protected:
static LLObjectSelectionHandle sObjectSelection;
- bool mReplace;
};
LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection;
-// static
-void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data)
+void near_attach_object(BOOL success, void *user_data)
{
- if (!user_data) return;
- CallbackData* cb_data = static_cast<CallbackData*>(user_data);
-
if (success)
{
- const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint;
+ const LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
U8 attachment_id = 0;
if (attachment)
@@ -5919,15 +5900,12 @@ void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data)
// interpret 0 as "default location"
attachment_id = 0;
}
- LLSelectMgr::getInstance()->sendAttach(attachment_id, cb_data->mReplace);
+ LLSelectMgr::getInstance()->sendAttach(attachment_id);
}
LLObjectAttachToAvatar::setObjectSelection(NULL);
-
- delete cb_data;
}
-// static
-void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point)
+void confirm_replace_attachment(S32 option, void* user_data)
{
if (option == 0/*YES*/)
{
@@ -5952,9 +5930,7 @@ void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointA
delta = delta * 0.5f;
walkToSpot -= delta;
- // The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak.
- CallbackData* user_data = new CallbackData(attachment_point, mReplace);
- gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance);
+ gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance);
gAgentCamera.clearFocusObject();
}
}
@@ -6074,7 +6050,7 @@ static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data)
const LLViewerObject* attached_object = (*attachment_iter);
if (attached_object)
{
- LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getItemID());
+ LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
if (itemp)
{
label += std::string(" (") + itemp->getName() + std::string(")");
@@ -6193,14 +6169,14 @@ class LLAttachmentEnableDrop : public view_listener_t
{
// make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
// so check to see if the item is in the inventory already
- item = gInventory.getItem((*attachment_iter)->getItemID());
+ item = gInventory.getItem((*attachment_iter)->getAttachmentItemID());
if (!item)
{
// Item does not exist, make an observer to enable the pie menu
// when the item finishes fetching worst case scenario
// if a fetch is already out there (being sent from a slow sim)
// we refetch and there are 2 fetches
- LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getItemID());
+ LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID());
worn_item_fetched->startFetch();
gInventory.addObserver(worn_item_fetched);
}
@@ -6547,7 +6523,7 @@ void handle_dump_attachments(void*)
!attached_object->mDrawable->isRenderType(0));
LLVector3 pos;
if (visible) pos = attached_object->mDrawable->getPosition();
- llinfos << "ATTACHMENT " << key << ": item_id=" << attached_object->getItemID()
+ llinfos << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID()
<< (attached_object ? " present " : " absent ")
<< (visible ? "visible " : "invisible ")
<< " at " << pos
@@ -6558,7 +6534,7 @@ void handle_dump_attachments(void*)
}
-// these are used in the gl menus to set control values, generically.
+// these are used in the gl menus to set control values.
class LLToggleControl : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6577,44 +6553,8 @@ class LLCheckControl : public view_listener_t
std::string callback_data = userdata.asString();
bool new_value = gSavedSettings.getBOOL(callback_data);
return new_value;
- }
-};
-
-// not so generic
-
-class LLAdvancedCheckRenderShadowOption: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- std::string control_name = userdata.asString();
- S32 current_shadow_level = gSavedSettings.getS32(control_name);
- if (current_shadow_level == 0) // is off
- {
- return false;
- }
- else // is on
- {
- return true;
- }
- }
-};
+}
-class LLAdvancedClickRenderShadowOption: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- std::string control_name = userdata.asString();
- S32 current_shadow_level = gSavedSettings.getS32(control_name);
- if (current_shadow_level == 0) // upgrade to level 2
- {
- gSavedSettings.setS32(control_name, 2);
- }
- else // downgrade to level 0
- {
- gSavedSettings.setS32(control_name, 0);
- }
- return true;
- }
};
void menu_toggle_attached_lights(void* user_data)
@@ -7939,7 +7879,7 @@ void initialize_menus()
// Help menu
// most items use the ShowFloater method
- // Advanced menu
+ // Advance menu
view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");
view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole");
@@ -7966,13 +7906,12 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
- // Develop > Render
view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas");
view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");
+ view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredGI(), "Advanced.EnableRenderDeferredGI");
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
@@ -7981,8 +7920,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest");
view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest");
view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
- view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
- view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
@@ -8139,8 +8076,7 @@ void initialize_menus()
commit.add("Object.Touch", boost::bind(&handle_object_touch));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
- view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
- view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar");
+ view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 15bdf126c5..d3e6f01bc8 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5233,3 +5233,28 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif
return ;
}
+const LLUUID &LLViewerObject::getAttachmentItemID() const
+{
+ return mAttachmentItemID;
+}
+
+void LLViewerObject::setAttachmentItemID(const LLUUID &id)
+{
+ mAttachmentItemID = id;
+}
+
+const LLUUID &LLViewerObject::extractAttachmentItemID()
+{
+ LLUUID item_id = LLUUID::null;
+ LLNameValue* item_id_nv = getNVPair("AttachItemID");
+ if( item_id_nv )
+ {
+ const char* s = item_id_nv->getString();
+ if( s )
+ {
+ item_id.set(s);
+ }
+ }
+ setAttachmentItemID(item_id);
+ return getAttachmentItemID();
+}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index be83fb7ef8..33fda9fa2d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -678,11 +678,15 @@ protected:
private:
static S32 sNumObjects;
+ //--------------------------------------------------------------------
+ // For objects that are attachments
+ //--------------------------------------------------------------------
public:
- const LLUUID &getItemID() const { return mAttachmentItemID; }
- void setItemID(const LLUUID &id) { mAttachmentItemID = id; }
+ const LLUUID &getAttachmentItemID() const;
+ void setAttachmentItemID(const LLUUID &id);
+ const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object
private:
- LLUUID mAttachmentItemID; // ItemID when item is in user inventory.
+ LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
};
///////////////////
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 9d4f6fdd0c..9b3243a1bc 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -814,7 +814,7 @@ void LLViewerTexture::generateGLTexture()
LLImageGL* LLViewerTexture::getGLTexture() const
{
llassert(mGLTexturep.notNull()) ;
-
+
return mGLTexturep ;
}
@@ -1489,8 +1489,13 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
//virtual
void LLViewerFetchedTexture::processTextureStats()
{
- if(mFullyLoaded)
+ if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
{
+ mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ;
+ }
+
+ if(mFullyLoaded)
+ {
if(mDesiredDiscardLevel <= mMinDesiredDiscardLevel)//already loaded
{
return ;
@@ -2131,7 +2136,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so
void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
if(!callback_list)
-{
+ {
mPauseLoadedCallBacks = FALSE ;
return ;
}
@@ -2160,7 +2165,7 @@ void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry:
void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
{
if(!callback_list)
-{
+ {
return ;
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 6392aad248..4e00355bbe 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -702,8 +702,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
}
- mDirtyMesh = 2; // Dirty geometry, need to regenerate.
+ mDirtyMesh = TRUE; // Dirty geometry, need to regenerate.
mMeshTexturesDirty = FALSE;
+ mShadow0Facep = NULL;
+ mShadow1Facep = NULL;
mHeadp = NULL;
mIsBuilt = FALSE;
@@ -739,6 +741,12 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRippleTimeLast = 0.f;
+ mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c");
+
+ // GL NOT ACTIVE HERE
+ //gGL.getTexUnit(0)->bind(mShadowImagep.get());
+ //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
+
mInAir = FALSE;
mStepOnLand = TRUE;
@@ -1967,7 +1975,7 @@ void LLVOAvatar::updateMeshData()
}
if(num_vertices < 1)//skip empty meshes
{
- continue ;
+ break ;
}
if(last_v_num > 0)//put the last inserted part into next vertex buffer.
{
@@ -1989,8 +1997,6 @@ void LLVOAvatar::updateMeshData()
// resize immediately
facep->setSize(num_vertices, num_indices);
- bool terse_update = false;
-
if(facep->mVertexBuffer.isNull())
{
facep->mVertexBuffer = new LLVertexBufferAvatar();
@@ -1998,16 +2004,8 @@ void LLVOAvatar::updateMeshData()
}
else
{
- if (facep->mVertexBuffer->getRequestedIndices() == num_indices &&
- facep->mVertexBuffer->getRequestedVerts() == num_vertices)
- {
- terse_update = true;
- }
- else
- {
facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
}
- }
facep->setGeomIndex(0);
facep->setIndicesIndex(0);
@@ -2021,7 +2019,7 @@ void LLVOAvatar::updateMeshData()
for(S32 k = j ; k < part_index ; k++)
{
- mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update);
+ mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR);
}
stop_glerror();
@@ -2431,6 +2429,12 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
LLJoint::sNumUpdates = 0;
LLJoint::sNumTouches = 0;
+ // *NOTE: this is necessary for the floating name text above your head.
+ if (mDrawable.notNull())
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE);
+ }
+
BOOL visible = isVisible() || mNeedsAnimUpdate;
// update attachments positions
@@ -3783,20 +3787,13 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
return num_indices;
}
- LLFace* face = mDrawable->getFace(0);
-
- bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
-
- if (needs_rebuild || mDirtyMesh)
+ if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
- if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
- {
updateMeshData();
- mDirtyMesh = 0;
+ mDirtyMesh = FALSE;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}
- }
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
{
@@ -4043,6 +4040,54 @@ U32 LLVOAvatar::renderRigid()
return num_indices;
}
+U32 LLVOAvatar::renderFootShadows()
+{
+ U32 num_indices = 0;
+
+ if (!mIsBuilt)
+ {
+ return 0;
+ }
+
+ if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
+ {
+ return 0;
+ }
+
+ if (!mIsBuilt)
+ {
+ return 0;
+ }
+
+ // Don't render foot shadows if your lower body is completely invisible.
+ // (non-humanoid avatars rule!)
+ if (!isTextureVisible(TEX_LOWER_BAKED))
+ {
+ return 0;
+ }
+
+ // Update the shadow, tractor, and text label geometry.
+ if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor())
+ {
+ updateShadowFaces();
+ mDrawable->clearState(LLDrawable::REBUILD_SHADOW);
+ }
+
+ U32 foot_mask = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_TEXCOORD0;
+
+ LLGLDepthTest test(GL_TRUE, GL_FALSE);
+ //render foot shadows
+ LLGLEnable blend(GL_BLEND);
+ gGL.getTexUnit(0)->bind(mShadowImagep, TRUE);
+ glColor4fv(mShadow0Facep->getRenderColor().mV);
+ mShadow0Facep->renderIndexed(foot_mask);
+ glColor4fv(mShadow1Facep->getRenderColor().mV);
+ mShadow1Facep->renderIndexed(foot_mask);
+
+ return num_indices;
+}
+
U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
{
if (!mImpostor.isComplete())
@@ -4168,6 +4213,11 @@ void LLVOAvatar::updateTextures()
{
setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));
}
+
+ if( render_avatar )
+ {
+ mShadowImagep->addTextureStats(mPixelArea);
+ }
}
@@ -5434,7 +5484,7 @@ BOOL LLVOAvatar::updateJointLODs()
if (res)
{
sNumLODChangesThisFrame++;
- dirtyMesh(2);
+ dirtyMesh();
return TRUE;
}
}
@@ -5458,9 +5508,18 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
mDrawable->addFace(poolp, NULL);
mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
+ LLFace *facep;
+
+ // Add faces for the foot shadows
+ facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
+ mShadow0Facep = facep;
+
+ facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
+ mShadow1Facep = facep;
+
mNumInitFaces = mDrawable->getNumFaces() ;
- dirtyMesh(2);
+ dirtyMesh();
return mDrawable;
}
@@ -5500,6 +5559,107 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
}
//-----------------------------------------------------------------------------
+// updateShadowFaces()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::updateShadowFaces()
+{
+ LLFace *face0p = mShadow0Facep;
+ LLFace *face1p = mShadow1Facep;
+
+ //
+ // render avatar shadows
+ //
+ if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD)
+ {
+ face0p->setSize(0, 0);
+ face1p->setSize(0, 0);
+ return;
+ }
+
+ LLSprite sprite(mShadowImagep.notNull() ? mShadowImagep->getID() : LLUUID::null);
+ sprite.setFollow(FALSE);
+ const F32 cos_angle = gSky.getSunDirection().mV[2];
+ F32 cos_elev = sqrt(1 - cos_angle * cos_angle);
+ if (cos_angle < 0) cos_elev = -cos_elev;
+ sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f);
+ LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f);
+
+ if (mShadowImagep->hasGLTexture())
+ {
+ LLVector3 normal;
+ LLVector3d shadow_pos;
+ LLVector3 shadow_pos_agent;
+ F32 foot_height;
+
+ if (mFootLeftp)
+ {
+ LLVector3 joint_world_pos = mFootLeftp->getWorldPosition();
+ // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
+ // but we make an explicit ray trace call in expectation of future improvements
+ resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
+ gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
+ shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
+ foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
+
+ // Pull sprite in direction of surface normal
+ shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
+
+ // Render sprite
+ sprite.setNormal(normal);
+ if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ {
+ sprite.setColor(0.f, 0.f, 0.f, 0.f);
+ }
+ else
+ {
+ sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
+ }
+ sprite.setPosition(shadow_pos_agent);
+
+ LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos;
+ //foot_to_knee.normalize();
+ foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
+ sprite.setYaw(azimuth(sun_vec - foot_to_knee));
+
+ sprite.updateFace(*face0p);
+ }
+
+ if (mFootRightp)
+ {
+ LLVector3 joint_world_pos = mFootRightp->getWorldPosition();
+ // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
+ // but we make an explicit ray trace call in expectation of future improvements
+ resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
+ gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
+ shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
+ foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
+
+ // Pull sprite in direction of surface normal
+ shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
+
+ // Render sprite
+ sprite.setNormal(normal);
+ if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ {
+ sprite.setColor(0.f, 0.f, 0.f, 0.f);
+ }
+ else
+ {
+ sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
+ }
+ sprite.setPosition(shadow_pos_agent);
+
+ LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos;
+ //foot_to_knee.normalize();
+ foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
+ sprite.setYaw(azimuth(sun_vec - foot_to_knee));
+
+ sprite.updateFace(*face1p);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
// updateSexDependentLayerSets()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
@@ -5514,12 +5674,9 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
//-----------------------------------------------------------------------------
void LLVOAvatar::dirtyMesh()
{
- dirtyMesh(1);
-}
-void LLVOAvatar::dirtyMesh(S32 priority)
-{
- mDirtyMesh = llmax(mDirtyMesh, priority);
+ mDirtyMesh = TRUE;
}
+
//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
@@ -5553,6 +5710,7 @@ BOOL LLVOAvatar::setParent(LLViewerObject* parent)
void LLVOAvatar::addChild(LLViewerObject *childp)
{
+ childp->extractAttachmentItemID(); // find the inventory item this object is associated with.
LLViewerObject::addChild(childp);
if (childp->mDrawable)
{
@@ -5642,15 +5800,6 @@ BOOL LLVOAvatar::canAttachMoreObjects() const
}
//-----------------------------------------------------------------------------
-// canAttachMoreObjects()
-// Returns true if we can attach <n> more objects.
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const
-{
- return (getNumAttachments() + n) <= MAX_AGENT_ATTACHMENTS;
-}
-
-//-----------------------------------------------------------------------------
// lazyAttach()
//-----------------------------------------------------------------------------
void LLVOAvatar::lazyAttach()
@@ -7793,15 +7942,18 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (facep->mVertexBuffer.isNull())
+ if (facep->mVertexBuffer.isNull() ||
+ (LLVertexBuffer::sEnableVBOs &&
+ ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
+ (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))))
{
- dirtyMesh(2);
+ mDirtyMesh = TRUE;
}
- if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+ if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
updateMeshData();
- mDirtyMesh = 0;
+ mDirtyMesh = FALSE;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index bddde08ca9..274dbe6332 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1016,6 +1016,44 @@ BOOL LLVOAvatarSelf::isWearingAttachment(const LLUUID& inv_item_id) const
}
//-----------------------------------------------------------------------------
+BOOL LLVOAvatarSelf::attachmentWasRequested(const LLUUID& inv_item_id) const
+{
+ const F32 REQUEST_EXPIRATION_SECONDS = 5.0; // any request older than this is ignored/removed.
+ std::map<LLUUID,LLTimer>::iterator it = mAttachmentRequests.find(inv_item_id);
+ if (it != mAttachmentRequests.end())
+ {
+ const LLTimer& request_time = it->second;
+ F32 request_time_elapsed = request_time.getElapsedTimeF32();
+ if (request_time_elapsed > REQUEST_EXPIRATION_SECONDS)
+ {
+ mAttachmentRequests.erase(it);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::addAttachmentRequest(const LLUUID& inv_item_id)
+{
+ LLTimer current_time;
+ mAttachmentRequests[inv_item_id] = current_time;
+}
+
+//-----------------------------------------------------------------------------
+void LLVOAvatarSelf::removeAttachmentRequest(const LLUUID& inv_item_id)
+{
+ mAttachmentRequests.erase(inv_item_id);
+}
+
+//-----------------------------------------------------------------------------
// getWornAttachment()
//-----------------------------------------------------------------------------
LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
@@ -1067,8 +1105,10 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
// Should just be the last object added
if (attachment->isObjectAttached(viewer_object))
{
- const LLUUID& attachment_id = viewer_object->getItemID();
+ const LLUUID& attachment_id = viewer_object->getAttachmentItemID();
LLAppearanceMgr::instance().registerAttachment(attachment_id);
+ // Clear any pending requests once the attachment arrives.
+ removeAttachmentRequest(attachment_id);
}
return attachment;
@@ -1077,7 +1117,7 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
//virtual
BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
{
- const LLUUID attachment_id = viewer_object->getItemID();
+ const LLUUID attachment_id = viewer_object->getAttachmentItemID();
if (LLVOAvatar::detachObject(viewer_object))
{
// the simulator should automatically handle permission revocation
@@ -1115,6 +1155,29 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
return FALSE;
}
+// static
+BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
+{
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if (item)
+ {
+ gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
+ gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
+ gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
+
+ // this object might have been selected, so let the selection manager know it's gone now
+ LLViewerObject *found_obj = gObjectList.findObject(item_id);
+ if (found_obj)
+ {
+ LLSelectMgr::getInstance()->remove(found_obj);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
{
LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
@@ -1625,15 +1688,15 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
if (isSelf())
{
if (gAgentAvatarp->isUsingBakedTextures())
- {
- requestLayerSetUpdate(type);
- }
+ {
+ requestLayerSetUpdate(type);
+ }
else
- {
- LLVisualParamHint::requestHintUpdates();
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
}
}
- }
else
{
tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 630afe7a0f..21c815a70c 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -291,10 +291,18 @@ protected:
public:
void updateAttachmentVisibility(U32 camera_mode);
BOOL isWearingAttachment(const LLUUID& inv_item_id) const;
+ BOOL attachmentWasRequested(const LLUUID& inv_item_id) const;
+ void addAttachmentRequest(const LLUUID& inv_item_id);
+ void removeAttachmentRequest(const LLUUID& inv_item_id);
LLViewerObject* getWornAttachment(const LLUUID& inv_item_id);
const std::string getAttachedPointName(const LLUUID& inv_item_id) const;
/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
/*virtual*/ BOOL detachObject(LLViewerObject *viewer_object);
+ static BOOL detachAttachmentIntoInventory(const LLUUID& item_id);
+
+private:
+ // Track attachments that have been requested but have not arrived yet.
+ mutable std::map<LLUUID,LLTimer> mAttachmentRequests;
//--------------------------------------------------------------------
// HUDs