Transferring a costume with new physics bones - eArmada8/ed8pkg2gltf GitHub Wiki
Transferring a costume with new physics bones
In my previous tutorial, we transferred a costume from one character to another, and we removed the extra bones that were not available on that model. Specifically, I removed LeftChest and RightChest from Tita's swimsuit, since Tita's model does not have chest physics. But what if we wanted to preserve those physics? We can!
So today we are going to explore an alternate way to port a costume, where we move parts of the skeleton from one character to another. It is expected that you have already done the previous tutorial.
Towa has lost a friendly bet to Rean, and today she must do all her teaching in a student uniform.
Identifying bones
To my knowledge, most of the bones of a skeleton are used exclusively by the animators, and if those bones are not present on the recipient model, then we are out of luck. Luckily, many of the bones are primarily manipulated by the physics system instead. These bones (like the skirt bones, hair bones, chest bones, etc), are capable of moving subtly by themselves, which means that preserving them does preserve some of their natural motion with gravity and the wind. They also tend to either not have children, or their children are also physics bones, which makes porting them very easy.
To demonstrate this, I will give Towa a skirt with physics. I will be using Towa (C_CHR041.pkg) as a recipient, and Altina (C_CHR015.pkg) as a donor.
To start, obtain and decompile both models. Identify the missing bones, but do not merge or delete them.
You will notice that I am actually missing quite a few bones, including FS01, Left and RightSA01, Left and RightSB01, BS01, and the 02 versions of those bones. These are all skirt bones, and they are all physics bones. (If you open up the .inf file for the model they come from {chr015.inf}, you will see many physics parameters which govern their spontaneous / calculated motion.) Towa’s model does not have skirt physics, so we will need to add them. Note that while she does not have skirt physics, this technique can also be adapted to fix incompatible physics (e.g. changing Rixia’s skirt physics to Juna’s).
Examining chr015.glb, you can see where these bones come from. You can see all those bones are bound directly to the hips. In the previous tutorial, we would have deleted all these groups, and transferred their weights to Hips. This method is still valid, but it will result in a completely stiff skirt that only moves with the hips.
This time we want to preserve the skirt physics, so we will actually add these bones to Towa’s skeleton.
NOTE: I am following the prior tutorial to identify bones by deleting vertex groups and locking them - but there is no need to save your work because we will not use any of these meshes! This is only for planning. Do not bother to copy files, delete files, backup files, etc. Just open them in Blender, examine them, and take notes.
First, let us make a list of bones that we are transferring, and their parents. Repeating the steps of the other tutorial, I have deleted parts of Altina’s meshes that I will not use (like hair ties). I will be keeping Towa's original legs, so Altina’s legs are also deleted. I then use "Lock groups using VGMap" and "Delete empty (unlocked) vertex groups" similarly to the other tutorial. I am left with 12 groups that I am transferring.
FS01 - child of Hips
FS02 - child of FS01
LeftSA01 - child of Hips
LeftSA02 - child of LeftSA01
LeftSB01 - child of Hips
LeftSB02 - child of LeftSB01
RightSA01 - child of Hips
RightSA02 - child of RightSA01
RightSB01 - child of Hips
RightSB02 - child of RightSB01
BS01 - child of Hips
BS02 - child of BS01
Note: If you are doing this tutorial with exactly this same model set (C_CHR015->C_CHR041), you might notice that I removed Altina's shoulder pad/shawl thing. Why? There are quite a few groups like sm_01 and Left_smA_01, which correspond to the shoulder pad. However, these do not have physics parameters in the .inf file, and are animated by hand. Therefore they are not good candidates for bone transfer, unless you are prepared to animate them by hand.
Finally, I made a plan to keep meshes 01-07, 11 and 13 from C_CHR041 (Towa). I will keep meshes 02-03, 07-09 from C_CHR015 (Altina).
Transferring bones
Now it is time to transfer the bones from Altina's skeleton to Towa's. First, prepare your work folder (C_CHR041). Delete the meshes folder entirely, we will not use it.
Backup metadata.json. We will need the information from it. Remove it from the work folder.
In Blender, start with a new, empty workspace (File -> New -> General). If you have the default objects, remove those.
Import chr041.glb with Bone Dir set to "Blender (best for re-importing)". Do not rename this model, it should remain VisualSceneNode because that is what the game expects.
Import chr015.glb with the same settings. Optional: Name it Altina, to reduce confusion.
NOTE: Be sure to import your recipient first, then your donor! Certain duplicate structures are automatically renamed by Blender to avoid conflicts, and we do not want anything in the recipient renamed.
Scale your donor model to match your recipient model. Object -> Transform -> Scale, then pull the mesh until neck lines up with the head. Then apply your changes (Object -> Apply -> Scale). (Since we are transferring the skirt bones, it is arguably most important to match the level of the hips, but this can be hard to see.)
Expand out Altina's entry and select the Armature. (Armature.001, under up_point.001 in the picture)
Go into Edit Mode. Then expand out the entire skeleton, and select all the skirt bones at once. (Click on FS01, then SHIFT-click on BS02. Be sure to do this in the Outliner, because the inner bones are hidden inside her mesh!)
Note that the parent of FS01 is Hips. You must start with a bone that is attached to a bone that already exists on your recipient model! We start with FS01 because Towa does have Hips. We cannot start with FS02 because Atina does not have FS01, which is the parent of FS02.
Separate the skirt bones away from Altina. (Armature menu -> Separate Bones)
You should now see a new skeleton, up_point.002, that only contains your skirt bones.
Go into Object Mode. Select up_point.002, then select Towa’s skeleton (up_point). (Towa's skeleton should be outlined in orange, and Altina's in red) Join the skirt bones to Towa's model (Object menu -> Join). As always, be careful of the join direction: A->B is not the same as B->A! up_point.002 should be gone, and Towa’s up_point should remain.
The skirt bones are now part of Towa's Armature, but they are not yet properly attached to the skeleton (FS01, etc should be a child of Hips). Select Towa's armature, and once again go into Edit Mode.
In Edit Mode, in the Outliner, click on FS01, Ctrl-click on the other 5 root skirt bones, then finally Ctrl-click on Hips. (The final bone you click will be the new parent of all the other bones you clicked.) Note: You can try to do this in the 3D viewport, but it would be difficult since you cannot see either the root skirt bones or Hips with meshes in the way.
Parent the skirt bones to Hips. (Armature menu -> Parent -> Make.) When presented with the options, select Keep Offset.
The skirt bones have now been attached to Towa's skeleton!
Transferring meshes from the donor to the recipient
The skeleton is now ready to receive meshes. Go into Object mode. Delete the meshes from your recipient that you are not going to keep. Here, I am deleting 00, 08-10, and 12.
We are now going to fuse the remaining meshes into a single mesh with separate submeshes. Rename the first remaining mesh (01), removing the suffix - both the node (orange triangle) and the mesh (green triangle) should be renamed from polySurface5056_01
to polySurface5056
.
Select all the meshes except polySurface5056 (click, Shift-click), then select polySurface5056 last (Ctrl-click). Join the meshes. (Object Mode -> Object Menu -> Join, or Ctrl-J).
Note: In the screenshot above, you can see that the original polySurface5056 (directly underneath VisualSceneNode) has been automatically renamed to polySurface5056.001 when we gave the polySurface5056 name to our mesh node. You can safely delete polySurface5056.001, or leave it in place. Either way, the game will use the correct node.
polySurface5056 should now have 9 submeshes.
Now join the meshes that you intend to keep from Altina (02,03,07,08,09) to polySurface5056. polySurface5056 should now have 14 submeshes.
Select Altina (whatever is left of her) and Delete Hierarchy to remove the remainder of the model. When you export, you want to export only a single model, since the game (and my scripts) only accept single models.
Export as a new .glb file (File menu -> Export -> glTF 2.0). Turn on Tangents export (Geometry -> Mesh -> Tangents). Here I just kept the default name of untitled.glb.
Extracting meshes and making metadata
Remember when we deleted metadata.json the meshes folder? It is time to fill that folder with the assets from untitled.glb. We want to have complete .vgmaps for this next step, so edit extract_from_gltf.py and change line 13 complete_vgmaps_default
to True.
From the command line, run extract_from_gltf.py on your new .glb file. python extract_from_gltf.py untitled.glb
(Or you can double click extract_from_gltf.py and it will attempt to work on every .glb file it finds. Just ignore then output of chr041.glb.)
Go into the new untitled
folder, and copy the meshes folder and metadata.json into the main work folder.
Open up the skeleton metadata.json. Replace name
and pkg_name
with the correct entries from the original metadata.json (not shown). This is the skeleton materials
section, grab the real entries from the original metadata.json files from C_CHR041 (Towa) and C_CHR015 (Altina) and replace these useless entries with the real entries.
Keep the heirarchy
section.
Replace the locators
section with the real section from C_CHR041 (Towa), the recipient.
Finishing the model
There is still work to do, changing texture colors, bonding the head to the neck, customizing the model, etc. However, now is a good time to make sure our model works.
Copy all the textures (*.dds) and compiled shaders (ed8_chr.fx#****) that you need from your donor (Altina) to your work folder. I just copied all the textures and all the shaders (skipping duplicates) because the compile scripts will not incorporate unneeded files into the final model.
Recompile the model. If you followed every step correctly, you should now have a working model!
As you can see, there are a bunch of duplicate meshes because we have not yet edited any of our meshes. For example, I want to keep Altina's hands, but they are in the same submesh as her legs, which I need to delete.
However, we will no longer be working with the full glb model. Save your work as a .blend file, and then open a new blank workspace in Blender. Import all your .ib/.vb files.
You can now proceed with removing all the parts of the meshes you do not need from meshes, connecting the donor and recipient meshes, and modifying textures, etc.
Here is the mod after removing all the extra mesh that we did not need!
Implementing the physics
The model should have been compiled properly and is technically useable in the game. However, for physics to happen, you will need to inform the game engine of the physics bones. This is done in the .inf file.
Open both chr041.inf and chr015.inf. These are usually either in the {CS3/CS4/Reverie}/data/chr folder or the {CS3/CS4/Reverie}/data/dlc/chr folder.
Transfer over the needed physics sections (both springJoint sections and the controlUniqueJoint sections) that you need, both for your new bones and the bones they are dependent on. (For example, you might think you only need FS02 if your prior model has FS01, but you will actually want to replace the old FS01 with the new FS01 and FS02, so the physics will behave the way you expect for your new mesh!) If there are any relevant IK sections (inverse kinematics), you can copy those too.
In my case, since I am compiling the new model is C_CHR041_C05.pkg, I will name my new .inf file as chr041_c05.inf. Since I plan to make this a DLC and have already changed my xml to point to the dlc folder, I saved this file as {CS3/CS4/Reverie}/data/dlc/chr/chr/chr041_c05/chr041_c05.inf.
Tah-dah! Notice Towa's skirt gently swaying in the breeze!