Skip to content

[OoT] Add support for importing/exporting SkinLimbs - #720

Merged
Dragorn421 merged 9 commits into
Fast-64:mainfrom
SlimyGooblin:main
Aug 15, 2026
Merged

[OoT] Add support for importing/exporting SkinLimbs#720
Dragorn421 merged 9 commits into
Fast-64:mainfrom
SlimyGooblin:main

Conversation

@SlimyGooblin

Copy link
Copy Markdown
Contributor

This PR adds support for importing/exporting to C the limbs and meshes used by Epona and other horses in OoT
There's nothing particularly special about how OoT handles smooth skinning so imports and exports work by just using an armature modifier
Currently the exporter is set up to export any mesh that has multiple weights per vertex in the format used by skinlimbs

To test out the importer you can change Import Skeleton settings to:

  • Skeleton: gEponaSkel
  • Object: object_horse
  • Overlay: ovl_En_Horse

@Dragorn421 Dragorn421 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! this has been attempted before without success, nice that you got it (I didn't test yet, just glanced at the code a bit)

Comment thread fast64_internal/f3d/f3d_gbi.py
Comment thread fast64_internal/f3d/f3d_gbi.py Outdated
Comment thread fast64_internal/f3d/f3d_parser.py Outdated
Comment thread fast64_internal/f3d/f3d_parser.py Outdated
Comment thread fast64_internal/f3d/f3d_writer.py
Comment thread fast64_internal/z64/exporter/skeleton/classes.py Outdated
SlimyGooblin and others added 2 commits August 8, 2026 10:07
Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>

@Dragorn421 Dragorn421 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UX note: I think it would be better to add an entry to the skeleton import/export "Mode" that spells "Skin (horses)" in order to import/export cpu-skinned skeletons.

Currently the switch between skin and standard limbs is made based on having multi-assigned vertices (cf ootDetermineLimbType), but that would probably be surprising to a user who expects the much more common (possibly flex) skeletons. Also the skin skeletons should be avoided as they seem more expensive, so it should be an opt-in rather than an automatic choice

Comment thread fast64_internal/z64/skeleton/importer/skinLimb_parser.py
Comment thread fast64_internal/z64/skinLimb_parser.py Outdated
@SlimyGooblin

Copy link
Copy Markdown
Contributor Author

UX note: I think it would be better to add an entry to the skeleton import/export "Mode" that spells "Skin (horses)" in order to import/export cpu-skinned skeletons.

Currently the switch between skin and standard limbs is made based on having multi-assigned vertices (cf ootDetermineLimbType), but that would probably be surprising to a user who expects the much more common (possibly flex) skeletons. Also the skin skeletons should be avoided as they seem more expensive, so it should be an opt-in rather than an automatic choice

Yeah, I was thinking about that too
How about adding a bone property that gets set on import? That way it can be tied to the armature instead of being a global setting
It'll obscure the setting a bit, but I figure it's not something that would be changed much

@Dragorn421

Copy link
Copy Markdown
Contributor

I guess an armature property could work yeah

@Dragorn421 Dragorn421 added enhancement New feature or request oot Has to do with the Ocarina of Time 64 side labels Aug 11, 2026

@Dragorn421 Dragorn421 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested epona skeleton import and animation import, works beautifully
Tested epona skeleton export and animation export, also works

Tested various oot things on blender 3.2 and 4.2

  • flex skeleton import/export and anim import/export works
  • scene import is broken, eg this is on importing deku tree:
Traceback (most recent call last):
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/scene/operators.py", line 102, in execute
    run_ops_without_view_layer_update(parseSceneFunc)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/scene/operators.py", line 28, in run_ops_without_view_layer_update
    func()
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/scene/operators.py", line 36, in parseSceneFunc
    parseScene(settings, settings.option)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/importer/scene.py", line 195, in parseScene
    sceneObj = parseSceneCommands(sceneName, None, None, sceneCommandsName, sceneData, f3dContext, 0, sharedSceneData)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/importer/scene_header.py", line 574, in parseSceneCommands
    roomObjs = parseRoomList(sceneObj, sceneData, roomListName, f3dContext, sharedSceneData, headerIndex)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/importer/scene_header.py", line 258, in parseRoomList
    roomObj = parseRoomCommands(
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/importer/room_header.py", line 117, in parseRoomCommands
    parseMeshHeader(roomObj, sceneData, meshHeaderName, f3dContext, sharedSceneData)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/importer/room_shape.py", line 38, in parseMeshHeader
    parseMeshList(roomObj, sceneData, meshListName, roomShapeIndex, f3dContext, sharedSceneData)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/importer/room_shape.py", line 132, in parseMeshList
    meshObj = importMeshC(
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/f3d/f3d_parser.py", line 2392, in importMeshC
    parseF3D(data, name, transformMatrix, name, name, drawLayer, f3dContext, True)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/f3d/f3d_parser.py", line 2033, in parseF3D
    f3dContext.processCommands(dlData, processedDLName, dlCommands)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/f3d/f3d_parser.py", line 1613, in processCommands
    self.addTriangle(command.params[0:3] + command.params[4:7], dlData)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/f3d/f3d_parser.py", line 755, in addTriangle
    verts = [self.getTransformedVertex(math_eval(index, self.f3d)) for index in indices]
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/f3d/f3d_parser.py", line 755, in <listcomp>
    verts = [self.getTransformedVertex(math_eval(index, self.f3d)) for index in indices]
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/model_classes.py", line 982, in getTransformedVertex
    position, normal = self.getVertexTransforms(bufferVert, has_normal, has_packed_normals)
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/model_classes.py", line 964, in getVertexTransforms
    transform = self.matrixData[self.getLimbName(limbIndex)]
  File "/home/dragorn421/.config/blender/3.2/scripts/addons/fast64_gitlinked/fast64_internal/z64/model_classes.py", line 865, in getLimbName
    return self.limbList[index]
IndexError: list index out of range

@SlimyGooblin

Copy link
Copy Markdown
Contributor Author

Should be fixed with 955c9a5

@Dragorn421 Dragorn421 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested:

  • Blender 3.2 deku tree import
  • Blender 3.2 temple of time import-export
  • Blender 3.2 gGerudoRedSkel, gGerudoRedSpinAttackAnim import-export
  • Blender 3.2 gEponaSkel, gEponaWalkingAnim import-export
  • Blender 3.2 gBoulderFragmentsDL import-export

@Dragorn421 Dragorn421 added the merge soon Will be merged in a few days at most if nothing else comes up label Aug 12, 2026
@Dragorn421
Dragorn421 merged commit af72158 into Fast-64:main Aug 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request merge soon Will be merged in a few days at most if nothing else comes up oot Has to do with the Ocarina of Time 64 side

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants