FO4 Segments and Subsegments - BadDogSkyrim/PyNifly GitHub Wiki
FO4 uses a method of segmenting nifs entirely different from Skyrim:
-
There are segments and subsegments. Segments generally correspond to a body part, such as an entire arm. Subsegments break a body part into bits. Subsegments are grouped under a parent segment. If a segment has subsegments it does not have vertices associated with it--it's just there to group subsegments. Subsegments always have vertices associated with them.
-
Subsegments have a user index and a bone ID (also referred to as a "material" in OS/nifly, but it's called "Bone ID" in nifskope):
-
The index is a small integer. It is unique and increases monotonically across subsegments under a segment. Subsegments are ordered from closest to the body out to the tip of the limb. For dismembering it's just an index, but it may also be used like a Skyrim body part: correlated with a flag set in an armor addon to decide whether to show that part, and so that different armor can knock out sections of another armor.
-
The Bone ID is a magic number that goes with the subsegment. It has been claimed to be a hash of bone names, but I can't reproduce that. It may repeat across a run of subsegments under the same segment, e.g. more than one subsegment associated with a bone. -1 is used as a null value.
-
-
The first segment is always empty. The rest (for humanoids) represent head, left arm, torso, left leg, right leg. Empty trailing segments may be omitted. Other empty segments must be present to hold the place.
-
Empty placeholder segments are important--they are holding space for body parts that this nif does not have. So make sure you create them in Blender with names that will result in exporting in the right order. Order matters for subsegments too. That order is always the same as the user index order.
-
Bone ID may be duplicated across different types of creature--e.g. Supermutant and Human arms use the same bone IDs, but their hands do not.
Dismemberment doesn't generally happen by hiding whole subsegments. It generally happens by disconnecting the limb at cut points.
- There's an additional set of blocks that describe per-segment data--one for each segment and subsegment, in order. Per-segment data includes the Bone ID/material and cut points.
- Cut points are generally defined along a long bone. They are equally spaced along the length of the bone, leaving the ends free. Some meshes skip some cut points based on details of the mesh--e.g., army fatigues skip the calf cut point that would land right at the top of the boot. Apparently the modeler decided trying to apply meat caps there would look bad.
- No idea why there need to be multiple cut points per bone, unless it's just to provide more variety when massacring people.
- Cut points are visualized in Blender with disks cutting across the limb. Move the disks, move the cut point. They are organized under a collection so they can be hidden all together. This visualization is only available if the mesh's SSF file can be found.
- On export, cut points are located by finding the collection with the name "<mesh_name>_Cutpoints", where "<mesh_name>" is the name of the Blender object. You can also select them explicitly.
Dismemberment works via an external SSF file which matches Bone ID to actual bone in the armature. The cut point data only has the Bone ID, not the bone name. The SSF file also has data about how to hide dismembered parts (we think).
On import, the SSF file will be read if possible, using the same mechanism as used for textures and materials files. (Look in the nif's directory tree if it's under a "meshes" directory; look in the addon's resource file list if not.) The Bone ID-to-bone data is used to generate the cut points. The filepath is stored in a "FO4_SEGMENT_FILE" Custom Property on the Blender object whether the file is found or not.
On export, the SSF file is written to the same location as the nif (similar to writing tri files).
To ensure you can export the right segment structure, segments and subsegments are implemented as verted groups with magic names:
-
Segments have names of the form "FO4 Seg ###", where the #'s are digits.
-
Subsegments for dismembering have the form "FO4 Seg ### | ### | ###". The first section is the parent segment name. Since that parent segment won't have any vertices assigned to it (segments with subsegments never do), you don't have to create it explicitly as its own vertex group.
-
The second section is the user index--either a small integer that defines the order of the subsegments, or a body part number such as 32 for head. You can use the number or use a body part name, listed below.
-
The third section is the material hash, in decimal or hex. Hex numbers start with '0x'. For known dismember parts, you can use the dismember name, listed below.
-
Subsegments can also omit the third section (the material) if it's not used in the particular nif.
-
On import, the system will do its best to give you reasonable vertex group names but since there is duplication, it may just give you numbers for the parts instead of the part names. You can safely rename them.
"FO4 Seg 003" -- A segment. 003 represents the body.
"FO4 Seg 006 | 001 | Thigh.R" -- A dismember subsegment under segment "FO4 Seg 002", using the "Thigh.R" material.
"FO4 Seg 001 | Hair Top | Head" -- A body part subsegment for top hair. These are defined using the "Head" material.
"FO4 Seg 001 | Hair Top" -- A body part that doesn't use the material field.
"FO4 Seg 001 | Hair Top | 0x1234" -- A body part providing the material by number rather than name.
Segmentation has to match across all nifs used in a skin in order for dismembering to work. E.g. for a body:
- Seg 0 = nothing
- Seg 1 = head/neck if any (humans don't have one in the body nif, supermutants and others do, but the segment is always there)
- Seg 2 = right arm
- Seg 3 = torso
- Seg 4 = left arm
- Seg 5 = right leg
- Seg 6 = left leg
For example, the human hands match this segment structure. Seg 0 and 1 are present but empty. Seg 2 contains the one subsegment which is the right hand. Seg 3 is empty, holding the place of the torso. Seg 4 has one subsegment for the left hand. So the structure matches up with the body even though the subsegments are different.
Supermutants do the same except their hands are part of the body nif, so they have an extra subsegment under segments 2 and 4 containing the hand.
"Hair Top": 30
"Hair Long": 31
"Head": 32
"HP-Neck": 33
"Hand": 35
"[U] Torso": 36
"[U] L Arm": 37
"[U] R Arm": 38
"[U] L Leg": 39
"[U] R Leg": 40
"[A] Torso": 41
"[A] L Arm": 42
"[A] R Arm": 43
"[A] L Leg": 44
"[A] R Leg": 45
"Headband": 46
"Eyes": 47
"Beard": 48
"Mouth": 49
"Neck": 50
"Ring": 51
"Scalp": 52
"Decapitation": 53
"Unnamed 54": 54
"Unnamed 55": 55
"Unnamed 56": 56
"Unnamed 57": 57
"Unnamed 58": 58
"Shield": 59
"Pipboy": 60
"FX": 61
"Head Meatcap": 100
"Body Meatcap": 101
"Calf.L": 0x4630dac2
"Calf.R": 0x22324321
"Foot.L": 0xa3e42571
"Foot.R": 0xc7e6bc92
"Hand.L": 0xD5EECA9A
"Hand.R": 0xB1EC5379
"Head": 0x86b72980
"HP-Neck": 0x3D6644AA
"Lo Arm.L": 0x212251d8
"Lo Arm.R": 0x6fc3fbb2
"Neck": 0x0155094f
"Thigh.L": 0x865d8d9e
"Thigh.R": 0xbf3a3cc5
"Up Arm.L": 0xfc03dc25
"Up Arm.R": 0xb2e2764f
"Ghoul Up Arm.R": 0x2a549ee1
"Ghoul Lo Arm.R": 0xf775131c
"Ghoul Hand.R": 0x85342e3c
"Ghoul Up Arm.L": 0x4e560702
"Ghoul Lo Arm.L": 0x93778aff
"Ghoul Hand.L": 0x5ae407df
"Death Claw Neck": 0xc0f43cc3
"Death Claw Up Arm.R": 0xf2ba1077
"Death Claw Elbow.R": 0xf4e10d0d
"Death Claw Hand.R": 0xe2da5319
"Death Claw Up Arm.L": 0x17932e95
"Death Claw Elbow.L": 0x0861e2c0
"Death Claw Hand.L": 0x8beb7000
"Ghoul Thigh.R": 0x9af9d18c
"Ghoul Calf.R": 0x8e0daa93
"Ghoul Foot.R": 0x6bd95520
"Ghoul Thigh.L": 0xa325b267
"Ghoul Calf.L": 0x51dd8370
"Ghoul Foot.L": 0xb4097cc3
"Mut Hound Fr Up Leg.L": 0x99338c09
"Mut Hound Fr Lo Leg.L": 0x7491a630
"Mut Hound Fr Foot.L": 0x8a99ba3f
"Mut Hound Bk Thigh.L": 0xa7860026
"Mut Hound Bk Knee.L": 0xaf6a52d7
"Mut Hound Bk Ankle.L": 0xb42c3610
"Mut Hound Bk Foot.L": 0x6e284ec0
"Mut Hound Bk Thigh.R": 0x0e97871c
"Mut Hound Bk Knee.R": 0x02433b3b
"Mut Hound Bk Ankle.R": 0x1d3db12a
"Mut Hound Bk Foot.R": 0x20c9e4aa
"Mut Hound Fr Up Leg.R": 0x5f96443c
"Mut Hound Fr Lo Leg.R": 0xdd80210a
"Mut Hound Fr Foot.R": 0x4c3c720a
"Mirelurk Fr Up Arm.R": 0xa5f4be71
"Mirelurk Fr Lo Arm.R": 0x99eb64eb
"Mirelurk Claw.R": 0x3c9df64f
"Mirelurk Shoulder.L": 0x40f66ca4
"Mirelurk Up Arm.L": 0xc1f62792
"Mirelurk Elbow.L": 0xf0da47f2
"Mirelurk Claw.L": 0x55acd556
"Mirelurk Fr Hip.R": 0x064f59cd
"Mirelurk Fr Thigh.R": 0x5b033df6
"Mirelurk Calf.R": 0x15fc7bad
"Mirelurk Foot.R": 0xf028841e
"Mirelurk Hip-Thigh.L": 0xf62a541a
"Mirelurk Kne-Clf.L": 0x5b1dd1c7
"Mirelurk Fr Foot.L": 0xbec92e74
"Mirelurk Bk Hip-Thigh.R": 0xfc5546b8
"Mirelurk Bk Kne-Clf.R": 0x24a15449
"Mirelurk Bk Foot.R": 0xc175abfa
"Mirelurk Bk Hip-Thigh.L": 0xb2b4ecd2
"Mirelurk Bk Kne-Clf.L": 0xc1886aab
"Mirelurk Bk Foot.L": 0x245c9518
"Dog Fr Knee.L": 0x5530c47b
"Dog Fr Calf.L": 0xcc3995c1
"Dog Fr Heel+Arch.L": 0xbd2750cf
"Dog Fr Paw.L": 0x77fe1ec8
"Dog Bk Knee.L": 0x52f7244b
"Dog Bk Calf.L": 0xcbfe75f1
"Dog Bk Heel+Arch.L": 0xfe31ace4
"Dog Bk Paw.L": 0x08eb5fa0
"Dog Bk Knee.R": 0x8d270da8
"Dog Bk Calf+Heel.R": 0x142e5c12
"Dog Bk Arch.R": 0x9a333507
"Dog Bk Paw.R": 0x61da7cb9
"Dog Fr Knee.R": 0x8ae0ed98
"Dog Fr Calf.R": 0x13e9bc22
"Dog Fr Heel+Arch.R": 0xd925c92c
"Dog Fr Paw.R": 0x1ecf3dd1
"Behemoth Arm+Elbow.R": 0x8c5ae189
"Behemoth 4 Arm.R": 0x071dfd97
"Behemoth Hand.R": 0xded0fadf
"Behemoth Arm+Elbow.L": 0xc2bb4be3
"Behemoth 4 Arm.L": 0x3e7a4ccc
"Behemoth Hand.L": 0xe7b74b84
"Behemoth Calf.R": 0xa411c600
"Behemoth Foot.R": 0xac900af3
"Behemoth Calf.L": 0xc0135fe3
"Behemoth Foot.R": 0x95f7bba8
"Robot 3 Torso": 0x3d6644aa
FO4 Seg 000
FO4 Seg 001 | Head | Head
FO4 Seg 002
FO4 Seg 003 | HP-Neck | Neck
FO4 Seg 000
FO4 Seg 001
FO4 Seg 002 | 000 | Up Arm.R
FO4 Seg 002 | 001 | Up Arm.R
FO4 Seg 002 | 002 | Up Arm.R
FO4 Seg 002 | 003 | Lo Arm.R
FO4 Seg 003
FO4 Seg 004 | 000 | Up Arm.L
FO4 Seg 004 | 001 | Up Arm.L
FO4 Seg 004 | 002 | Up Arm.L
FO4 Seg 004 | 003 | Lo Arm.L
FO4 Seg 005 | 000 | Thigh.R
FO4 Seg 005 | 001 | Thigh.R
FO4 Seg 005 | 002 | Thigh.R
FO4 Seg 005 | 003 | Calf.R
FO4 Seg 005 | 004 | Foot.R
FO4 Seg 006 | 000 | Thigh.L
FO4 Seg 006 | 001 | Thigh.L
FO4 Seg 006 | 002 | Thigh.L
FO4 Seg 006 | 003 | Calf.L
FO4 Seg 006 | 004 | Foot.L