from typing import Dict, List from dataclasses import dataclass from itertools import islice from io import BytesIO import struct from collada.util import matrix_transpose, find_semantics from collada import parse from collada import types from collada.generate import renderer from collada import buffer from prettyprinter import pprint, install_extras install_extras(include=["dataclasses"]) @dataclass class State: # arbitrary binary data, including vertex buffers and index # buffers buf: BytesIO # geometry__indices: # keys: collada id # values: the index the geometry was placed at in the C++ geometries[] array geometry__indices: Dict[str, int] # geometry__vertex_index_tables: # keys: collada id # values: vertex_index_table (see buffer.py) geometry__vertex_index_tables: Dict[str, List[int]] def __init__(self): self.buf = BytesIO() self.geometry__indices = {} self.geometry__vertex_index_tables = {} def render_matrix(fs): fsi = iter(fs) for i in range(4): s = ", ".join(f"{f}f" for f in islice(fsi, 4)) yield f"{s}," def render_inverse_bind_matrix(collada, skin): inverse_bind_matrix_input, = find_semantics(skin.joints.inputs, "INV_BIND_MATRIX") inverse_bind_matrix_source = collada.lookup(inverse_bind_matrix_input.source, types.SourceCore) stride = inverse_bind_matrix_source.technique_common.accessor.stride count = inverse_bind_matrix_source.technique_common.accessor.count array = inverse_bind_matrix_source.array_element assert type(inverse_bind_matrix_source.array_element) == types.FloatArray assert stride == 16 assert array.count == count * stride inverse_bind_matrices = [] yield "static const float inverse_bind_matrices[] = {" for i in range(count): offset = stride * i matrix = matrix_transpose(array.floats[offset:offset+stride]) yield from render_matrix(matrix) yield "};" def renderbin(f, elems, t): fmt = { float: '