mirror of
https://github.com/DarklightGames/io_scene_psk_psa.git
synced 2025-02-17 10:08:31 +01:00
55 lines
2.0 KiB
Python
55 lines
2.0 KiB
Python
from ctypes import Structure, sizeof
|
|
from typing import Type
|
|
|
|
from .data import Psk
|
|
from ..shared.data import Section, Vector3
|
|
|
|
MAX_WEDGE_COUNT = 65536
|
|
MAX_POINT_COUNT = 4294967296
|
|
MAX_BONE_COUNT = 2147483647
|
|
MAX_MATERIAL_COUNT = 256
|
|
|
|
|
|
def _write_section(fp, name: bytes, data_type: Type[Structure] = None, data: list = None):
|
|
section = Section()
|
|
section.name = name
|
|
if data_type is not None and data is not None:
|
|
section.data_size = sizeof(data_type)
|
|
section.data_count = len(data)
|
|
fp.write(section)
|
|
if data is not None:
|
|
for datum in data:
|
|
fp.write(datum)
|
|
|
|
|
|
def write_psk(psk: Psk, path: str):
|
|
if len(psk.wedges) > MAX_WEDGE_COUNT:
|
|
raise RuntimeError(f'Number of wedges ({len(psk.wedges)}) exceeds limit of {MAX_WEDGE_COUNT}')
|
|
if len(psk.points) > MAX_POINT_COUNT:
|
|
raise RuntimeError(f'Numbers of vertices ({len(psk.points)}) exceeds limit of {MAX_POINT_COUNT}')
|
|
if len(psk.materials) > MAX_MATERIAL_COUNT:
|
|
raise RuntimeError(f'Number of materials ({len(psk.materials)}) exceeds limit of {MAX_MATERIAL_COUNT}')
|
|
if len(psk.bones) > MAX_BONE_COUNT:
|
|
raise RuntimeError(f'Number of bones ({len(psk.bones)}) exceeds limit of {MAX_BONE_COUNT}')
|
|
elif len(psk.bones) == 0:
|
|
raise RuntimeError(f'At least one bone must be marked for export')
|
|
|
|
with open(path, 'wb') as fp:
|
|
_write_section(fp, b'ACTRHEAD')
|
|
_write_section(fp, b'PNTS0000', Vector3, psk.points)
|
|
|
|
wedges = []
|
|
for index, w in enumerate(psk.wedges):
|
|
wedge = Psk.Wedge16()
|
|
wedge.material_index = w.material_index
|
|
wedge.u = w.u
|
|
wedge.v = w.v
|
|
wedge.point_index = w.point_index
|
|
wedges.append(wedge)
|
|
|
|
_write_section(fp, b'VTXW0000', Psk.Wedge16, wedges)
|
|
_write_section(fp, b'FACE0000', Psk.Face, psk.faces)
|
|
_write_section(fp, b'MATT0000', Psk.Material, psk.materials)
|
|
_write_section(fp, b'REFSKELT', Psk.Bone, psk.bones)
|
|
_write_section(fp, b'RAWWEIGHTS', Psk.Weight, psk.weights)
|