Skip to main content

No project description provided

Project description

xc3_model_py PyPI

Python bindings to xc3_model for high level and efficient data access to model files for Xenoblade Chronicles X, Xenoblade Chronicles 1 Definitive Edition, Xenoblade Chronicles 2, Xenoblade Chronicles 3, and Xenoblade Chronicles X Definitive Edition.

Installation

The package can be installed for Python version 3.9, 3.10, 3.11, or 3.12 using pip on newer versions of Windows, Linux, or MacOS. The prebuilt wheels (.whl files) are included only for situations where pip might not be available such as for plugin development for applications. The wheels are zip archives and can be extracted to obtain the compiled .pyd or .so file. xc3_model_py requires the numpy package for transforms and vertex data.

Installing: pip install xc3_model_py
Updating: pip install xc3_model_py --upgrade

Introduction

Parsing and conversion to Python happens in optimized Rust code when calling xc3_model_py.load_map or xc3_model_py.load_model. All files revisions are converted to the same types on import like xc3_model_py.ModelRoot or xc3_model_py.MapRoot. This avoids needing to add any special handling for different file versions or different games. Pregenerated shader databases compatible with a specific release are linked in releases. For more advanced usage, see xenoblade_blender.

import xc3_model_py

# Get a list of MapRoot.
database = xc3_model_py.shader_database.ShaderDatabase.from_file("xc3.bin")
roots = xc3_model_py.load_map("xenoblade3_dump/map/ma59a.wismhd", database)

for root in roots:
    for group in root.groups:
        for models in group.models:
            for material in models.materials:
                print(material.name)
                # The shader contains assignment information when specifying a database.

            for model in models.models:
                buffers = group.buffers[model.model_buffers_index]

                # prints (num_instances, 4, 4)
                print(len(model.instances.shape))
# This returns only a single ModelRoot.
database = xc3_model_py.shader_database.ShaderDatabase.from_file("xc3.bin")
root = xc3_model_py.load_model("xenoblade3_dump/chr/chr/01012013.wimdo", database)

for material in root.models.materials:
    print(material.name)

for model in root.models.models:
    # prints (1, 4, 4)
    print(len(model.instances.shape))

    # Access vertex and index data for this model.
    buffers = root.buffers
    for buffer in buffers.vertex_buffers:
        for attribute in buffer.attributes:
            print(attribute.attribute_type, attribute.data.shape)

    # Access vertex skinning data for each mesh.
    for mesh in model.meshes:
        vertex_buffer = buffers.vertex_buffers[mesh.vertex_buffer_index]

        if buffers.weights is not None:
            # Calculate the index offset based on the weight group for this mesh.
            pass_type = root.models.materials[mesh.material_index].pass_type
            lod_item_index = 0 if mesh.lod_item_index is None else mesh.lod_item_index
            start_index = buffers.weights.weights_start_index(
                mesh.flags2, lod_item_index, pass_type
            )

            weight_buffer = buffers.weights.weight_buffer(mesh.flags2)
            if weight_buffer is not None:
                # Get vertex skinning attributes.
                for attribute in vertex_buffer.attributes:
                    if (
                        attribute.attribute_type
                        == xc3_model_py.vertex.AttributeType.WeightIndex
                    ):
                        # Find the actual per vertex skinning information.
                        weight_indices = attribute.data[:, 0] + start_index
                        skin_weights = weight_buffer.weights[weight_indices]
                        # Note that these indices index into a different bone list than the skeleton.
                        bone_indices = weight_buffer.bone_indices[weight_indices, 0]
                        bone_name = weight_buffer.bone_names[bone_indices[0]]

Certain types like matrices and vertex atribute data are stored using numpy.ndarray. All transformation matrices are column-major to match the Rust code in xc3_model. This greatly reduces conversion overhead and allows for more optimized Python code. xc3_model_py requires the numpy package to be installed. Blender already provides the numpy package, enabling the use of functions like foreach_get and foreach_set for efficient property access.

# blender
blender_mesh.vertices.add(positions_array.shape[0])
blender_mesh.vertices.foreach_set('co', positions_array.reshape(-1))

Animations can be loaded from a file all at once. The track type is currently opaque, meaning that implementation details are not exposed. The values can be sampled at the desired frame using the appropriate methods.

import xc3_model_py

path = "xenoblade3_dump/chr/ch/ch01027000_event.mot"
animations = xc3_model_py.load_animations(path)

for animation in animations:
    print(
        animation.name, animation.space_mode, animation.play_mode, animation.blend_mode
    )
    print(f"frames: {animation.frame_count}, tracks: {len(animation.tracks)}")

    track = animation.tracks[0]

    # Each track references a bone in one of three ways.
    bone_index = track.bone_index()
    bone_hash = track.bone_hash()
    bone_name = track.bone_name()
    if bone_index is not None:
        pass
    elif bone_hash is not None:
        # Use xc3_model_py.murmur3(bone_name) for hashing the skeleton bones.
        pass
    elif bone_name is not None:
        pass

    # Sample the transform for a given track at each frame.
    # This essentially "bakes" the keyframes of the animation.
    for frame in range(animation.frame_count):
        print(track.sample_scale(frame, animation.frame_count))
        print(track.sample_rotation(frame, animation.frame_count))
        print(track.sample_translation(frame, animation.frame_count))
    print()

xc3_model_py enables Rust log output by default to use with Python's logging module. Logging can be disabled entirely if not needed using logging.disable().

import logging

# Configure log messages to include more information.
FORMAT = "%(levelname)s %(name)s %(filename)s:%(lineno)d %(message)s"
logging.basicConfig(format=FORMAT, level=logging.INFO)

Documentation

See the pyi stub file for complete function and type information. This also enables autocomplete in supported editors like the Python extension for VSCode. The Python API attempts to match the Rust functions and types in xc3_model as closely as possible.

Installation

The compiled extension module can be imported just like any other Python file. On Windows, rename xc3_model_py.dll to xc3_model_py.pyd. If importing xc3_model_py fails, make sure the import path is specified correctly and the current Python version matches the version used when building. For installing in the current Python environment, install maturin and use maturin develop --release.

Building

Build the project with cargo build --release. This will compile a native python module for the current Python interpreter. For use with Blender, make sure to build for the Python version used by Blender. This can be achieved by activating a virtual environment with the appropriate Python version or setting the Python interpeter using the PYO3_PYTHON environment variable. See the PyO3 guide for details.

Limitations

Some types from xc3_model_py are opaque wrappers around the underlying Rust types and cannot be constructed in any way from Python. Some of these limitations should hopefully be resolved in the future.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

xc3_model_py-0.15.0-cp312-cp312-win_amd64.whl (5.5 MB view details)

Uploaded CPython 3.12Windows x86-64

xc3_model_py-0.15.0-cp312-cp312-manylinux_2_34_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

xc3_model_py-0.15.0-cp312-cp312-macosx_11_0_arm64.whl (4.2 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

xc3_model_py-0.15.0-cp312-cp312-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

xc3_model_py-0.15.0-cp311-cp311-win_amd64.whl (5.5 MB view details)

Uploaded CPython 3.11Windows x86-64

xc3_model_py-0.15.0-cp311-cp311-manylinux_2_34_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

xc3_model_py-0.15.0-cp311-cp311-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

xc3_model_py-0.15.0-cp311-cp311-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

xc3_model_py-0.15.0-cp310-cp310-win_amd64.whl (5.5 MB view details)

Uploaded CPython 3.10Windows x86-64

xc3_model_py-0.15.0-cp310-cp310-manylinux_2_34_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

xc3_model_py-0.15.0-cp310-cp310-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

xc3_model_py-0.15.0-cp310-cp310-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

xc3_model_py-0.15.0-cp39-cp39-win_amd64.whl (5.5 MB view details)

Uploaded CPython 3.9Windows x86-64

xc3_model_py-0.15.0-cp39-cp39-manylinux_2_34_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.34+ x86-64

xc3_model_py-0.15.0-cp39-cp39-macosx_11_0_arm64.whl (4.3 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

xc3_model_py-0.15.0-cp39-cp39-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded CPython 3.9macOS 10.12+ x86-64

File details

Details for the file xc3_model_py-0.15.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 df63612abfed9e51e7d6b2c9b08096f78d570a5960365d9a1cbe328ffddfb333
MD5 232e4b4134a4280bb984f5d298876636
BLAKE2b-256 5d20aef1b0e4b27dfbb13f9bcdf03cfdb3bf6aa1410726a695f762f5a187c40f

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 64976db5265dcd79ef3b68bfea5d985d4c556da86b04016e6a6974635aa69de2
MD5 fb9a0a3b0b50bf71ab7ff5202989bc91
BLAKE2b-256 1f0c9d0f72436d2424f232ca1b5d3eb29c992d2dc32f531cb9d017b69775d1aa

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f23696ae735d1c737dd5c0a0990d6eca0907795a423af37d266126a7c51df1e1
MD5 8b632874b8d6ef06ae832d2bbc58e982
BLAKE2b-256 9e068284eb886a1e17167fab37186cfda5d4811f98af0c1bfe64ab1d4b05228d

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 93a2918594079b38955e7f81abf3e762a4eca2fa4e7589f2e0f9e92d868ecd0c
MD5 e000759a12f2b2c47e08c9408c1888ec
BLAKE2b-256 7d6edb20b32f5b8588bbe6f4831b96a9643a2fd9bc28dcfd5ec0adbf0436ee78

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 2069076edff0b55c3375b0614f4970d242cea7cb4eb467a392bea8f42fd70544
MD5 53040639cc643ee721e8034c1303b27b
BLAKE2b-256 0c1d9e6d11479822f93d376033ce00f162549d80258ebdac0454547152304ac3

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 58dd7c9da609523b9681f07233204ddbc51d6c0e411e5293ad9f0924234cd246
MD5 b3a50a0d2b031e261c088e0e92ad6779
BLAKE2b-256 5965fa180928a49bddb7930cd94caa8f00561ef6e282d24aa02a30eaeb4480a4

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7b1c8ccff76c5aa7bb8fc27ce9c13b0796f156d31c30aca7ee0def7384b58633
MD5 ebdcfc141deb5653c4694d2e07c85505
BLAKE2b-256 8554330a1589cd0d0a5f2eb99142eef1207f0aabc7b2af8e68413ed6dfda0539

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e068e428209308c347d9707eb1dd0667fed79219f50e476c62fd43ca259ba8e8
MD5 73caa8cbc8afc2e2ac3a9742f846a49a
BLAKE2b-256 acca43f44317eb6a78d5ff29d86f71862ed052329f2fd21047f949e55e86e0a5

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 1ca088216052aa14ac92faf99d043a3919f7aee1726f7a2a1b76125ec1a2bd70
MD5 df642ac8947371777788075c730f5811
BLAKE2b-256 695caeeb8b5b4046b40727ec1915759526d7d0b0b544f127b424fced600c134e

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 432859a1b7e57015c1f9e675356c40f80fb8b4369aab66bb6ce81222084f7465
MD5 c95215983214e1c975bf26d230f79522
BLAKE2b-256 ff6e00bd7afbe5ae544b42301dc0fd67abb938377f8196ef3459e697043a5f86

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1676df047d937f229c23bdafce51fea8f5551929bbffcdacd9a55338ce9154c9
MD5 c71052aa9eb8daec6db331d37c647acb
BLAKE2b-256 1fd24d0c028aa246fdee8d0fb8ea375c40c996f062e7e919ddd2f5a8186081d0

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f88e79ae07426b8d0108e94d5a1edce7f2cad960f04007b4c25592fa722ef11c
MD5 e5a1e618f0b6af9cb3c166b4fa61f08b
BLAKE2b-256 bbae10f85d108a1d8693f741ae1d037ea3fe4d48353d5384917554a5cbfc6226

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 2ed6298d92c92fd59959d3096e5f64f4933a9fd83e1b311f09af025ca209e0a2
MD5 a7fe9f879bf422ab1c156dc1957b3797
BLAKE2b-256 ddc334edf2aeed73eb6e83d5bcb1fb7e0dc4b8a10363ba56ff2cd07b74d58f47

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp39-cp39-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp39-cp39-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 8668aefdf697af72db801a0462c1414d6b675015495981daf350c03bfae33789
MD5 fefd24e5a1bdc3abf704274ab18c1539
BLAKE2b-256 cd5d25d08c4998050fabf8dd72f467529747b40869e856b6c969ddaf12e0d1c1

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1d9825cfde4931dfc00452bbda393d3f844c40632a09afdd53afcf5c64b73022
MD5 7b091837ead11101dbc636788b9d4004
BLAKE2b-256 c9b730983841ab22e4a160426a9c467643540f22d297f0fe01f357209da1841d

See more details on using hashes here.

File details

Details for the file xc3_model_py-0.15.0-cp39-cp39-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for xc3_model_py-0.15.0-cp39-cp39-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5d15785a5df9c060033d921bc579b43bb3ad700e84758a9e5f2baf5bd7d87beb
MD5 34386acfa4af7fc65458f8f6973a699a
BLAKE2b-256 8f9837cf734988f060f412b977ed095d1d729e3b959713236e809212ce685f4a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page