niftools / pyffi

PyFFI is a Python library for processing block structured files.
http://www.niftools.org/pyffi
Other
48 stars 26 forks source link

Skyrim Nifs and update_skin_partition spell: missing functionality vs Nifskope spell 'Make All Skin Partitions' #5

Open kormgar opened 10 years ago

kormgar commented 10 years ago

After my BoneWeight Copy tool adds a new NifFormat.BSDismemberSkinInstance block and assigns it as a skininstance, etc I use the following call to build the skin partitions:

niBlock.update_skin_partition(maxbonesperpartition=max_part_bones, maxbonespervertex=max_vert_bones, trianglepartmap=partition_map)

This resulting nif, on export, fails to properly render in the construction kit or in-game. However, running the Nifskope spell ''Make All Skin Partitions' fixes the mesh and allows it to be properly rendered in game.

I have yet to identify all of the changes made by the Nifskope spell, but one set of changes modifies the following properties

_BSDismemberSkinInstance.partitions.pf_editor_visible = 1 _BSDismemberSkinInstance.partitions.reserved_bits_1 = 0 _BSDismemberSkinInstance.partitions.pf_start_net_boneset = 1

Now, nifskope always sets these properties to this value, which might actually be a Nifskope bug.

Nifskope makes some additional modifications to the nif that I have not yet identified that allow newly rigged Skyrim meshes to be usable in game.

kormgar commented 10 years ago

It appears that Nifskope automatically sets the _BSDismemberSkinInstance partitions settings to the same values regardless of the partitions. The Pyffi spell ignores them entirely. With that issue in mind, I've assembled this dictionary of partition information from fallout meshes:

{0: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSO'},\ 1: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_HEAD'},\ 3: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_LEFTARM'},\ 5: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_RIGHTARM'},\ 7: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_LEFTLEG'},\ 10: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_RIGHTLEG'},\ 101: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_SECTIONCAP_HEAD'},\ 103: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_SECTIONCAP_LEFTARM'},\ 105: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_SECTIONCAP_RIGHTARM'},\ 107: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_SECTIONCAP_LEFTLEG'},\ 110: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_SECTIONCAP_RIGHTLEG'},\ 201: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_TORSOCAP_HEAD'},\ 203: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOCAP_LEFTARM'},\ 205: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOCAP_RIGHTARM'},\ 207: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOCAP_LEFTLEG'},\ 210: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_TORSOCAP_RIGHTLEG'},\ 1000: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOSECTION_HEAD'},\ 3000: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOSECTION_LEFTARM'},\ 5000: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOSECTION_RIGHTARM'},\ 7000: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'BP_TORSOSECTION_LEFTLEG'},\ 10000: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'BP_TORSOSECTION_RIGHTLEG'}}

Is this data that should be added to the xml description of _BSDismemberSkinInstance partitions, or added to the pyffi spell?

I can assemble a similar dictionary for Skyrim meshes.

kormgar commented 10 years ago

And all that I've found so far for the Skryim partitions

{32: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'SBP_32_BODY'},\ 33: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'SBP_33_HANDS'},\ 34: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'SBP_34_FOREARMS'},\ 37: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'SBP_37_FEET'},\ 38: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'SBP_38_CALVES'},\ 40: {'pf_editor_visible' : 1, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'SBP_40_TAIL'},\ 130: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'SBP_130_HEAD'},\ 143: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 0, 'body_part' : 'SBP_143_EARS'},\ 230: {'pf_editor_visible' : 0, 'reserved_bits_1' : 0, 'pf_start_net_boneset' : 1, 'body_part' : 'SBP_230_HEAD'}}