Skip to content

Commit

Permalink
Wiki, unnecessary type cast
Browse files Browse the repository at this point in the history
  • Loading branch information
ilmheg committed Apr 24, 2022
1 parent b8b5628 commit a17a88e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 145 deletions.
2 changes: 1 addition & 1 deletion MultiAssist.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ def _run(self):

dpg.add_button(label="Save settings", callback=lambda:self._save_settings())

dpg.add_menu_item(label="Help", callback=lambda:webbrowser.open('https://github.com/ilmheg/MultiAssist/blob/main/README.md'))
dpg.add_menu_item(label="Wiki", callback=lambda:webbrowser.open('https://github.com/ilmheg/MultiAssist/wiki/2.-Using-MultiAssist'))
dpg.add_menu_item(label=" ", enabled=False) # one right align pls
dpg.add_menu_item(label="Alternative Blender Addon (by 0ceal0t)", callback=lambda:webbrowser.open('https://github.com/0ceal0t/BlenderAssist'))
with dpg.group(horizontal=True):
Expand Down
162 changes: 25 additions & 137 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
![mabanner](gh/banner.png)
# MultiAssist
<p>
<img align="right" width="300" src="https://user-images.githubusercontent.com/103583531/164975695-d08aa30d-5bb8-403b-b4bb-927dadeb906a.png" />
Upon opening MultiAssist, you'll see the MultiAssist GUI with the "Extract" tab selected. You can resize this window however you like, however it was designed for use at its default size.
</p>

[AnimAssist](https://github.com/lmcintyre/AnimAssist) GUI with support for repacking .pap files with multiple animations, minor bug fixes, and more extensive export options, including FBX. It can also be used without the GUI through command line arguments.

This project assists in the editing of FFXIV animation files.
Expand All @@ -8,23 +13,16 @@ I started this fork so I had a quick way to extract some animation data from XIV

Essentially everything good in this project comes from Perchbird's work, everything bad in this project is probably by me.

Using **Blender**? Consider checking out [0ceal0t's BlenderAssist](https://github.com/0ceal0t/BlenderAssist)! Another tool that utilizes animassist and fbx2havok to achieve similar things to this project, in a Blender addon!

# Table of Contents
- [Prerequisites](#prerequisites)
+ [Required software](#required-software)
+ [Recommended software](#recommended-software)
+ [Optional Software](#optional-software)
- [Installation and Usage](#installation-and-usage)
* [Installation](#installation)
* [Extracting an animation](#extracting-an-animation)
* [Editing your exported animation](#editing-your-exported-animation)
* [Repacking your edited animation](#repacking-your-edited-animation)
* [Getting your edited animation back into FFXIV](#getting-your-edited-animation-back-into-ffxiv)
- [Command Line Usage](#optional-command-line-usage)
- [Technical rundown of the process](#technical-rundown-of-the-process)
- [Future development plans for MultiAssist](#future-development-plans-for-multiassist)
- [Building, contributions, and notes](#building-contributions-notes)

<p align="center">
<img width=400 src="https://user-images.githubusercontent.com/103583531/164982393-3df386b5-51af-4fc6-adff-85f47e7728c2.gif" width="600" />
<p align="center">
Au Ra with Crash Bandicoot's run, made with .fbx exports.
</p>
</p>

# Getting Started
Visit [the project's wiki](https://github.com/ilmheg/MultiAssist/wiki) for guides on MultiAssist and demonstrations of animation editing for XIV!

# Prerequisites
### Required software
Expand Down Expand Up @@ -54,132 +52,19 @@ Using **Blender**? Consider checking out [0ceal0t's BlenderAssist](https://githu
* [VFXEditor](https://github.com/0ceal0t/Dalamud-VFXEditor)
* Way to edit the timeline section of animation files, among many other things.

# Installation and Usage
## Installation
# Installation
To install MultiAssist, head to [Releases](https://github.com/ilmheg/MultiAssist/releases) and download the latest MultiAssist.zip. Extract the files to an accessible location and run MultiAssist.exe to use the GUI. Do not remove any of the extracted files in this folder.

Make sure you have looked at the [Required software](#required-software) and have installed VC++2012 32-bit Redist.

## Extracting an animation


### Extracting raw animation and skeleton files from XIV
For demonstration purposes, we will use FFXIV Explorer to export our animations and skeleton files. If it's your first time using FFXIV Explorer, make sure your FFXIV Path is set in Options > Settings > FFXIV Path.

Most animations you will want to edit are located in 040000.win32.index. To open this in FFXIV Explorer navigate to File > Open and select 040000.win32.index.

The contents of this index file are divided into folders such as chara/human and chara/monster. Skeletons will generally be located at `chara/{category}/{type_char}{id}/skeleton/base/b0001/skl_{type_char}{id}b0001.sklb`.


For a quick reference on the different human folders, take a look at this table.

| Race/Gender | Folder | Notes |
| ------------------|----------------------| -------|
| Hyur Midlander M | chara/human/c0101/ | A lot of emotes use the Hyur male skeleton, and thus will be found near the Hyur male folder.
| Hyur Midlander F | chara/human/c0201/ |
| Hyur Highlander M | chara/human/c0301/ |
| Hyur Highlander F | chara/human/c0401/ |
| Elezen M | chara/human/c0501/ |
| Elezen F | chara/human/c0601/ |
| Miqote M | chara/human/c0701/ |
| Miqote F | chara/human/c0801/ |
| Roegadyn M | chara/human/c0901/ |
| Roegadyn F | chara/human/c1001/ |
| Lalafell M | chara/human/c1101/ | Also the location of most Lalafell F animations.
| Lalafell F | chara/human/c1201/ |
| Au Ra M | chara/human/c1301/ |
| Au Ra F | chara/human/c1401/ |
| Hrothgar M | chara/human/c1501/ |
| Hrothgar F | | c1601 (probably)
| Viera M | chara/human/c1701/ |
| Viera F | chara/human/c1801/ |

Animation files always have the `.pap` extension. It can sometimes be difficult to determine which skeleton an animation uses. MultiAssist will warn you if there is a mismatch between the skeleton and the skeleton the animation file was built with. Animation files will usually be nested within an `/animation/` folder. Emotes will generally be further within a `bt_common` folder, for example `chara/human/c0101/animation/bt_common/emote` for most Male Hyur emotes.

Finding non-human files is a broader topic, however, searching for a mount/minion/etc. in TextTools will provide you with an id within its material/model paths that should provide sufficient information. If Fatter Cat's material path is `chara/monster/m0512/obj/body/b0001/texture/v01_m0512b0001_d.tex` you would know Fatter Cat related files will be under `chara/monster/m0512/`, for example.

For this demonstration, I will be exporting the Fatter Cat skeleton and animation file. The basic animations for a mount are stored within a `mount.pap`. To grab this file, navigate to and select `chara/monster/m0512/animation/a0001/bt_common/resident/mount.pap` in FFXIV explorer. With it selected, select File > Extract Raw (Or press Ctrl+Shift+E) and select your save directory. It is essential that you extract this file as a raw file.

The skeleton for Fatter Cat is listed under `chara/monster/m0512/skeleton/base/b0001/skl_m0512b0001.sklb`. We just need the .sklb file, so select it and extract the raw file again.

With both the .sklb skeleton file and .pap animation file extracted, we can move to MultiAssist. You may wish to move the files to a more convenient location. Note that the .pap and .sklb files will be nested within the same folder layout as described in FFXIV Explorer after extracting.


### Exporting editable animation files with MultiAssist
After extracting our animation and skeleton files, we can finally open `MultiAssist.exe` to extract an editable animation file.

With the Extract tab selected, we first select our .pap and .sklb files. You can select these with the in-app file explorer by pressing \[...\] or by typing in a path manually.

With the paths to the respective files set, press \[Submit\] to populate the animations list in the lower left corner. If your .pap only has one animation in it, only a single animation will be displayed here, otherwise, select the animation you wish to extract. If you change the .pap file at any point, make sure to press \[Submit\] once again.

The export options in the lower right corner allow you to select the file type and path of your exported animation file. I'll select .fbx and name my animation file export. Select your export directory and press \[Export\] to begin exporting the file. This should be a very quick process.

Please make sure you have everything correctly inputted before pressing \[Export\]. If successful, there will be a success dialog displaying the export directory.

![j](gh/etab.png)

## Editing your exported animation
### FBX
#### ***NOTE ON FBX SUPPORT:***
*fbx2havok is an older proof-of-concept project by Perchbird, provided mostly as is. The build in this project makes a number of changes for ease of use in Blender and prevents re-imported animations from being glitchy. If something goes wrong, keep the unpolished nature of this in mind. I am interested in any errors you encounter using this method.*
# Note on FBX support:
fbx2havok is an older proof-of-concept project by Perchbird. The build in this project makes a number of changes for ease of use in Blender and prevents re-imported animations from being glitchy. If something goes wrong, keep the unpolished nature of this in mind. I am interested in any errors you encounter using this method.

The exported file can be imported into your 3D editor of choice. Make sure you import the right one. If you are using 3DS max you should see `Animation Take: Havok Frames` when importing. The default import settings should be correct for 3DS Max. In Blender, you'll likely want to set `Transform: Scale` to `100.0`.
In the current release, please use blender, either as a middle-man, or for all FBX editing.

Make as many edits to your animations as you'd like, and export the file as an FBX once again. Make sure Bake Animation is selected, and if you have multiple objects in your scene, make sure to only export the animated armature.
I am very interested in the progression of this and am working on ironing out remaining issues with FBX exports.

With the edited FBX, we can proceed to repacking the file.

### HKX (Packfile) \[HavokMax\]

From the [AnimAssist README.md](https://github.com/lmcintyre/AnimAssist/blob/main/README.md)
> Open 3DS Max and check the Plug-in Manager to ensure HavokMax is properly installed.
> From the Max menu, click Import and select your output_file.hkx from the previous step to open it in 3DS Max. Select disable scale, invert top, and set Back: Top. Click import, and you'll get a wonderful fistbumping skeleton, read directly from what was once game files.
> You have some sweet changes to some animation, but now we need to put it back into the game.
> From the Max menu, click Export and type any filename you want, and save it in a cool, dry place. In the "Save as type" drop-down, select "Havok Export (*.HKA, *.HKX, *.,HKT)". We will be saving an hkx file once more. Export your file, again, selecting disable scale, invert top, and set Back: Top. You must select those, as well as Export animation and include skeleton. Set toolset to 2014. In my testing, I found that it was optional, however, it seems safest to disable optimize tracks according to user reports.

### Other export formats (havok binary tagfile and XML)
Not properly implemented yet. The XML file will contain all animations if more than one is present.
These probably aren't super useful. Both files (and the .hkx packfile) can be opened in Havok Standalone Tools, but probably not much else. I consider the xml file useful for debugging. At the current time, these two formats cannot be repacked into a .pap with MultiAssist.

## Repacking your edited animation
With an edited and exported .fbx or .hkx, repackaging the animation is simple.

As with the extraction process, select your .pap and .sklb file. These should be the same, unedited files you used to extract the animation from. You may re-extract these files from FFXIV if you have lost them.

Select your edited .fbx or HavokMax export, and press submit to populate the animation list. You should select the animation you want to replace. This can technically be any animation, but generally you will want to replace the same animation you extracted.

Enter a name and export directory into the Export options and press \[Repack\]. As always, make sure you fill out every field before pressing \[Repack\].

![repack_tab](gh/rtab.png)

### Getting your edited animation back into FFXIV
The resulting .pap file can be imported into FFXIV through TexTools by using the raw file operations (Tools > Raw File Operations > Import Raw File), leaving Decompressed Type 2 Data checked, or by placing it in the right place in penumbra.

The destination you will be importing your .pap into will generally be the same as the location you extracted it from. Include the file name and extension, and make sure you use forward slashes ("/") when entering your destination path.

For the Fatter Cat, in TexTools you would enter `chara/monster/m0512/animation/a0001/bt_common/resident/mount.pap` as the destination, then press \[Import File\] to select your new .pap file. It doesn't matter what your new .pap file is named, as long as it is imported to the right place.

If the game loads the animation fine, it's successful! If it crashes or otherwise, something probably went wrong, either while editing the animation or within AnimAssist.

# (Optional) Command Line Usage
This project maintains the command line functionality of AnimAssist, both within animassist.exe and MultiAssist.exe. Using command line arguments will not initialize the GUI and at this point probably has better error reporting than the GUI. Here's a basic rundown of the commands, refer to the above [Installation and Usage](#installation-and-usage) for further information.

### Extracting
`multiasisst.exe extract -s original_skeleton_file.sklb -p original_pap_file.pap -a modified_animation.hkx -i <animation index> -o new_ffxiv_animation.pap -t <file type>`

where `<file type>` is one of:
* fbx
* hkxp
* hkxt
* xml
### Repacking
`multiasisst.exe pack -s original_skeleton_file.sklb -p original_pap_file.pap -a modified_animation -i <index to replace> -o new_ffxiv_animation.pap`

Furthermore, you can use the original AnimAssist commands with `aextract` and `apack` and the respective original arguments. Please note that the original commands do not support multi-pap repacking, but do retain some minor fixes in the extraction process.

# Technical rundown of the process
### Extraction
Expand All @@ -196,14 +81,17 @@ Furthermore, you can use the original AnimAssist commands with `aextract` and `a
* XML - Uses animassist.exe and the havok data from step 1 to return an XML file with the same format as Havok Preview Tool exports.

### Repackaging
In short, the files end up as the XML export format discussed in the final step of extraction. From this, the animation and binding of the modded animation replace the animation and binding of the user inputted animation index. The merged XML is passed back to animassist.exe where it is converted into a binary tagfile. The header is regenerated with new offsets and the timeline data is copied from the original .pap into the new export.
This is almost completely handled by animmassist.exe and the Havok.sdk now. The old process used conversion to XML and literally merged the Animation object and Binding object with the old file.

Now, the process is similar, just done in one step through the Havok SDK.

### Changes to HAVOK2FBX2HAVOK
* Doesn't set axis orientation
* Exports directly to binary
* Sets customframerate = 30
* Experimental optional fix for certain components not animating when exported (nnumberoftracks = numberofbones)
* Outputs uncompressed animations (Optionally compressed in future release)
* Outputs uncompressed animations
* Predictive compression available through animassist.exe

# Future development plans for MultiAssist
I hope to continue supporting this project. In the near future I will improve input validation and error reporting within the GUI. Additionally, I am looking for ways to further streamline the process in the more distant future, such as exporting directly to penumbra. Less generally, I believe direct animation swapping and features of a similar vein are also within the scope of this project.
Expand Down
11 changes: 4 additions & 7 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ int main(int argc, const char** argv) {
// 3 = skl + anim -> out hk*
// 4 = skl + anim -> xml packfile
// 5 = xml packfile of anim -> binary tagfile
// 6 = skl + anim - > binary tagfile
// 7 = anim - > additive tagfile
// 8 = mod_anim + anim - > binary tagfile
// 6 = skl + anim - > binary tagfile
// 7 = anim - > additive tagfile
// 8 = mod_anim + anim - > binary tagfile
// 9 = anim - > predictive compressed animation tagfile
int mode = _wtoi(nargv[1]);

Expand Down Expand Up @@ -188,7 +188,7 @@ int main(int argc, const char** argv) {
rinput.m_numTransformTrackToBoneIndices = bind_ptr->m_transformTrackToBoneIndices.getSize();
*/

hkaAdditiveAnimationUtility::Input input;
hkaAdditiveAnimationUtility::Input input;
input.m_numberOfPoses = w->m_transforms.getSize() / w->m_numberOfTransformTracks; //frames
input.m_numberOfTransformTracks = w->m_numberOfTransformTracks;
input.m_originalData = w->m_transforms.begin();
Expand Down Expand Up @@ -217,12 +217,9 @@ int main(int argc, const char** argv) {
res = hkSerializeUtil::saveTagfile(anim_root_container, hkRootLevelContainer::staticClass(), stream.getStreamWriter(), nullptr, hkSerializeUtil::SAVE_DEFAULT);
} else if (mode == 9) {
auto* anim_container = reinterpret_cast<hkaAnimationContainer*>(anim_root_container->findObjectByType(hkaAnimationContainerClass.getName()));
hkaAnimation* anim_ptr = anim_container->m_animations[0];
auto binding_ptr = anim_container->m_bindings[0];
auto binding = *anim_container->m_bindings[0];
auto skl = *anim_container->m_skeletons[0];
hkaInterleavedUncompressedAnimation* uncompressed_anim = static_cast<hkaInterleavedUncompressedAnimation*>(anim_ptr);


/*
hkaPredictiveCompressedAnimation::TrackCompressionParams track_params;
Expand Down

0 comments on commit a17a88e

Please sign in to comment.