_____ From: opensource-dev-boun...@lists.secondlife.com [mailto:opensource-dev-boun...@lists.secondlife.com] On Behalf Of Marine Kelley Sent: Monday, May 10 2010 09:24 To: opensource-dev@lists.secondlife.com Subject: [opensource-dev] Cannot wear two different bodyparts at the sametime Hello all, I have just filed a JIRA under Viewer 2.0.1 (although it shows for 2.0.0 as well) at <https://jira.secondlife.com/browse/VWR-19425> https://jira.secondlife.com/browse/VWR-19425 In short, when you wear a new skin and a new hair at the same time (by selecting both and pressing Wear), one of them is worn then removed, leaving you with the default version and an error message. I have discovered this when testing RLV 2.0 (and pulling my hair for days over it) which uses outfits very extensively and that ability is crippled. But since it is also present in the vanilla SL viewer 2.0, I don't see what I can do. Have anyone encountered this problem ? Marine *waves* There's a few JIRAs on it already I think (not all of them that exact same issue but all having to do with a broken COF) and all the "fun" bugs that come from that. What happens in your specific case: 1) I'd guess you're calling LLAppearanceMgr::addCOFItemLink twice in a row - both the currently worn hair and skin link are removed from "Current Outfit" - you'll have two calls to link_inventory_item() with two different ModifiedCOFCallback callbacks 2) (let's say the skin link callback fires first) - it fires off LLAppearanceMgr::updateAppearanceFromCOF() which does the whole LLWearableHoldingPattern dance - the old skin link was removed but there's a new one so you're set for skin - the old hair link was removed but the new hair link hasn't been created yet (or the viewer hasn't been notified of it yet) - when it gets to LLWearableHoldingPattern::checkMissingWearables() it decides that since there is no hair link in COF it should just create one from scratch and wear that You probably got lucky too since there's another bug in wearing more than one body part at the same time: - when the wearable gets recovered it creates a new item link for it in "Current Outfit" - when both the original and the recovered wearable link complete you now have two body parts of the same type listed under COF and you may get lucky and end up with the one you want, or you may get the one you don't want the next time you try to wear something The easiest solution there was to simply change "checkMissingWearable()" to first call a new "recoverExistingWearable()" which checks what's currently worn and reuses that instead of creating a new default wearable. So it goes: - if wearable type either should be always be present (=body part) or was requested (=clothing) but wasn't resolved then: - iterate over what's currently worn on that wearable type and compare the asset UUID - if it matches then you just grab the existing LLWearable* and put that in mFoundList instead - or do nothing if a clothing layer was requested but isn't currently worn Which goes back to the far less annoying 1.23 behaviour (if you wear something that can't have its asset fetched (or that times out) then you do *not* change what's currently worn). It still won't work perfect though because you'll still have two independent callbacks firing and two LLWearableHoldingPattern instances: - extend LLAppearanceMgr::addCOFItemLink to take a callback as an extra parameter - instead of creating its own callback have it use the one passed to it if it's not null That way you can go: LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy(); LLAppearanceMgr::instance().addCOFItemLink(..., true, cb); LLAppearanceMgr::instance().addCOFItemLink(..., true, cb); LLAppearanceMgr::instance().addCOFItemLink(..., true, cb); And you'll just have one single call to LLAppearanceMgr::updateAppearanceFromCOF() no matter how many you add. One thing to note is that there's code in addCOFItemLink that will make sure that if you already have an item of that wearable type in COF then it'll remove the old link to make sure that you don't end up with 2 body parts and 4 shirts listed so you'll need to do that filtering yourself because since the new links don't exist yet that code doesn't end up actually doing anything (and in 2.0.2 it needs fixing to still filter out body parts). So for me it looks like (items is an array of LLViewerInventoryItem* to body parts and clothing items): LLAppearanceMgr::filterWearableItems(items, X); // <- this one isn't public by default so you'll have to change that LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy(); for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) LLAppearanceMgr::instance().addCOFItemLink(*itItem, true, cb); (X will be 1 on 2.0.1 but 5 - probably subject to change but that seems to be the current limit - on 2.0.2 since that has the code for multi-wearables all in place now and for 2.0.2 filterWearableItems needs "fixing" to handle body parts differently because it doesn't do that on its own) That's still not the end of it though :(. - I had to make LLWearableHoldingPattern a "fake singleton" (only allow one of them to be running at any given time) in order to get rid of some of the COF corruption or "wear this, then suddenly unwear and/or revert to something from before" - instead of LLAppearanceMgr::purgeCategory() followed by linkAll() I use a new "syncCOF" which instead of doing a complete purge followed by a rebuild it instead purges what isn't wanted, links what is wanted but isn't linked and keeps what's wanted and already linked (primarily useful because it cuts down on the time it takes for link creation callbacks to fire which side-steps some bugs even if it's not going to be perfect in and by itself) - since attachments get attached/detached as part of LLWearableHoldingPattern you'll see some of them getting attached only to just end up detached again a second later (and others will revert) because it'll be working off of an outdated list that's no longer accurate (so the LLAgentWearable::userAttachMultipleAttachments should be in updateAppearanceOnCOF and not in LLWearableHoldingPattern::onAllComplete() - put in "COF validation" to keep COF in sync with what's worn (recreate links that aren't actually missing but are still deleted by LLWearableHoldingPattern::clearCOFLinksForMissingWearables() to name one) and get rid of duplicates or "left-overs" (from trying to wear more than one at a time) - fix wearing multiple items at the same time (instead of calling "LLXXXBridge::performAction" X times - which is the default behaviour you just do the workaround above and wear all items at the same time - or attach them all at the same time). This fixes the behaviour you're seeing with "Wear" in the official viewer (and what's causing "Attachment pending for this spot" on attachments when "Wear"'ing) - fix for what's worn reverting when switching from 2.0 to 1.23 back to 2.0 (aside from the edge case where only an attachment changes but no change in wearables) - fix for http://jira.secondlife.com/browse/VWR-18780 (summary of goes wrong is in the comments) - on the surface it might seem to match what you're running into but it actually has a very different cause and chain of events so they're not duplicates With all of that it seems to more or less be glitch-free (I haven't been able to trigger any of the official viewer appearance related bugs anyway so far) and the code holds up fairly well across LL code drops so far. Some of the patches fix the same issue in different places, others complement each other. The appearance manager doesn't really handle attachments well though: you can't use addCOFItemLink on those because you'll spam the user with "attachment is pending for this point" (aside from forcing them to rebake just for wearing an attachment) and RezMultipleAttachmentsFromInv has a bug that will discard new messages if the current one hasn't finished processing yet. You can't use RezSingleAttachmentFromInv either because there's a time delay between the time where it attaches and where the link will appear in COF which causes it to get detached right after getting attached (although it *usually* works well enough and certainly a whole lot better than using COF to attach things). I'd guess it was tested by dutifully clicking one single thing at a time and then sitting and waiting for that to finish before wearing something new. It breaks once you deviate from that or if the region you're on is experiencing issue (stuck pending.downloads come to mind), or if the grid as a whole isn't feeling well, or if your own internet is having hick-ups. Since links are constantly getting deleted and created there's a chance you'll run into inventory cache "corruption" too (you'll see - usually older - items in COF that can't be deleted and when you look at the properties they'll list as being owned by Thrax Linden - which is the default name in the .xml for that panel). About all you can do then is just clear cache and relog again. I definitely symphatize with you :(. I've screamed at COF and the appearance manager quite a LOT over the past 2 months :p. All in all it's rather depressing since it takes time away from working on your own thing :(. (And the frustration probably makes this email come out a lot more "snarky"/"annoyed" then I'd want to) I just redid my patches for 2.0.2 this weekend but I should still have the 2.0.1 ones somewhere if they'd be useful (for reference if nothing else). Don't remember how commented they are, but with the outlines from this email it should be okies. They're more or less limited to one issue per patch too so it's not a 600Kb dump to sort through for those handful of lines that are relevant :p. (This really does need fixing in the offical viewer though) Kitty
_______________________________________________ Policies and (un)subscribe information available here: http://wiki.secondlife.com/wiki/OpenSource-Dev Please read the policies before posting to keep unmoderated posting privileges