def write(self, stream, resource=None): s = StreamWriter(stream) s.u32(self.ID) s.u32(0) clip_stream = BytesIO() self.clip.write(clip_stream) s.u32(clip_stream.tell()) clip_stream.seek(0, SEEK_SET) clip_ptr = StreamPtr.begin_write(s, True) ik_ptr = StreamPtr.begin_write(s, True) actor_ptr = StreamPtr.begin_write(s, True) event_ptr = StreamPtr.begin_write(s, True) s.u32(self.unknown1) s.u32(self.unknown2) vector_ptr = StreamPtr.begin_write(s, True) for i in range(16): s.u8(self.unknown3[i]) clip_ptr.end() stream.write(clip_stream.read()) s.align(char=self.PADDING_CHAR) if self.ik_info != None: ik_ptr.end() self.ik_info.write(stream) s.align(char=self.PADDING_CHAR) actor_ptr.end() s.zs(self.actor_name) s.align(char=self.PADDING_CHAR) event_ptr.end() self.event_table.write(stream) s.align(char=self.PADDING_CHAR) vector_ptr.end() for i in range(4): s.f32(self.vector[i])
def write(self, stream, resource=None): s = StreamWriter(stream) s.u32(self.ID) s.u32(0) clip_stream = BytesIO() self.clip.write(clip_stream) s.u32(clip_stream.tell()) clip_stream.seek(0, SEEK_SET) clip_ptr = StreamPtr.begin_write(s, True) ik_ptr = StreamPtr.begin_write(s, True) actor_ptr = StreamPtr.begin_write(s, True) event_ptr = StreamPtr.begin_write(s, True) s.u32(self.unknown1) s.u32(self.unknown2) vector_ptr = StreamPtr.begin_write(s, True) for i in range(16): s.u8(self.unknown3[i]) clip_ptr.end() stream.write(clip_stream.read()) s.align(char=self.PADDING_CHAR) if self.ik_info is not None: ik_ptr.end() self.ik_info.write(stream) s.align(char=self.PADDING_CHAR) actor_ptr.end() s.zs(self.actor_name) s.align(char=self.PADDING_CHAR) event_ptr.end() self.event_table.write(stream) s.align(char=self.PADDING_CHAR) vector_ptr.end() for i in range(4): s.f32(self.vector[i])
def read(self, stream, resource=None): s = StreamReader(stream) assert s.chars(4) == self.TAG self.version = s.u32() cBlends = s.i32() cLods = s.i32() cPointers = s.i32() cVectors = s.i32() assert s.i32() == 0x00000008 assert s.i32() == 0x0000000C blend_ptr = StreamPtr.begin_read(s) vertex_ptr = StreamPtr.begin_read(s) vector_ptr = StreamPtr.begin_read(s) blend_ptr.end() lod_ptrs = [] for blend_index in range(cBlends): blend = Blend() blend.age_gender_flags = s.u32() blend.blend_region = s.u32() self.blends.append(blend) blend.lods = [Blend.LOD() for lod_index in range(cLods)] lod_ptrs.append([self.LodPtr(s.u32(), s.u32(), s.u32()) for lod_index in range(cLods)]) vertex_ptr.end() pointers = [self.VertexPtr(s.i16()) for pointer_index in range(cPointers)] vector_ptr.end() vectors = [[self.unpack(s.i16()) for i in range(3)] for vector_index in range(cVectors)] for blend_index, blend in enumerate(self.blends): start_vector_ptr = 0 current_vector_offset = 0 blend_ptr = lod_ptrs[blend_index] for lod_index, lod in enumerate(blend.lods): lod_blend_index = blend_index + lod_index if lod_blend_index >= len(blend_ptr): print('Skipping missing LOD %s - %s'%(lod_blend_index,len(blend_ptr))) continue lod_ptr = blend_ptr[blend_index + lod_index] current_vertex_id = lod_ptr.start_vertex_id for vector_ptr_index in range(lod_ptr.vertex_count): vertex = Blend.Vertex() vector_ptr = pointers[vector_ptr_index + start_vector_ptr] current_vector_offset += vector_ptr.offset vertex.id = current_vertex_id vertex_vector_offset = 0 if vector_ptr.has_position: vertex.position = vectors[current_vector_offset + vertex_vector_offset] vertex_vector_offset += 1 if vector_ptr.has_normal: vertex.normal = vectors[current_vector_offset + vertex_vector_offset] vertex_vector_offset += 1 current_vertex_id += 1 lod.vertices.append(vertex) start_vector_ptr += lod_ptr.vertex_count current_vector_offset += lod_ptr.vector_count
def write(self, stream, resources=None): s = StreamWriter(stream) indexedFloats = [] curves = [] curveMap = {} for t in self.tracks: assert isinstance(t, Track) for curve in t: assert isinstance(curve, Curve) if len(curve.frames) > self.max_frame_count: self.max_frame_count = len(curve.frames) + 1 cdi = CurveDataInfo() curve.flags.static = len(curve.frames) == 0 cdi.frame_count = len(curve.frames) cdi.process_frames(curve.frames) cdi.flags = curve.flags cdi.type = curve.type cdi.track_key = t.track_key curveMap[cdi] = curve.frames curves.append(cdi) cCurves = len(curves) cFloats = len(indexedFloats) #Begin writing... s.chars('_pilC3S_') s.u32(self.version) s.u32(self.unknown1) s.f32(self.frame_duration) s.u16(self.max_frame_count) s.u16(self.unknown2) s.u32(cCurves) s.u32(cFloats) curveOffset = StreamPtr.begin_write(s) frameOffset = StreamPtr.begin_write(s) nameOffset = StreamPtr.begin_write(s) srcNameOffset = StreamPtr.begin_write(s) curveOffset.end() for curve in curves: curve.write(stream) nameOffset.end() s.zs(self.name) srcNameOffset.end() s.zs(self.source_file_name) frameOffset.end() for curve in curves: curve.frame_data_ptr.end() frames = curveMap[curve] for f in frames: f.write(stream, curve, indexedFloats) return self
def write(self, stream, resources=None): s = StreamWriter(stream) indexedFloats = [] curves = [] curveMap = {} for t in self.tracks: assert isinstance(t,Track) for curve in t: assert isinstance(curve,Curve) if len(curve.frames) > self.max_frame_count: self.max_frame_count = len(curve.frames) + 1 cdi = CurveDataInfo() curve.flags.static = len(curve.frames) == 0 cdi.frame_count = len(curve.frames) cdi.process_frames(curve.frames) cdi.flags = curve.flags cdi.type = curve.type cdi.track_key = t.track_key curveMap[cdi] = curve.frames curves.append(cdi) cCurves = len(curves) cFloats = len(indexedFloats) #Begin writing... s.chars('_pilC3S_') s.u32(self.version) s.u32(self.unknown1) s.f32(self.frame_duration) s.u16(self.max_frame_count) s.u16(self.unknown2) s.u32(cCurves) s.u32(cFloats) curveOffset = StreamPtr.begin_write(s) frameOffset = StreamPtr.begin_write(s) nameOffset = StreamPtr.begin_write(s) srcNameOffset = StreamPtr.begin_write(s) curveOffset.end() for curve in curves: curve.write(stream) nameOffset.end() s.zs(self.name) srcNameOffset.end() s.zs(self.source_file_name) frameOffset.end() for curve in curves: curve.frame_data_ptr.end() frames = curveMap[curve] for f in frames: f.write(stream, curve, indexedFloats) return self
def read(self, stream, resources=None): s = StreamReader(stream) tag = s.chars(8) if not tag == '_pilC3S_': raise Exception("Not a valid _S3Clip_") self.version = s.u32() self.unknown1 = s.u32() self.frame_duration = s.f32() self.max_frame_count = s.u16() self.unknown2 = s.u16() cCurves = s.u32() cFloats = s.u32() curveOffset = StreamPtr.begin_read(s) frameOffset = StreamPtr.begin_read(s) nameOffset = StreamPtr.begin_read(s) srcNameOffset = StreamPtr.begin_read(s) curveOffset.end() curves = [] for curveIndex in range(cCurves): cdi = CurveDataInfo() cdi.read(stream) curves.append(cdi) nameOffset.end() self.name = s.zs() srcNameOffset.end() self.source_file_name = s.zs() frameOffset.end() indexedFloats = [] for floatIndex in range(cFloats): indexedFloats.append(s.f32()) trackMap = {} self.tracks = [] for curveIndex,cdi in enumerate(curves): cdi.frame_data_ptr.end() if cdi.track_key not in trackMap.keys(): t = Track(cdi.track_key) trackMap[cdi.track_key] = t self.tracks.append(t) track = trackMap[cdi.track_key] frames = [] for frameIndex in range(cdi.frame_count): f = Frame() f.read(stream, cdi, indexedFloats) frames.append(f) curve = Curve(cdi.type) curve.flags = cdi.flags curve.frames = frames track[curve.type] = curve return self
def read(self, stream, resources=None): s = StreamReader(stream) tag = s.chars(8) if not tag == '_pilC3S_': raise Exception("Not a valid _S3Clip_") self.version = s.u32() self.unknown1 = s.u32() self.frame_duration = s.f32() self.max_frame_count = s.u16() self.unknown2 = s.u16() cCurves = s.u32() cFloats = s.u32() curveOffset = StreamPtr.begin_read(s) frameOffset = StreamPtr.begin_read(s) nameOffset = StreamPtr.begin_read(s) srcNameOffset = StreamPtr.begin_read(s) curveOffset.end() curves = [] for curveIndex in range(cCurves): cdi = CurveDataInfo() cdi.read(stream) curves.append(cdi) nameOffset.end() self.name = s.zs() srcNameOffset.end() self.source_file_name = s.zs() frameOffset.end() indexedFloats = [] for floatIndex in range(cFloats): indexedFloats.append(s.f32()) trackMap = {} self.tracks = [] for curveIndex, cdi in enumerate(curves): cdi.frame_data_ptr.end() if cdi.track_key not in trackMap.keys(): t = Track(cdi.track_key) trackMap[cdi.track_key] = t self.tracks.append(t) track = trackMap[cdi.track_key] frames = [] for frameIndex in range(cdi.frame_count): f = Frame() f.read(stream, cdi, indexedFloats) frames.append(f) curve = Curve(cdi.type) curve.flags = cdi.flags curve.frames = frames track[curve.type] = curve return self
def write(self, stream, resource=None): s = StreamWriter(stream) self.frame_data_ptr = StreamPtr.begin_write(s) s.u32(self.track_key) s.f32(self.offset) s.f32(self.scale) s.u16(self.frame_count) self.flags.write(stream) s.u8(self.type) return self
def read(self, stream, resource=None): s = StreamReader(stream) self.frame_data_ptr = StreamPtr.begin_read(s) self.track_key = s.u32() self.offset = s.f32() self.scale = s.f32() self.frame_count = s.u16() self.flags.read(stream) self.type = s.u8() return self
def read(self, stream, resources=None): s = StreamReader(stream) if s.u32() != self.ID: raise Exception("Not a valid clip resource") if s.u32(): raise Exception("Linked clip offset not supported") clipSize = s.u32() clip_ptr = StreamPtr.begin_read(s, True) ik_ptr = StreamPtr.begin_read(s, True) actor_ptr = StreamPtr.begin_read(s, True) event_ptr = StreamPtr.begin_read(s, True) self.unknown1 = s.u32() self.unknown2 = s.u32() vector_ptr = StreamPtr.begin_read(s, True) self.unknown3 = [] for i in range(16): self.unknown3.append(s.u8()) a = clip_ptr.seek_data() clipStream = BytesIO() clipStream.write(stream.read(clipSize)) clipStream.seek(0, SEEK_SET) self.clip = Clip() self.clip.read(clipStream) clipStream.close() assert actor_ptr.seek_data() self.actor_name = s.zs() if ik_ptr.seek_data(): self.ik_info = ClipIKInfo() self.ik_info.read(stream) else: self.ik_info = None assert event_ptr.seek_data() self.event_table.read(stream) self.vector = [] assert vector_ptr.seek_data() for i in range(4): self.vector.append(s.f32())
def write_presets(cls, stream,presets, resources): s = StreamWriter(stream) s.i32(len(presets)) ce = ComplateEncoder() for preset in presets: assert isinstance(preset,cls.BuildBuyPreset) s.i8(preset.unk1) if preset.unk1 != 1: s.i32(preset.unk2) preset_ptr = StreamPtr.begin_write(s) ce.serialize(preset.complate,stream,resources) preset_ptr.end() s.u32(preset.id)
def read(self, stream, resources=None): s = StreamReader(stream) if s.u32() != self.ID: raise Exception("Not a valid clip resource") if s.u32(): raise Exception("Linked clip offset not supported") clipSize = s.u32() clip_ptr = StreamPtr.begin_read(s, True) ik_ptr = StreamPtr.begin_read(s, True) actor_ptr = StreamPtr.begin_read(s, True) event_ptr = StreamPtr.begin_read(s, True) self.unknown1 = s.u32() self.unknown2 = s.u32() vector_ptr = StreamPtr.begin_read(s, True) self.unknown3 = [] for i in range(16): self.unknown3.append(s.u8()) a= clip_ptr.seek_data() clipStream = BytesIO() clipStream.write(stream.read(clipSize)) clipStream.seek(0, SEEK_SET) self.clip = Clip() self.clip.read(clipStream) clipStream.close() assert actor_ptr.seek_data() self.actor_name = s.zs() if ik_ptr.seek_data(): self.ik_info = ClipIKInfo() self.ik_info.read(stream) else: self.ik_info = None assert event_ptr.seek_data() self.event_table.read(stream) self.vector = [] assert vector_ptr.seek_data() for i in range(4): self.vector.append(s.f32())
def read_presets(cls,stream,resources=None): s = StreamReader(stream) c = s.i32() ce = ComplateEncoder() presets = [] for i in range(c): preset = cls.BuildBuyPreset() preset.unk1 = s.i8() if preset.unk1 != 1: preset.unk2 = s.i32() preset_ptr = StreamPtr.begin_read(s,relative=True,offset_start=True) preset.complate = ce.deserialize(stream,resources) preset_ptr.end() preset.id = s.u32() presets.append(preset) return presets
def write_pointer(self, stream): self.size32 = 1 t = type(self.value) if isinstance(self.value, list): self.size32 = len(self.value) t = type(self.value[0]) if t == float: self.type_code = self.TYPE.FLOAT elif t == int: self.type_code = self.TYPE.INT elif t == ExternalResource: self.type_code = self.TYPE.TEXTURE elif t == ResourceKey: self.size32 = 4 self.type_code = self.TYPE.TEXTURE else: raise NotImplementedError("Serialization of type %s is not supported in this format!" % t) s = StreamWriter(stream) s.hash(self.name) s.u32(self.type_code) s.u32(self.size32) self.pointer = StreamPtr.begin_write(s)
def write_pointer(self, stream): self.size32 = 1 t = type(self.value) if isinstance(self.value, list): self.size32 = len(self.value) t = type(self.value[0]) if t == float: self.type_code = self.TYPE.FLOAT elif t == int: self.type_code = self.TYPE.INT elif t == ExternalResource: self.type_code = self.TYPE.TEXTURE elif t == ResourceKey: self.size32 = 4 self.type_code = self.TYPE.TEXTURE else: raise NotImplementedError( "Serialization of type %s is not supported in this format!" % t) s = StreamWriter(stream) s.hash(self.name) s.u32(self.type_code) s.u32(self.size32) self.pointer = StreamPtr.begin_write(s)
def read(self, stream, resource=None): s = StreamReader(stream) assert s.chars(4) == self.TAG self.version = s.u32() cBlends = s.i32() cLods = s.i32() cPointers = s.i32() cVectors = s.i32() assert s.i32() == 0x00000008 assert s.i32() == 0x0000000C blend_ptr = StreamPtr.begin_read(s) vertex_ptr = StreamPtr.begin_read(s) vector_ptr = StreamPtr.begin_read(s) blend_ptr.end() lod_ptrs = [] for blend_index in range(cBlends): blend = Blend() blend.age_gender_flags = s.u32() blend.blend_region = s.u32() self.blends.append(blend) blend.lods = [Blend.LOD() for lod_index in range(cLods)] lod_ptrs.append([ self.LodPtr(s.u32(), s.u32(), s.u32()) for lod_index in range(cLods) ]) vertex_ptr.end() pointers = [ self.VertexPtr(s.i16()) for pointer_index in range(cPointers) ] vector_ptr.end() vectors = [[self.unpack(s.i16()) for i in range(3)] for vector_index in range(cVectors)] for blend_index, blend in enumerate(self.blends): start_vector_ptr = 0 current_vector_offset = 0 blend_ptr = lod_ptrs[blend_index] for lod_index, lod in enumerate(blend.lods): lod_blend_index = blend_index + lod_index if lod_blend_index >= len(blend_ptr): print('Skipping missing LOD %s - %s' % (lod_blend_index, len(blend_ptr))) continue lod_ptr = blend_ptr[blend_index + lod_index] current_vertex_id = lod_ptr.start_vertex_id for vector_ptr_index in range(lod_ptr.vertex_count): vertex = Blend.Vertex() vector_ptr = pointers[vector_ptr_index + start_vector_ptr] current_vector_offset += vector_ptr.offset vertex.id = current_vertex_id vertex_vector_offset = 0 if vector_ptr.has_position: vertex.position = vectors[current_vector_offset + vertex_vector_offset] vertex_vector_offset += 1 if vector_ptr.has_normal: vertex.normal = vectors[current_vector_offset + vertex_vector_offset] vertex_vector_offset += 1 current_vertex_id += 1 lod.vertices.append(vertex) start_vector_ptr += lod_ptr.vertex_count current_vector_offset += lod_ptr.vector_count
def read_pointer(self, stream): s = StreamReader(stream) self.name = s.u32() self.type_code = s.u32() self.size32 = s.u32() self.pointer = StreamPtr.begin_read(s)