ousnius / BodySlide-and-Outfit-Studio

BodySlide and Outfit Studio, a tool to convert, create, and customize outfits and bodies for Bethesda games.
GNU General Public License v3.0
290 stars 64 forks source link

Copy special "cloth" boneweight works incorrectly #379

Closed Indarello closed 2 years ago

Indarello commented 2 years ago

I tested this problem with different versions and found that 4.9.1 is latest properly working version for this issue next version available for download (5.0.7) have this bug

So when you copy boneweight from some clothing that have special cloth bones: they are copied and have physics in game, but they are dispalced in game (see img 1) and not displaced in nifskope (see img 2) But for proper custom boneweight copy they should be dispalced in nifskope (see img 3) and in result will look good in game https://imgur.com/a/bHpdX6a

Or maybe I understand something wrong, what I do: 1)load project with my new dress (my dress is img 2) 2)import from nif another working dress (custom working dress is img 3) with custom bones 3)set reference to working dress and copy boneweight for my new dress 4)delete custom dress, save and build outfit

sts1skj commented 2 years ago

A lot of code changed between 4.9.1 (January 11, 2020) and 5.0.7 (May 30, 2020). I made my first pull request on January 19th, and over the coming months I changed a lot of code, including major changes to bones and coordinate system handling. Some commits that may have broken "special cloth" bone weights:

Since I'm probably the person who broke "special cloth" bone weights, perhaps I should try to fix it. But I need a lot more information, since I know very little about how "special cloth" bone weights work. I don't think I've ever seen decent-looking cloth bone weighting in Skyrim.

@Indarello It would be helpful if you could provide the following information:

  1. Which game is this for
  2. A nif for a working dress
  3. A nif for a new dress

Hopefully, with this information, I will be able to reproduce the error.

Indarello commented 2 years ago

F4 test copy weight.zip

sts1skj commented 2 years ago

Some preliminary observations from examining testcopy.nif, which has shapes "bot" and "try to copy weight here":

  1. I don't have Fallout 4. So I can't test directly in the game; I can only rely on Outfit Studio and NifSkope.
  2. If you turn on "Show Pose" in Outfit Studio, it shows the same twisted dress as NifSkope shows.
  3. If you turn off "Do Skinning" in NifSkope, it shows the dress untwisted, the same as Outfit Studio, but without the skin offset.
  4. Both shapes have a skin offset of about (0,.9,-120.8), which you can see by looking at the Coordinates tab of the Shape Properties window in Outfit Studio. This is a commonly used skin offset for Fallout 4. It's not necessary to have a skin offset, but it's generally good to pick a skin offset so that the most-detailed portion of the mesh has coordinates near (0,0,0). I think the skin offset of (0,.9,-120.8) was chosen to put the character's face near (0,0,0).
  5. The shape "bot" appears to have 9 custom bones: ButtCBP{L,R}_ 01, CLOTH_BN_COAT_C_00{1,2,3,4,5}, and ThighCBP{L,R}_F_02.
  6. The Butt and Thigh custom bones seem to appear normally. The twisting only seems to affect the Cloth custom bones.
  7. Each Cloth custom bone seems to have a mismatch between the bone-to-global transform in the bone's NiNode and the skin-to-bone transform in the shape's bone list (BSSkin::BoneData in NifSkope). That's what makes the affected vertices twist around when you turn on "Show Pose" in Outfit Studio or "Do Skinning" in NifSkope. (The skin-to-bone and bone-to-global transforms are applied in sequence to each vertex to map it from skin space to global space.)
  8. When you do "Copy Bone Weights" in Outfit Studio, the resulting nif has skin-to-bone transforms for the five Cloth bones that differ for the two shapes, as shown by NifSkope. The rest of the skin-to-bone transforms seem to match between the two shapes.
  9. When a new bone is added to a shape in Outfit Studio 5.0 or later, it generates a skin-to-bone transform for the new bone from the shape's global-to-skin transform and the NiNode's bone-to-global transform. If the bone-to-global transform is garbage, then so too will the resulting skin-to-bone transform be garbage. This new way of calculating a new skin-to-bone transform was implemented by me, probably in one of the commits listed in my previous message. If I recall correctly, the old method was to copy the skin-to-bone transform from some other shape.
  10. Outfit Studio's "Reset Transforms" command resets the skin-to-bone transforms of the shape (in addition to resetting other things), recalculating them as mentioned in observation 9. So I would expect it to preserve (and propagate) the presumably bad data in the bone-to-global transforms, making the problem worse.

So I think I understand the problem:

Now, keep in mind that these conclusions are preliminary. I may not be understanding the problem correctly at all. And I can't test any of this in Fallout 4, because I don't have Fallout 4.

@Indarello Some questions:

  1. Do you see any flaws in my reasoning?
  2. Do you have any idea why the NiNodes for the Cloth bones would have bad data?
  3. Have you tried updating the NiNodes with good data before using "Copy Bone Weights"? (I have no idea how you would do that.)
  4. Have you tried Outfit Studio's "Reset Transforms" command and checked the result in Fallout 4? (I would expect this to produce bad results.)
  5. Have you tried using NifSkope to update the skin-to-bone transforms for the five Cloth bones in the BSSkin::BoneData for shape "try to copy weight here" by copying them from the shape "bot" after Outfit Studio has trashed them? (This would probably be quite unpleasant to do, because the records aren't labeled with their bone names. You have to figure out the right record by finding the corresponding NiNode in the NiSkin::Instance's children list, count how far it is from the end of the list, and count the same number of records from the end of the bone list.)

Keep in mind that I am not suggesting that you have done anything wrong. I am not suggesting any procedure to follow. I am not proposing a solution. I'm merely seeking to understand the problem. Solutions will be addressed later.

@ousnius Some questions:

  1. Does my reasoning seem correct?
  2. Do you have any other observations?
  3. Has anyone else had this problem since Outfit Studio 5.0 was released two years ago? If so, how was it resolved? (I vaguely recall discussing this with you two years ago, but I don't remember the conclusion.)
Indarello commented 2 years ago

I cant find any buttons you asking, probably they don't exist in F4 outfit studio I just imported dress from .obj and I just simply copied boneweight, and I think it should work ok, I dont udnerstand all this development staff "global-to-skin transform", "vertex to map" and so on, please dont ask me about them or provide images what button I should press to give you this info. I just noticed that in nifskope dresses look different and I thought that may help you, I dont care if after fix they still look different in nifskope, I just want it solved for game

sts1skj commented 2 years ago

@Indarello I apologize for my long technical post. I should have realized it would not be useful to you. I have a bad habit of inflicting long technical explanations on my colleagues when I get excited about something I'm working on. I'm sorry.

sts1skj commented 2 years ago

@ousnius Ideas for solutions

This is assuming my reasoning above is correct. I see the problem as this: how to help the user fix the bad data. Fixing the bad data manually is very difficult, as far as I know.

Idea 1: When loading a skinned mesh from any source, check for inconsistencies between node and skin data. (Node data gives the bone-to-global transform. Skin data gives the skin-to-bone transform. They are connected via the global-to-skin transform.) If inconsistencies are found, pop up a dialog window with choices. For inconsistencies in standard bones, the options would be:

For inconsistencies in custom bones, the options would be:

Idea 2: When the user does "Reset Transforms", check for the existence of custom bones. If there are any, offer the user the choice of how to reset them:

The dialog window could also give information about how many standard bones and custom bones have inconsistencies. Perhaps it could even list them. (Currently, "Reset Transforms" updates skin data and does not change nodes.)

Idea 3: In the "Copy Bone Weights" dialog, there's currently a check for a mismatch between the source and target global-to-skin transforms. We could add a check for inconsistencies between node and source skin data, and ask the user what to do. For standard bones, the options would be:

For custom bones, the options would be:

Currently, "Calculate target skin bone data from node data" is always done (I think). In Outfit Studio 4.9.1 and older, if I recall correctly, "Copy skin bone data from source to target" is always done.

Of course, these three ideas are not mutually exclusive. We could do all three.