def dump_ogf4_m04(cr, out, opts): dump_ogf4_m05(cr, out, opts) pr = PackedReader(cr.next(Chunks.SWIDATA)) out('swidata: {') out(' ?:', pr.getf('IIII')) sc = pr.getf('I')[0] if opts.diff: out( ' swis-info:', 'count=' + str(sc) + ', hash=' + calc_hash(pr.getb((4 + 2 + 2) * sc))) else: out(' swis: [') for _ in range(sc): out(' {offs: %i, tris: %i, vtxs: %i}' % pr.getf('IHH')) out(' ]') out('}')
def dump_anm(cr, out, opts): for (cid, data) in cr: if cid != Chunks.MAIN: out('UNKNOWN ANM CHUNK: {:#x}'.format(cid)) continue pr = PackedReader(data) out('name:', pr.gets()) out('range:', pr.getf('II')) out('fps:', pr.getf('f')[0]) ver = pr.getf('H')[0] if ver != 5: raise Exception('unsupported anm version: {}'.format(ver)) out('version:', ver) out('envelopes: [{') dump_envelopes(pr, out) out('}]')
def dump_ogf(cr, out, opts): pr = PackedReader(cr.next(Chunks.HEADER)) ver = pr.getf('B')[0] out('version:', ver) if ver == 4: dump_ogf4(pr, cr, out, opts) else: raise Exception('unsupported OGF format version: %i' % ver)
def parse_gamemtl(data): materials = {} for (cid, data) in ChunkedReader(data): if cid == 4098: for (_, cdata) in ChunkedReader(data): name, desc = None, None for (cccid, ccdata) in ChunkedReader(cdata): if cccid == 0x1000: reader = PackedReader(ccdata) material_index = reader.getf('I')[0] name = reader.gets() materials[material_index] = name if cccid == 0x1005: desc = PackedReader(ccdata).gets() return materials
def dump_ogf4_m05(cr, out, opts): pr = PackedReader(cr.next(Chunks.TEXTURE)) out('texture: {') out(' image:', pr.gets()) out(' shader:', pr.gets()) out('}') pr = PackedReader(cr.next(Chunks.VERTICES)) out('vertices: {') vf, vc = pr.getf('II') if vf == VertexFormat.FVF_1L or vf == VertexFormat.FVF_1L_CS: out(' format:', 'fvf_2l' if vf == VertexFormat.FVF_1L else 'fvf_1l_cs') if opts.diff: out( ' data-info:', 'count=' + str(vc) + ', hash=' + calc_hash(pr.getb(15 * 4 * vc))) else: out(' data: [') for _ in range(vc): out(' {v: %s, n: %s, tg: %s, bn: %s, tx: %s, b: %i' % (pr.getf('fff'), pr.getf('fff'), pr.getf('fff'), pr.getf('fff'), pr.getf('ff'), pr.getf('I')[0])) out(' ]') elif vf == VertexFormat.FVF_2L or vf == VertexFormat.FVF_2L_CS: out(' format:', 'fvf_2l' if vf == VertexFormat.FVF_2L else 'fvf_2l_cs') if opts.diff: out( ' data-info:', 'count=' + str(vc) + ', hash=' + calc_hash(pr.getb(16 * 4 * vc))) else: out(' data: [') for _ in range(vc): out(' {b: %s, v: %s, n: %s, tg: %s, bn: %s, bw: %f, tx: %s' % (pr.getf('HH'), pr.getf('fff'), pr.getf('fff'), pr.getf('fff'), pr.getf('fff'), pr.getf('f')[0], pr.getf('ff'))) out(' ]') elif vf == VertexFormat.FVF_3L_CS or vf == VertexFormat.FVF_4L_CS: nl = 3 if vf == VertexFormat.FVF_3L_CS else 4 out(' format:', 'fvf_' + str(nl) + 'l_cs') if opts.diff: out( ' data-info:', 'count=' + str(vc) + ', hash=' + calc_hash(pr.getb(((14 + nl - 1) * 4 + nl * 2) * vc))) else: out(' data: [') for _ in range(vc): out(' {b: %s, v: %s, n: %s, tg: %s, bn: %s, bw: %s, tx: %s' % (pr.getf(str(nl) + 'H'), pr.getf('fff'), pr.getf('fff'), pr.getf('fff'), pr.getf('fff'), pr.getf(str(nl - 1) + 'f'), pr.getf('ff'))) out(' ]') else: raise Exception('unexpected vertex format: {:#x}'.format(vf)) out('}') pr = PackedReader(cr.next(Chunks.INDICES)) ic = pr.getf('I')[0] // 3 if opts.diff: out('indices-info:', 'count=' + str(ic) + ', hash=' + calc_hash(pr.getb(3 * 2 * ic))) else: out('indices: {') for _ in range(ic): out(' ', pr.getf('HHH')) out('}')
def dump_ogf4_m10(cr, out, opts): def oout(*args): out(' ', *args) def ooout(*args): oout(' ', *args) def dump_box(pr, out): out('box: {') out(' rotation:', pr.getf('fffffffff')) out(' position:', pr.getf('fff')) out(' halfsize:', pr.getf('fff')) out('}') bonescount = 0 for cid, data in cr: pr = PackedReader(data) if cid == Chunks.S_DESC: out('s desc: {') out(' src:', pr.gets()) out(' export tool:', pr.gets()) out(' export time:', pr.getf('I')[0]) out(' create time:', pr.getf('I')[0]) out(' modify time:', pr.getf('I')[0]) out('}') elif cid == Chunks.CHILDREN: out('children: [{') for _, ccr in ChunkedReader(data): if _: out('}, {') dump_ogf(ChunkedReader(ccr), oout, opts) out('}]') elif cid == Chunks.S_USERDATA: out('userdata:', pr.gets()) elif cid == Chunks.S_BONE_NAMES: out('s bone names: [{') bonescount = pr.getf('I')[0] for _ in range(bonescount): if _: out('}, {') out(' name:', pr.gets()) out(' parent:', pr.gets()) dump_box(pr, oout) out('}]') elif cid == Chunks.S_IKDATA: out('s ikdata: [{') for _ in range(bonescount): if _: out('}, {') ver = pr.getf('I')[0] if ver != 0x1: raise Exception( 'unexpected ikdata version: {:#x}'.format(ver)) out(' gamemtl:', pr.gets()) out(' shape: {') out(' type:', pr.getf('H')[0]) out(' flags:', pr.getf('H')[0]) dump_box(pr, ooout) out(' sphere: {') out(' center:', pr.getf('fff')) out(' radius:', pr.getf('f')[0]) out(' }') out(' cylinder: {') out(' center:', pr.getf('fff')) out(' direction:', pr.getf('fff')) out(' height:', pr.getf('f')[0]) out(' radius:', pr.getf('f')[0]) out(' }') out(' }') out(' joint: {') out(' type:', pr.getf('I')[0]) out(' limits: [') out(' {%s, s: %f, d: %f}' % (pr.getf('ff'), pr.getf('f')[0], pr.getf('f')[0])) out(' {%s, s: %f, d: %f}' % (pr.getf('ff'), pr.getf('f')[0], pr.getf('f')[0])) out(' {%s, s: %f, d: %f}' % (pr.getf('ff'), pr.getf('f')[0], pr.getf('f')[0])) out(' ]') out(' spring:', pr.getf('f')[0]) out(' damping:', pr.getf('f')[0]) out(' flags:', pr.getf('I')[0]) out(' break: {') out(' force:', pr.getf('f')[0]) out(' torque:', pr.getf('f')[0]) out(' }') out(' friction:', pr.getf('f')[0]) out(' }') out(' rotation:', pr.getf('fff')) out(' position:', pr.getf('fff')) out(' mass: {') out(' value:', pr.getf('f')[0]) out(' center:', pr.getf('fff')) out(' }') out('}]') elif cid == Chunks.S_MOTION_REFS_0: out('s motion refs 0:', pr.gets()) elif cid == Chunks.S_MOTIONS: out('s motions: len={}, hash={}'.format(len(data), calc_hash(data))) elif cid == Chunks.S_SMPARAMS: out('s smparams: {') ver = pr.getf('H')[0] if (ver != 3) and (ver != 4): print('unsupported smparams version={}'.format(ver)) out(' version:', ver) out(' partitions: [{') for pi in range(pr.getf('H')[0]): if pi: out(' }, {') pn = pr.gets() out(' name:', pn) out(' bones: [{') for bi in range(pr.getf('H')[0]): if bi: out(' }, {') out(' name:', pr.gets()) out(' id:', pr.getf('I')[0]) out(' }]') break out(' }]') out('}') else: print('unknown ogf4_m10 chunk={:#x}, len={}, hash={}'.format( cid, len(data), calc_hash(data)))
def dump_object(cr, out, opts): def oout(*args): out(' ', *args) cr = ChunkedReader(cr.next(Chunks.Object.MAIN)) ver = cr.nextf(Chunks.Object.VERSION, 'H')[0] if ver != 0x10: raise Exception('unsupported OBJECT format version: {}'.format(ver)) out('version:', ver) getserr = '' def gets_error(e): global getserr getserr = ' //!' + str(e) def sgets(pr): global getserr getserr = '' return pr.gets(onerror=gets_error) + getserr for (cid, data) in cr: pr = PackedReader(data) if cid == Chunks.Object.USERDATA: out('userdata:', sgets(pr)) elif cid == Chunks.Object.LOD_REF: out('lod_ref:', pr.gets()) elif cid == Chunks.Object.FLAGS: out('flags:', pr.getf('I')[0]) elif cid == Chunks.Object.MESHES: out('meshes: [{') for (_, d) in ChunkedReader(data): if _: out('}, {') dump_mesh(ChunkedReader(d), oout, opts) out('}]') elif (cid == Chunks.Object.SURFACES1) or (cid == Chunks.Object.SURFACES2): out('surfaces{}'.format(cid - Chunks.Object.SURFACES1 + 1) + ': [{') for _ in range(pr.getf('I')[0]): if _: out('}, {') out(' name:', pr.gets()) out(' eshader:', pr.gets()) out(' cshader:', pr.gets()) if cid == Chunks.Object.SURFACES2: out(' gamemtl:', pr.gets()) out(' texture:', pr.gets()) out(' vmap:', pr.gets()) out(' flags:', pr.getf('I')[0]) fvf = pr.getf('I')[0] out(' fvf:', 'default' if fvf == 0x112 else fvf) out(' ?=1:', pr.getf('I')[0]) out('}]') elif cid == Chunks.Object.BONES: out('bones: [{') pr = PackedReader(data) for _ in range(pr.getf('I')[0]): if _: out('}, {') out(' def: {') out(' name:', pr.gets()) out(' parent:', pr.gets()) out(' vmap:', pr.gets()) out(' }') out(' pose: {') out(' offset:', pr.getf('fff')) out(' rotate:', pr.getf('fff')) out(' length:', pr.getf('f')[0]) out(' }') out('}]') elif cid == Chunks.Object.BONES1: out('bones: [{') for (_, d) in ChunkedReader(data): if _: out('}, {') dump_bone(ChunkedReader(d), oout) out('}]') elif cid == Chunks.Object.TRANSFORM: out('transform: {') out(' position:', pr.getf('fff')) out(' rotation:', pr.getf('fff')) out('}') elif cid == Chunks.Object.PARTITIONS0: out('partitions1: [{') for _ in range(pr.getf('I')[0]): if _: out('}, {') out(' name:', pr.gets()) sz = pr.getf('I')[0] out(' bones:', pr.getf('%dI' % sz)) out('}]') elif cid == Chunks.Object.PARTITIONS1: out('partitions1: [{') for _ in range(pr.getf('I')[0]): if _: out('}, {') out(' name:', pr.gets()) sz = pr.getf('I')[0] out(' bones:', [pr.gets() for __ in range(sz)]) out('}]') elif cid == Chunks.Object.MOTION_REFS: out('motion_refs:', pr.gets()) elif cid == Chunks.Object.REVISION: out('revision: {') out(' owner:', pr.gets()) out(' ctime:', time.ctime(pr.getf('I')[0])) out(' moder:', pr.gets()) out(' mtime:', time.ctime(pr.getf('I')[0])) out('}') elif cid == Chunks.Object.MOTIONS: if opts.diff: out('motions-info:', 'count=' + str(pr.getf('I')[0]) + ', hash=' + calc_hash(data)) continue out('motions: [{') for _ in range(pr.getf('I')[0]): if _: out('}, {') dump_motion(pr, oout) out('}]') elif cid == Chunks.Object.SMOTIONS3: out('smotions3:', [pr.gets() for _ in range(pr.getf('I')[0])]) elif cid == Chunks.Object.LIB_VERSION: out('lib_version:', pr.getf('Q')[0]) else: out('UNKNOWN OBJ CHUNK: {:#x}'.format(cid))
def dump_mesh(cr, out, opts): ver = cr.nextf(Chunks.Mesh.VERSION, 'H')[0] if ver != 0x11: raise Exception('unsupported MESH format version: {}'.format(ver)) out('version:', ver) for (cid, data) in cr: pr = PackedReader(data) if cid == Chunks.Mesh.MESHNAME: out('meshname:', pr.gets()) elif cid == Chunks.Mesh.BBOX: out('bbox:', pr.getf('fff'), '-', pr.getf('fff')) elif cid == Chunks.Mesh.FLAGS: out('flags:', pr.getf('B')[0]) elif cid == Chunks.Mesh.OPTIONS: out('options:', pr.getf('II')) elif cid == Chunks.Mesh.VERTS: vc = pr.getf('I')[0] if opts.diff: out('vertices-info:', 'count=' + str(vc) + ', hash=' + calc_hash(data)) continue out('vertices: [') for _ in range(vc): out(' ', pr.getf('fff')) out(']') elif cid == Chunks.Mesh.FACES: if opts.diff: out('faces-info:', 'count=' + str(pr.getf('I')[0]) + ', hash=' + calc_hash(data)) continue out('faces: [') for _ in range(pr.getf('I')[0]): fr = pr.getf('IIIIII') f = ((fr[0], fr[2], fr[4]), (fr[1], fr[3], fr[5])) out(' ', f) out(']') elif cid == Chunks.Mesh.SG: if opts.diff: out('sgroups-hash:', calc_hash(data)) continue out('sgroups:', [pr.getf('I')[0] for _ in range(len(data) // 4)]) elif cid == Chunks.Mesh.VMREFS: if opts.diff: out('vmrefs-hash:', calc_hash(data)) continue out('vmrefs: [') for _ in range(pr.getf('I')[0]): sz = pr.getf('B')[0] out(' ', [pr.getf('II') for __ in range(sz)]) out(']') elif cid == Chunks.Mesh.SFACE: out('sfaces: [{') for _ in range(pr.getf('H')[0]): if _: out('}, {') out(' name:', pr.gets()) sz = pr.getf('I')[0] if opts.diff: out(' faces-info:', 'count=' + str(sz) + ', hash=' + calc_hash(pr.getb(sz * 4))) continue out(' faces:', [pr.getf('I')[0] for __ in range(sz)]) out('}]') elif cid == Chunks.Mesh.VMAPS0: out('vmaps0: [{') for _ in range(pr.getf('I')[0]): if _: out('}, {') out(' name:', pr.gets()) sz = pr.getf('I')[0] if opts.diff: out(' uvs-hash:', calc_hash(pr.getb(sz * 2 * 4))) out(' vtx-hash:', calc_hash(pr.getb(sz * 1 * 4))) continue out(' uvs:', [pr.getf('ff') for __ in range(sz)]) out(' vtx:', [pr.getf('I')[0] for __ in range(sz)]) out('}]') elif cid == Chunks.Mesh.VMAPS2: out('vmaps2: [{') for _ in range(pr.getf('I')[0]): if _: out('}, {') out(' name:', pr.gets()) out(' dim:', pr.getf('B')[0] & 0x3) dsc = pr.getf('B')[0] & 0x1 out(' dsc:', dsc) typ = pr.getf('B')[0] & 0x3 # enum {VMT_UV,VMT_WEIGHT} out(' type:', typ) sz = pr.getf('I')[0] if opts.diff: if typ == 0: out(' uvs-hash:', calc_hash(pr.getb(sz * 2 * 4))) elif typ == 1: out(' wgh-hash:', calc_hash(pr.getb(sz * 4))) out(' vtx-hash:', calc_hash(pr.getb(sz * 4))) if dsc != 0: out(' fcs-hash:', calc_hash(pr.getb(sz * 4))) continue if typ == 0: out(' uvs:', [pr.getf('ff') for __ in range(sz)]) elif typ == 1: out(' wgh:', [pr.getf('f')[0] for __ in range(sz)]) out(' vtx:', [pr.getf('I')[0] for __ in range(sz)]) if dsc != 0: out(' fcs:', [pr.getf('I')[0] for __ in range(sz)]) out('}]') else: out('UNKNOWN MESH CHUNK: {:#x}'.format(cid))
def dump_bone(cr, out): ver = cr.nextf(Chunks.Bone.VERSION, 'H')[0] if ver != 0x2: raise Exception('unsupported BONE format version: {}'.format(ver)) pr = PackedReader(cr.next(Chunks.Bone.DEF)) out('def: {') out(' name:', pr.gets()) out(' parent:', pr.gets()) out(' vmap:', pr.gets()) out('}') for (cid, data) in cr: pr = PackedReader(data) if cid == Chunks.Bone.BIND_POSE: out('pose: {') out(' offset:', pr.getf('fff')) out(' rotate:', pr.getf('fff')) out(' length:', pr.getf('f')[0]) out('}') elif cid == Chunks.Bone.DEF: out('def:', pr.gets()) elif cid == Chunks.Bone.MATERIAL: out('gamemtl:', pr.gets()) elif cid == Chunks.Bone.SHAPE: out('shape: {') out(' type:', pr.getf('H')[0]) out(' flags:', pr.getf('H')[0]) out(' box: rot={}, tr={}, hs={}'.format(pr.getf('fffffffff'), pr.getf('fff'), pr.getf('fff'))) out(' sphere: pos={}, rad={}'.format(pr.getf('fff'), pr.getf('f')[0])) out(' cylinder: ctr={}, dir={}, h={}, r={}'.format(pr.getf('fff'), pr.getf('fff'), pr.getf('f')[0], pr.getf('f')[0])) out('}') elif cid == Chunks.Bone.IK_FLAGS: out('ik_flags:', pr.getf('I')[0]) elif cid == Chunks.Bone.IK_JOINT: out('ik_joint: {') out(' type:', pr.getf('I')[0]) out(' lims: {}, spr={}, dmp={}'.format(pr.getf('fff'), pr.getf('f')[0], pr.getf('f')[0])) out(' spring:', pr.getf('f')[0]) out(' damping:', pr.getf('f')[0]) out('}') elif cid == Chunks.Bone.BREAK_PARAMS: out('break: {') out(' force:', pr.getf('f')[0]) out(' torque:', pr.getf('f')[0]) out('}') elif cid == Chunks.Bone.FRICTION: out('friction:', pr.getf('f')[0]) elif cid == Chunks.Bone.MASS_PARAMS: out('mass: {') out(' value:', pr.getf('f')[0]) out(' center:', pr.getf('fff')) out('}') else: out('UNKNOWN BONE CHUNK: {:#x}'.format(cid))
def dump_params(chunk_id, data, out): out('Params Chunk:', hex(chunk_id), len(data)) packed_reader = PackedReader(data) params_version = packed_reader.getf('<H')[0] out(SPACES * 1 + 'params version:', params_version) # bone parts partition_count = packed_reader.getf('<H')[0] out(SPACES * 1 + 'bone parts:') for partition_index in range(partition_count): partition_name = packed_reader.gets() out(SPACES * 2 + 'bone part {0}:'.format(partition_index), partition_name) bone_count = packed_reader.getf('<H')[0] out(SPACES * 3 + 'bones count:', bone_count) for bone in range(bone_count): out(SPACES * 4 + 'bone index:', bone) if params_version == 1: bone_id = packed_reader.getf('<I')[0] out(SPACES * 5 + 'bone id:', bone_id) elif params_version == 2: bone_name = packed_reader.gets() out(SPACES * 5 + 'bone_name:', bone_name) elif params_version == 3 or params_version == 4: bone_name = packed_reader.gets() bone_id = packed_reader.getf('<I')[0] out(SPACES * 5 + 'bone_name:', bone_name) out(SPACES * 5 + 'bone id:', bone_id) else: raise BaseException('Unknown params version') # motions params out(SPACES * 1 + 'motion params:') motion_count = packed_reader.getf('<H')[0] out(SPACES * 2 + 'motion count:', motion_count) for motion_index in range(motion_count): out(SPACES * 3 + 'motion index:', motion_index) name = packed_reader.gets() out(SPACES * 4 + 'name:', name) flags = packed_reader.getf('<I')[0] out(SPACES * 4 + 'flags:', flags) bone_or_part = packed_reader.getf('<H')[0] out(SPACES * 4 + 'bone or part:', bone_or_part) motion = packed_reader.getf('<H')[0] out(SPACES * 4 + 'motion:', motion) speed = packed_reader.getf('<f')[0] out(SPACES * 4 + 'speed:', speed) power = packed_reader.getf('<f')[0] out(SPACES * 4 + 'power:', power) accrue = packed_reader.getf('<f')[0] out(SPACES * 4 + 'accrue:', accrue) falloff = packed_reader.getf('<f')[0] out(SPACES * 4 + 'falloff:', falloff) if params_version == 4: # motion marks num_marks = packed_reader.getf('<I')[0] out(SPACES * 4 + 'marks count:', num_marks) for mark_index in range(num_marks): out(SPACES * 5 + 'mark index:', mark_index) mark_name = packed_reader.gets_a() out(SPACES * 6 + 'mark name:', mark_name) count = packed_reader.getf('<I')[0] out(SPACES * 6 + 'intervals count:', count) for index in range(count): out(SPACES * 7 + 'interval index:', index) interval_first = packed_reader.getf('<f')[0] out(SPACES * 8 + 'interval first:', interval_first) interval_second = packed_reader.getf('<f')[0] out(SPACES * 8 + 'interval second:', interval_second)