def read_header00(self, reader: ByteIO): self.id = ''.join(list([chr(reader.read_uint8()) for _ in range(4)])) self.version = reader.read_uint32() print('Found MDL version', self.version) # self.checksum = reader.read_uint32() self.name = reader.read_ascii_string(64) self.file_size = reader.read_uint32()
def read_field(self, reader: ByteIO): count = self.count if count == 0: count = 1 exit_point = 0 if self.indirection_bytes: if self.indirection_level > 1: raise NotImplementedError( 'More than one indirection, not yet handled') if self.count > 0: raise NotImplementedError( 'Indirection.Count > 0 && field.Count > 0') indir = self.indirection_bytes[0] entry = reader.tell() offset = reader.read_uint32() if indir == 0x03: pass if not offset: return None exit_point = reader.tell() # with reader.save_current_pos(): # reader.seek(entry+offset) # return self.read_field_data(reader) elif indir == 0x04: # data = [] count = reader.read_uint32() exit_point = reader.tell() # if count>0: # with reader.save_current_pos(): # reader.seek(entry + offset) # for _ in range(count): # data.append(self.read_field(reader)) # return data else: raise NotImplementedError("Unknown indirection. ({0})".format( hex(indir))) if self.count > 0 and self.indirection_level > 0: array = [] with reader.save_current_pos(): reader.seek(entry + offset) for _ in range(count): data = self.read_field_data(reader) array.append(data) if exit_point: reader.seek(exit_point) return array else: array = [] with reader.save_current_pos(): reader.seek(entry + offset) for _ in range(count): data = self.read_field_data(reader) array.append(data) if exit_point: reader.seek(exit_point) return array else: if exit_point: reader.seek(exit_point) return self.read_field_data(reader)
def read(self, reader: ByteIO): self.endframeIndex = reader.read_uint32() self.motionFlags = reader.read_uint32() self.v0 = reader.read_float() self.v1 = reader.read_float() self.angle = reader.read_float() self.vector.read(reader) self.position.read(reader) return self
def read(self, reader: ByteIO): entry = reader.tell() self.scale = [reader.read_uint32() for _ in range(6)] self.offset = [reader.read_uint32() for _ in range(6)] for offset in self.offset: with reader.save_current_pos(): reader.seek(entry + offset) self.theAnimValues.append(SourceMdlAnimationValue(reader.read_uint16())) return self
def read(self, reader: ByteIO): entry = reader.tell() self.string_offset = reader.read_int32() self.string = reader.read_from_offset(entry + self.string_offset, reader.read_ascii_string) entry = reader.tell() self.compiler_identifier_offset = reader.read_int32() self.compiler_identifier = reader.read_from_offset(entry + self.compiler_identifier_offset, reader.read_ascii_string) self.fingerprint = reader.read_uint32() self.user_data = reader.read_uint32()
def read(self, reader: ByteIO): entry = reader.tell() self.parameter_name_offset = reader.read_int32() self.parameter_name = reader.read_from_offset(entry + self.parameter_name_offset, reader.read_ascii_string) entry = reader.tell() self.parameter_type_offset = reader.read_int32() self.parameter_type = reader.read_from_offset(entry + self.parameter_type_offset, reader.read_ascii_string) self.fingerprint = reader.read_uint32() self.fingerprint_default = reader.read_uint32()
def read(self, reader: ByteIO): entry = reader.tell() self.strip_group_count = reader.read_uint32() self.strip_group_offset = reader.read_uint32() self.flags = reader.read_uint8() with reader.save_current_pos(): if self.strip_group_offset > 0: reader.seek(entry + self.strip_group_offset) for _ in range(self.strip_group_count): self.vtx_strip_groups.append(SourceVtxStripGroup().read(reader)) return self
def read(self, reader: ByteIO, model: SourceVtxModel): entry = reader.tell() self.lod = len(model.vtx_model_lods) self.meshCount = reader.read_uint32() self.meshOffset = reader.read_uint32() self.switchPoint = reader.read_float() with reader.save_current_pos(): if self.meshOffset > 0: reader.seek(entry + self.meshOffset) for _ in range(self.meshCount): self.vtx_meshes.append(SourceVtxMesh().read(reader)) return self
def read(self,reader:ByteIO): entry = reader.tell() self.cycle = reader.read_float() self.eventIndex = reader.read_uint32() self.eventType = reader.read_uint32() self.options = [reader.read_uint8() for _ in range(64)] self.nameOffset = reader.read_uint32() if self.nameOffset: self.theName = reader.read_from_offset(self.nameOffset+entry,reader.read_ascii_string) else: self.theName = str(self.eventIndex) return self
def parse(self, reader: ByteIO, parent=None, in_array=False): name = None parent = parent if not in_array: string_id = reader.read_uint32() name = "ERROR" if string_id == -1 else self.strings[string_id] add = lambda v: parent.update({name: v} ) if not in_array else parent.append(v) data_type = reader.read_int8() flag_info = KVFlag.Nothing if data_type & 0x80: data_type &= 0x7F flag_info = KVFlag(reader.read_int8()) if data_type == KVType.NULL: add(None) return if data_type == KVType.BOOLEAN: add(reader.read_int8() > 0) return if data_type == KVType.INTEGER: add(reader.read_int64()) return if data_type == KVType.DOUBLE: add(reader.read_double()) return if data_type == KVType.STRING: string_id = reader.read_int32() if string_id == -1: add(None) return add(self.strings[string_id]) return if data_type == KVType.ARRAY: size = reader.read_uint32() arr = [] for _ in range(size): self.parse(reader, arr, True) add(arr) return if data_type == KVType.OBJECT: size = reader.read_uint32() tmp = {} for _ in range(size): self.parse(reader, tmp, False) add(tmp) if not parent: parent = tmp return parent
def read(self, reader: ByteIO): self.count = reader.read_uint32() self.size = reader.read_uint32() self.unk1 = reader.read_uint32() self.unk2 = reader.read_uint32() entry = reader.tell() self.offset = reader.read_uint32() self.total_size = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.offset) assert self.total_size == self.size * self.count self.buffer = ByteIO(byte_object=reader.read_bytes(self.count * self.size)) self.read_buffer()
def read(self, reader: ByteIO): entry = reader.tell() self.vertex_count = reader.read_uint32() self.vertex_offset = reader.read_uint32() self.index_count = reader.read_uint32() self.index_offset = reader.read_uint32() self.strip_count = reader.read_uint32() self.strip_offset = reader.read_uint32() self.flags = StripGroupFlags(reader.read_uint8()) global extra_8 if extra_8: self.topology_indices_count = reader.read_uint32() self.topology_offset = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.index_offset) for _ in range(self.index_count): self.vtx_indexes.append(reader.read_uint16()) reader.seek(entry + self.vertex_offset) for _ in range(self.vertex_count): SourceVtxVertex().read(reader, self) reader.seek(entry + self.strip_offset) for _ in range(self.strip_count): SourceVtxStrip().read(reader, self) if extra_8: reader.seek(entry + self.topology_offset) # for _ in range(self.topology_indices_count): self.topology = (reader.read_bytes(self.topology_indices_count * 2)) return self
def read(self, reader: ByteIO): entry = reader.tell() self.name = reader.read_ascii_string() reader.seek(entry + 36) self.format = DXGI_FORMAT(reader.read_int32()) self.offset = reader.read_uint32() reader.skip(12)
def read(self, reader: ByteIO): self.id = reader.read_uint64() entry = reader.tell() self.resource_name_offset = reader.read_int32() self.resource_name = reader.read_from_offset(entry + self.resource_name_offset, reader.read_ascii_string) self.unk =reader.read_uint32() a = 5
def read(self, reader: ByteIO): entry = reader.tell() self.boneIndex = reader.read_uint32() self.boneNewParentIndex = reader.read_uint32() self.startInfluence = reader.read_float() self.peakInfluence = reader.read_float() self.tailInfluence = reader.read_float() self.endInfluence = reader.read_float() self.startFrameIndex = reader.read_uint32() self.localAnimOffset = reader.read_uint32() if self.localAnimOffset != 0: with reader.save_current_pos(): reader.seek(entry + self.localAnimOffset) self.theLocalAnims.read(reader) self.unused = [reader.read_uint32() for _ in range(4)] return self
def read(self, reader: ByteIO, block_info: InfoBlock = None): self.info_block = block_info entry = reader.tell() self.vertex_offset = reader.read_uint32() self.vertex_count = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.vertex_offset) for _ in range(self.vertex_count): v_buffer = VertexBuffer() v_buffer.read(reader) self.vertex_buffer.append(v_buffer) entry = reader.tell() self.index_offset = reader.read_uint32() self.index_count = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.index_offset) for _ in range(self.index_count): i_buffer = IndexBuffer() i_buffer.read(reader) self.index_buffer.append(i_buffer)
def read(self, reader: ByteIO, mdl: SourceMdlFileDataV10): self.boneIndex = reader.read_uint32() self.type = reader.read_uint32() self.startBlah = reader.read_uint32() self.endBlah = reader.read_uint32() self.restIndex = reader.read_uint32() self.inputField = reader.read_uint32() if mdl.version > 10: self.unused = [reader.read_uint32() for _ in range(8)] mdl.bone_controllers.append(self) return self
def read(self, reader: ByteIO): entry = reader.tell() self.nameOffset = reader.read_uint32() self.thePathFileName = reader.read_from_offset( entry + self.nameOffset, reader.read_ascii_string) self.flags = reader.read_uint32() self.used = reader.read_uint32() self.unused1 = reader.read_uint32() self.materialP = reader.read_uint32() self.clientMaterialP = reader.read_uint32() self.unused = [reader.read_uint32() for _ in range(5)]
def read(self, reader: ByteIO): self.introspection_version = reader.read_int32() self.s_id = reader.read_int32() entry = reader.tell() self.name_offset = reader.read_int32() self.name = reader.read_from_offset(entry + self.name_offset, reader.read_ascii_string) self.disc_crc = reader.read_int32() self.user_version = reader.read_uint32() entry = reader.tell() self.field_offset = reader.read_int32() self.field_count = reader.read_int32() with reader.save_current_pos(): if self.field_count > 0: reader.seek(entry + self.field_offset) for n in range(self.field_count): field = NTROEnumField(self) field.read(reader) self.fields.append(field)
def read(self, reader: ByteIO): self.version = reader.read_uint32() if self.version!=7: if self.version == 402653184: reader.insert_begin(b'\x07') self.version = reader.read_uint32() print('VTX FILE WAS "PROTECTED", but screew it :P') else: raise NotImplementedError('VTX version {} is not supported!'.format(self.version)) self.vertex_cache_size = reader.read_uint32() self.max_bones_per_strip = reader.read_uint16() self.max_bones_per_tri = reader.read_uint16() self.max_bones_per_vertex = reader.read_uint32() self.checksum = reader.read_uint32() self.lodCount = reader.read_uint32() self.material_replacement_list_offset = reader.read_uint32() self.bodyPartCount = reader.read_uint32() self.bodyPartOffset = reader.read_uint32() global max_bones_per_vertex max_bones_per_vertex = self.max_bones_per_vertex if self.bodyPartOffset > 0: reader.seek(self.bodyPartOffset) try: for _ in range(self.bodyPartCount): self.vtx_body_parts.append(SourceVtxBodyPart().read(reader)) except struct.error: global extra_8 extra_8 = False self.vtx_body_parts.clear() reader.seek(self.bodyPartOffset) for _ in range(self.bodyPartCount): self.vtx_body_parts.append(SourceVtxBodyPart().read(reader)) if self.material_replacement_list_offset > 0: reader.seek(self.material_replacement_list_offset) for _ in range(self.lodCount): self.material_replacement_lists.append(MaterialReplacementList().read(reader))
def read(self, reader: ByteIO, stripgroup: SourceVtxStripGroup): entry = reader.tell() self.index_count = reader.read_uint32() self.index_mesh_index = reader.read_uint32() self.vertex_count = reader.read_uint32() self.vertex_mesh_index = reader.read_uint32() self.bone_count = reader.read_uint16() self.flags = StripHeaderFlags(reader.read_uint8()) self.bone_state_change_count = reader.read_uint32() self.bone_state_change_offset = reader.read_uint32() global extra_8 if extra_8: self.topology_indices_count = reader.read_int32() self.topology_offset = reader.read_int32() # print('Strip end',reader.tell()) stripgroup.vtx_strips.append(self)
def read(self, reader: ByteIO): self.id = reader.read_fourcc() if self.id != 'IDSV': if self.id[:-1] == 'DSV': reader.insert_begin(b'I') self.id = reader.read_fourcc() print('VVD FILE WAS "PROTECTED", but screew it :P') else: raise NotImplementedError('VVD format {} is not supported!'.format(self.id)) self.version = reader.read_uint32() self.checksum = reader.read_uint32() self.lod_count = reader.read_uint32() self.lod_vertex_count = [reader.read_uint32() for _ in range(8)] self.fixup_count = reader.read_uint32() self.fixup_table_offset = reader.read_uint32() self.vertex_data_offset = reader.read_uint32() self.tangent_data_offset = reader.read_uint32() self.fixed_vertexes_by_lod = [[]] * self.lod_count if self.lod_count <= 0: return reader.seek(self.vertex_data_offset) for _ in range(self.lod_vertex_count[0]): self.vertexes.append(SourceVertex().read(reader)) reader.seek(self.fixup_table_offset) if self.fixup_count > 0: for _ in range(self.fixup_count): self.fixups.append(SourceVvdFixup().read(reader)) if self.lod_count > 0: for lod_index in range(self.lod_count): for fixup_index in range(len(self.fixups)): fixup = self.fixups[fixup_index] if fixup.lod_index >= lod_index: for j in range(fixup.vertex_count): vertex = self.vertexes[fixup.vertex_index + j] self.fixed_vertexes_by_lod[lod_index].append(vertex)
def read(self, reader: ByteIO): self.count = reader.read_uint32() self.size = reader.read_uint32() entry = reader.tell() self.attributes_offset = reader.read_uint32() self.attributes_count = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.attributes_offset) for _ in range(self.attributes_count): v_attrib = VertexAttribute() v_attrib.read(reader) self.attributes.append(v_attrib) entry = reader.tell() self.offset = reader.read_uint32() self.total_size = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.offset) assert self.total_size == self.size * self.count self.buffer = ByteIO(byte_object=reader.read_bytes(self.count * self.size)) self.read_buffer()
class BinaryKeyValue(Dummy): ENCODING = (0x46, 0x1A, 0x79, 0x95, 0xBC, 0x95, 0x6C, 0x4F, 0xA7, 0x0B, 0x05, 0xBC, 0xA1, 0xB7, 0xDF, 0xD2) FORMAT = (0x7C, 0x16, 0x12, 0x74, 0xE9, 0x06, 0x98, 0x46, 0xAF, 0xF2, 0xE6, 0x3E, 0xB5, 0x90, 0x37, 0xE7) SIG = (0x56, 0x4B, 0x56, 0x03) def __init__(self, block_info: InfoBlock = None): self.strings = [] self.info_block = block_info self.kv = [] self.flags = 0 self.buffer = ByteIO() # type: ByteIO def read(self, reader: ByteIO): fourcc = reader.read_bytes(4) assert tuple(fourcc) == self.SIG, 'Invalid KV Signature' encoding = reader.read_bytes(16) assert tuple(encoding) == self.ENCODING, 'Unrecognized KV3 Encoding' format = reader.read_bytes(16) assert tuple(format) == self.FORMAT, 'Unrecognised KV3 Format' self.flags = reader.read_bytes(4) if self.flags[3] & 0x80: self.buffer.write_bytes( reader.read_bytes(self.info_block.block_size - (reader.tell() - self.info_block.absolute_offset))) working = True while reader.tell() != reader.size() and working: block_mask = reader.read_uint16() for i in range(16): if block_mask & (1 << i) > 0: offset_and_size = reader.read_uint16() offset = ((offset_and_size & 0xFFF0) >> 4) + 1 size = (offset_and_size & 0x000F) + 3 lookup_size = offset if offset < size else size entry = self.buffer.tell() self.buffer.seek(entry - offset) data = self.buffer.read_bytes(lookup_size) self.buffer.seek(entry) while size > 0: self.buffer.write_bytes( data[:lookup_size if lookup_size < size else size]) size -= lookup_size else: data = reader.read_int8() self.buffer.write_int8(data) if self.buffer.size() == (self.flags[2] << 16) + ( self.flags[1] << 8) + self.flags[0]: working = False break self.buffer.seek(0) string_count = self.buffer.read_uint32() for i in range(string_count): self.strings.append(self.buffer.read_ascii_string()) self.parse(self.buffer, self.kv, True) self.buffer.close() del self.buffer def parse(self, reader: ByteIO, parent=None, in_array=False): name = None parent = parent if not in_array: string_id = reader.read_uint32() name = "ERROR" if string_id == -1 else self.strings[string_id] add = lambda v: parent.update({name: v} ) if not in_array else parent.append(v) data_type = reader.read_int8() flag_info = KVFlag.Nothing if data_type & 0x80: data_type &= 0x7F flag_info = KVFlag(reader.read_int8()) if data_type == KVType.NULL: add(None) return if data_type == KVType.BOOLEAN: add(reader.read_int8() > 0) return if data_type == KVType.INTEGER: add(reader.read_int64()) return if data_type == KVType.DOUBLE: add(reader.read_double()) return if data_type == KVType.STRING: string_id = reader.read_int32() if string_id == -1: add(None) return add(self.strings[string_id]) return if data_type == KVType.ARRAY: size = reader.read_uint32() arr = [] for _ in range(size): self.parse(reader, arr, True) add(arr) return if data_type == KVType.OBJECT: size = reader.read_uint32() tmp = {} for _ in range(size): self.parse(reader, tmp, False) add(tmp) if not parent: parent = tmp return parent
def read_header01(self, reader: ByteIO): self.eye_position.read(reader) self.hull_min_position.read(reader) self.hull_max_position.read(reader) self.view_bounding_box_min_position.read(reader) self.view_bounding_box_max_position.read(reader) self.flags = reader.read_uint32() self.bone_count = reader.read_uint32() self.bone_offset = reader.read_uint32() self.bone_controller_count = reader.read_uint32() self.bone_controller_offset = reader.read_uint32() self.hitbox_set_count = reader.read_uint32() self.hitbox_set_offset = reader.read_uint32() self.local_sequence_count = reader.read_uint32() self.local_sequence_offset = reader.read_uint32() self.sequence_group_count = reader.read_uint32() self.sequence_group_offset = reader.read_uint32() self.texture_count = reader.read_uint32() self.texture_offset = reader.read_uint32() self.texture_data_offset = reader.read_int32() self.skin_reference_count = reader.read_uint32() self.skin_family_count = reader.read_uint32() self.skin_family_offset = reader.read_uint32() self.body_part_count = reader.read_uint32() self.body_part_offset = reader.read_uint32() self.local_attachment_count = reader.read_uint32() self.local_attachment_offset = reader.read_uint32() self.sound_table = reader.read_uint32() self.sound_index = reader.read_uint32() self.sound_groups = reader.read_uint32() self.sound_group_offset = reader.read_uint32() self.transitions_count = reader.read_uint32() self.transition_offset = reader.read_uint32() if self.body_part_count == 0 and self.local_sequence_count > 0: self.mdl_file_only_has_animations = True
def read_from_buffer(self, reader: ByteIO): if self.format == DXGI_FORMAT.R32G32B32_FLOAT: return [ reader.read_float() for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R32G32B32_UINT: return [ reader.read_uint32() for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R32G32B32_SINT: return [ reader.read_int32() for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R32G32B32A32_FLOAT: return [ reader.read_float() for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R32G32B32A32_UINT: return [ reader.read_uint32() for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R32G32B32A32_SINT: return [ reader.read_int32() for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R16G16_FLOAT: return [ short_to_float(reader.read_int16()) for _ in range(self.format.name.count('16')) ] elif self.format == DXGI_FORMAT.R32G32_FLOAT: return [ short_to_float(reader.read_float()) for _ in range(self.format.name.count('32')) ] elif self.format == DXGI_FORMAT.R16G16_SINT: return [ reader.read_int16() for _ in range(self.format.name.count('16')) ] elif self.format == DXGI_FORMAT.R16G16_UINT: return [ reader.read_uint16() for _ in range(self.format.name.count('16')) ] elif self.format == DXGI_FORMAT.R8G8B8A8_SNORM: return [ reader.read_int8() for _ in range(self.format.name.count('8')) ] elif self.format == DXGI_FORMAT.R8G8B8A8_UNORM: return [ reader.read_uint8() for _ in range(self.format.name.count('8')) ] elif self.format == DXGI_FORMAT.R8G8B8A8_UINT: return [ reader.read_uint8() for _ in range(self.format.name.count('8')) ] else: raise NotImplementedError('Unknown buffer format {}'.format( self.format.name))
def read(self,reader:ByteIO,mdl:SourceMdlFileData): entry = reader.tell() self.baseHeaderOffset = reader.read_int32() self.nameOffset = reader.read_uint32() self.theName = reader.read_from_offset(entry+self.nameOffset,reader.read_ascii_string) self.activityNameOffset = reader.read_uint32() self.theActivityName = reader.read_from_offset(entry+self.activityNameOffset,reader.read_ascii_string) self.flags = reader.read_uint32() self.activity = reader.read_int32() self.activityWeight = reader.read_uint32() self.eventCount = reader.read_uint32() self.eventOffset = reader.read_uint32() self.bbMin.read(reader) self.bbMax.read(reader) self.blendCount = reader.read_uint32() self.animIndexOffset = reader.read_uint32() self.movementIndex = reader.read_uint32() self.groupSize = [reader.read_uint32() for _ in range(2)] self.paramIndex = [reader.read_int32() for _ in range(2)] self.paramStart = [reader.read_uint32() for _ in range(2)] self.paramEnd = [reader.read_uint32() for _ in range(2)] self.paramParent = reader.read_uint32() self.fadeInTime = reader.read_float() self.fadeOutTime = reader.read_float() self.localEntryNodeIndex = reader.read_uint32() self.localExitNodeIndex = reader.read_uint32() self.nodeFlags = reader.read_uint32() self.entryPhase = reader.read_float() self.exitPhase = reader.read_float() self.lastFrame = reader.read_float() self.nextSeq = reader.read_uint32() self.pose = reader.read_uint32() self.ikRuleCount = reader.read_uint32() self.autoLayerCount = reader.read_uint32() self.autoLayerOffset = reader.read_uint32() self.weightOffset = reader.read_uint32() self.poseKeyOffset = reader.read_uint32() self.ikLockCount = reader.read_uint32() self.ikLockOffset = reader.read_uint32() self.keyValueOffset = reader.read_uint32() self.keyValueSize = reader.read_uint32() self.cyclePoseIndex = reader.read_uint32() if mdl.version == 49: self.activityModifierOffset = reader.read_int32() self.activityModifierCount = reader.read_uint32() self.unused = [reader.read_uint32() for _ in range(5)] else: self.unused = [reader.read_uint32() for _ in range(7)] if self.groupSize[0] > 1 and self.groupSize[1] > 1 and self.poseKeyOffset !=0: with reader.save_current_pos(): reader.seek(entry+self.poseKeyOffset) for _ in range(self.groupSize[0]+self.groupSize[1]): self.thePoseKeys.append(reader.read_float()) if self.eventCount > 0 and self.eventOffset!=0: with reader.save_current_pos(): reader.seek(entry+self.eventOffset) for _ in range(self.eventCount): self.theEvents.append(SourceMdlEvent().read(reader)) return self
def read(self, reader: ByteIO, MDL: SourceMdlFileData): entry = reader.tell() self.entry = entry self.baseHeaderOffset = reader.read_int32() self.nameOffset = reader.read_int32() self.theName = reader.read_from_offset(entry + self.nameOffset, reader.read_ascii_string) self.fps = reader.read_float() self.flags = self.STUDIO(reader.read_uint32()) self.frameCount = reader.read_uint32() self.movementCount = reader.read_uint32() self.movementOffset = reader.read_uint32() self.unused1 = [reader.read_uint32() for _ in range(6)] self.animBlock = reader.read_uint32() self.animOffset = reader.read_uint32() self.ikRuleCount = reader.read_uint32() self.ikRuleOffset = reader.read_uint32() self.animblockIkRuleOffset = reader.read_uint32() self.localHierarchyCount = reader.read_uint32() self.localHierarchyOffset = reader.read_uint32() self.sectionOffset = reader.read_uint32() self.sectionFrameCount = reader.read_uint32() self.spanFrameCount = reader.read_uint16() self.spanCount = reader.read_uint16() self.spanOffset = reader.read_uint32() self.spanStallTime = reader.read_float() self.fileOffsetStart2 = entry + self.spanOffset self.fileOffsetEnd2 = entry + self.spanOffset-1 if self.spanFrameCount!=0 or self.spanCount!=0 or self.spanOffset!=0 or self.spanStallTime!=0: for bone_index in range(len(MDL.bones)): bone = MDL.bones[bone_index] #type: SourceMdlBone if bone.flags & SourceMdlBone.BONE_HAS_SAVEFRAME_POS: self.fileOffsetEnd2 += self.spanCount * 6 if bone.flags & SourceMdlBone.BONE_HAS_SAVEFRAME_ROT: self.fileOffsetEnd2 += self.spanCount * 8 return self
def read(self, reader: ByteIO): self.animBlock = reader.read_uint32() self.animOffset = reader.read_uint32() return self
def read(self, reader: ByteIO): self.lod_index = reader.read_uint32() self.vertex_index = reader.read_uint32() self.vertex_count = reader.read_uint32() return self