diff options
| -rw-r--r-- | indra/newview/llagentwearables.cpp | 15 | ||||
| -rw-r--r-- | indra/newview/llagentwearablesfetch.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 127 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.h | 8 | ||||
| -rw-r--r-- | indra/newview/llfloatergroups.cpp | 31 | ||||
| -rw-r--r-- | indra/newview/llinventorybridge.cpp | 46 | ||||
| -rw-r--r-- | indra/newview/llsidepanelappearance.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llviewerjointattachment.cpp | 37 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 98 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.h | 10 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 236 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.cpp | 79 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.h | 8 | 
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  | 
