def read(self, stream, resources=None): s = StreamReader(stream) self.version = s.u32() tgi = TGIList(package=resources) tgi.begin_read(stream) if self.version >= 0x00000007: self.presets = ProductBase.read_presets(stream,tgi) self.product_info = ProductInfo() self.product_info.read(stream,tgi) self.model = tgi.get_resource(s.i32()) self.diagonal_model = tgi.get_resource(s.i32()) self.post_model = tgi.get_resource(s.i32()) self.post_tile_spacing = s.i32() self.can_walk_over = s.i8() == 1 if self.version >= 0x00000008: if self.version >= 0x000000A: self.should_not_get_thick_snow = s.i8() == 1 self.snow_post_shape_is_circle = s.i8()==1 self.snow_thickness_post_scale_factor = s.f32() self.snow_thickness_rail_scale_factor = s.f32() self.snow_thickness_post_vertical_offset = s.f32() self.snow_thickness_rail_vertical_offset = s.f32() self.has_wall = s.i8() == 1 if self.version < 0x000000A or self.has_wall: self.raise_fence_geometry_above_wall = s.i8()== 1 self.wall = tgi.get_resource(s.i32()) tgi.end_read(stream)
def read(self, stream, rcol): s = StreamReader(stream) data_len = s.u32() end = stream.tell() + data_len self.name = s.u32() self.material = rcol.get_block(s.u32(), (MaterialDefinition, MaterialSet)) self.vertex_format = rcol.get_block(s.u32(), VertexFormat) self.vertex_buffer = rcol.get_block(s.u32(), (VertexBuffer, VertexBufferShadow)) self.index_buffer = rcol.get_block(s.u32(), (IndexBuffer, IndexBufferShadow)) flags = s.u32() self.flags = flags >> 8 self.primitive_type = flags & 0x000000FF self.stream_offset = s.u32() self.start_vertex = s.i32() self.start_index = s.i32() self.min_vertex_index = s.i32() self.vertex_count = s.i32() self.primitive_count = s.i32() self.bounds.read(stream) self.skin_controller = rcol.get_block(s.u32(), ObjectSkinController) self.bone_references = [s.u32() for i in range(s.i32())] self.scale_offsets = rcol.get_block(s.u32(), MaterialDefinition) self.states = [self.State(stream) for i in range(s.i32())] if self.parent.version > ModelLod.VERSION.DEFAULT: self.parent_name = s.u32() self.mirror_plane_normal = [s.f32() for i in range(3)] self.mirror_plane_offset = s.f32() if not stream.tell() == end: raise Exception( "Invalid MLOD.Mesh data length: expected 0x%X, but got 0x%08X" % (end, stream.tell()))
def read_property(self, stream, hash, tgi): s = StreamReader(stream) id = s.u32() value = None if not id: return False if not s.u8(): t = s.u8() if t == 0x00: value = bool(s.u8()) elif t == 0x01: value = s.i8() elif t == 0x02: value = s.i16() elif t == 0x03: value = s.i32() elif t == 0x04: value = s.i64() elif t == 0x05: value = s.u8() elif t == 0x06: value = s.u16() elif t == 0x07: value = s.u32() elif t == 0x08: value = s.u64() elif t == 0x09: value = s.f32() elif t == 0x0A: value = [s.f32() for i in range(4)] elif t == 0x0B: value = [s.f32() for i in range(4)] elif t == 0x0C: value = tgi.get_resource(s.u8()) elif t == 0x0D: value = s.p16() else: raise Exception("Unknown TXTC parameter type %s" % t) hash[id] = value return True
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.version = s.u32() self.deltas = [ self.Item(s.u32(), [s.f32() for i in range(3)], [s.f32() for i in range(3)], [s.f32() for i in range(4)]) ]
def read(self, stream, resource=None): s = StreamReader(stream) self.type = s.u32() self.origin = [s.f32() for i in range(3)] self.normal = [s.f32() for i in range(3)] self.x_axis = [s.f32() for i in range(3)] self.y_axis = [s.f32() for i in range(3)] self.pair_offset = s.f32()
def read(self, stream, resource=None): Light.read(self, stream) s = StreamReader(stream) self.at = [s.f32() for i in range(3)] self.falloff_angle = s.f32() self.shade_light_rig_multiplier = s.f32() self.bottom_angle = s.f32() self.shade_colour = [s.f32() for i in range(3)]
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() self.routing_slots = [RoutingSlot() for i in range(s.i32())] self.container_slots = [ContainerSlot() for i in range(s.i32())] self.effect_slots = [EffectSlot() for i in range(s.i32())] self.target_slots = [TargetSlot() for i in range(s.i32())] self.cone_slots = [ConeSlot() for i in range(s.i32())] def read_names(slots): for slot in slots: slot.name = s.hash(Slot.NAMES) def read_bones(slots): for slot in slots: slot.bone_name = s.u32() def read_transforms(slots): for slot in slots: slot.transform = s.m43() def read_offsets(slots): if any(slots): for i in range(s.i32()): slots[i].offset = SlotOffset([s.f32(), s.f32(), s.f32()], [s.f32(), s.f32(), s.f32()]) pass pass read_names(self.routing_slots) read_bones(self.routing_slots) read_transforms(self.routing_slots) read_offsets(self.routing_slots) read_names(self.container_slots) read_bones(self.container_slots) for slot in self.container_slots: slot.flags = s.u32() read_transforms(self.container_slots) read_offsets(self.container_slots) read_names(self.effect_slots) read_bones(self.effect_slots) read_transforms(self.effect_slots) read_offsets(self.effect_slots) read_names(self.target_slots) read_bones(self.target_slots) read_transforms(self.target_slots) read_offsets(self.target_slots) read_names(self.cone_slots) read_bones(self.cone_slots) read_transforms(self.cone_slots) for cone_slot in self.cone_slots: cone_slot.radius = s.f32() cone_slot.angle = s.f32() read_offsets(self.cone_slots) pass
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_rcol(self, stream, rcol): self.read_tag(stream) s = StreamReader(stream) self.version = s.u32() self.rig.key = s.tgi('ITG') self.unknown = s.f32() for i in range(self.RESERVED_COUNT): self.reserved[i] = s.u8() cValues = s.u32() self.bone_weights = [0.0] * cValues for i in range(cValues): self.bone_weights[i] = s.f32()
def read(self, stream, resource=None): s = StreamReader(stream) self.name = s.u32() self.priority = s.i8() self.footprint_type_flags = s.u32() self.points = [(s.f32(), s.f32()) for i in range(s.i32())] self.allow_intersection_flags = s.u32() self.surface_type_flags = s.u32() self.surface_attribute_flags = s.u32() self.level_offset = s.i32() if self.ftpt.version >= Footprint.VERSION.EXTENDED: self.elevation_offset = s.f32() self.bounds.read(stream)
def read(self, stream, resources=None): s = StreamReader(stream) assert s.u16() == self.TAG self.id = s.u32() self.time_code = s.f32() self.unknown1 = s.f32() self.unknown2 = s.f32() self.unknown3 = s.u32() length = s.u32() self.name = s.zs() assert len(self.name) == length s.align()
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 read_data(self, stream, keys=None): s = StreamReader(stream) if self.type_code == self.TYPE.FLOAT: return s.f32() if self.size32 == 1 else [s.f32() for i in range(self.size32)] if self.type_code == self.TYPE.INT: return s.i32() if self.size32 == 1 else[s.i32() for i in range(self.size32)] if self.type_code == self.TYPE.TEXTURE: if self.size32 == 4: val = keys.get_resource(s.u32()) stream.seek(12, SEEK_CUR) return val elif self.size32 == 5: key = s.tgi('ITG') stream.seek(4, SEEK_CUR) return key
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.flags = s.u32() self.priority = s.u32() assert s.u32() == 0 self.blend_in_time = s.f32() self.blend_out_time = s.f32() assert s.u32() == 0 self.speed = s.f32() self.actor = rcol.get_block(s.u32(), ActorDefinition) self.timing_priority = s.u32() assert s.u32() == 0x00000010 for i in range(5): assert s.u32() == 0 assert s.u32() == DEADBEEF MulticastDecisionGraphNode.read(self, stream, rcol)
def read(self, stream, resource=None): s = StreamReader(stream) self.version = s.u32() tgi = TGIList(order='igt', count_size=8, package=resource, use_length=False) tgi.begin_read(stream) self.presets = [self.CasPreset(stream, tgi) for i in range(s.u32())] self.part_name = s.s7(16, '>') self.display_index = s.f32() self.has_unique_texture_space = s.u8() self.body_type = s.u32() self.part_flags = s.u32() self.age_gender_flags = s.u32() self.clothing_category = s.u32() self.naked_cas_part = tgi.get_resource(s.i8()) self.base_cas_part = tgi.get_resource(s.i8()) self.blend_fat = tgi.get_resource(s.i8()) self.blend_fit = tgi.get_resource(s.i8()) self.blend_thin = tgi.get_resource(s.i8()) self.blend_special = tgi.get_resource(s.i8()) self.draw_layer = s.u32() self.sources = [tgi.get_resource(s.i8()) for i in range(s.u8())] self.lod_infos = [CASLodInfo(stream) for i in range(s.u8())] self.diffuse_refs = [tgi.get_resource(s.i8()) for i in range(s.u8())] self.specular_refs = [tgi.get_resource(s.i8()) for i in range(s.u8())] self.secondary_diffuse_refs = [tgi.get_resource(s.i8()) for i in range(s.u8())] self.secondary_specular_refs = [tgi.get_resource(s.i8()) for i in range(s.u8())] self.slot_poses = [tgi.get_resource(s.i8()) for i in range(s.u8())] self.shoe_material = s.s7(16, '>') tgi.end_read(stream)
def read(self, stream, resources): s = StreamReader(stream) self.age_gender = s.u32() self.edge_color = s.u32() self.specular_color = s.u32() self.specular_power = s.f32() self.is_genetic = bool(s.u8())
def read(self, stream, resources=None): s = StreamReader(stream) self.weight = s.f32() self.decision_graph_nodes = [ resources.get_block(s.u32(), DecisionGraphNode.get_node_types()) ]
def read(self, stream, resource=None): Event.read(self, stream) s = StreamReader(stream) self.prop_actor_name = s.u32() self.object_actor_name = s.u32() self.slot_name = s.u32() self.unknown4 = s.u32() self.matrix = [[s.f32() for i in range(4)] for i in range(4)]
def read(self, stream, resources): s = StreamReader(stream) self.model = resources.get_block(s.u32(), ModelLod) self.flags = s.u32() self.id = s.u16() self.is_sunshadow = bool(s.u16()) self.min_z = s.f32() self.max_z = s.f32()
def read(self, stream, resource=None): s = StreamReader(stream) self.version = s.u32() names = [s.s7(16, '>') for i in range(s.u32())] poses = [[[s.f32() for j in range(3)] for i in range(4)] for pose_index in range(s.u32())] self.bones = [ self.Bone(names[i], pose) for i, pose in enumerate(poses) ]
def read_data(self, stream, keys=None): s = StreamReader(stream) if self.type_code == self.TYPE.FLOAT: return s.f32() if self.size32 == 1 else [ s.f32() for i in range(self.size32) ] if self.type_code == self.TYPE.INT: return s.i32() if self.size32 == 1 else [ s.i32() for i in range(self.size32) ] if self.type_code == self.TYPE.TEXTURE: if self.size32 == 4: val = keys.get_resource(s.u32()) stream.seek(12, SEEK_CUR) return val elif self.size32 == 5: key = s.tgi('ITG') stream.seek(4, SEEK_CUR) return key
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() cLods = s.i32() self.bounds.read(stream) if self.version >= self.VERSION.EXTENDED: self.extra_bounds = [BoundingBox(stream=stream) for i in range(s.i32())] self.fade_type = s.u32() self.custom_fade_distance = s.f32() self.lods = [self.LOD(stream, rcol) for i in range(cLods)]
def read(self, stream, resources=None): s = StreamReader(stream) self.version = s.u32() self.name_guid = s.u64() self.desc_guid = s.u64() self.name_key = s.s7() self.desc_key = s.s7() self.price = s.f32() self.niceness_multiplier = s.f32() self.crap_score = s.f32() self.status_flags = s.u8() self.icon = s.u64() self.environment_score = s.f32() self.fire_type = s.u32() self.is_stealable = bool(s.i8()) self.is_reposessable = bool(s.i8()) self.ui_sort_index = s.u32() if self.version >= 0x0000000D: self.is_placeable_on_roof = bool(s.u8()) if self.version >= 0x0000000E: self.is_visible_in_worldbuilder = bool(s.u8()) if self.version >= 0x0000000F: self.product_name = s.u32()
def read(self, stream, resources=None): s = StreamReader(stream) self.version = s.u32() self.name_guid = s.u64() self.desc_guid = s.u64() self.name_key = s.s7(size=16,order='>') self.desc_key = s.s7(size=16,order='>') self.price = s.f32() self.niceness_multiplier = s.f32() self.crap_score = s.f32() self.status_flags = s.u8() self.icon = s.u64() assert s.u8() == 0 self.environment_score = s.f32() self.fire_type = s.u32() self.is_stealable = bool(s.i8()) self.is_reposessable = bool(s.i8()) self.ui_sort_index = s.u32() if self.version >= 0x0000000D: self.is_placeable_on_roof = bool(s.u8()) if self.version >= 0x0000000E: self.is_visible_in_worldbuilder = bool(s.u8()) if self.version >= 0x0000000F: self.product_name = s.u32()
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() cLods = s.i32() self.bounds.read(stream) if self.version >= self.VERSION.EXTENDED: self.extra_bounds = [ BoundingBox(stream=stream) for i in range(s.i32()) ] self.fade_type = s.u32() self.custom_fade_distance = s.f32() self.lods = [self.LOD(stream, rcol) for i in range(cLods)]
def read(self, stream, resource=None): s = StreamReader(stream) self.version_major = s.u32() self.version_minor = s.u32() cBones = s.i32() self.bones = [] opposites = [] parents = [] self.__hashes = {} for i in range(cBones): bone = Bone(self) bone.position = [s.f32() for i in range(3)] bone.orientation = [s.f32() for i in range(4)] bone.scale = [s.f32() for i in range(3)] bone.name = s.p32() opposites.append(s.i32()) parents.append(s.i32()) hash_name = s.u32() if not hash_name == FNV32.hash(bone.name): print( "WARNING: Bone %s should have matching hash 0x%08X, but has 0x%08X", bone.name, FNV32.hash(bone.name), hash_name) self.__hashes[hash] = bone bone.flags = s.u32() self.bones.append(bone) for bone_index, opposite_index in enumerate(opposites): if opposite_index >= 0: self.bones[bone_index].opposite = self.bones[opposite_index] for bone_index, parent_index in enumerate(parents): if parent_index >= 0: self.bones[bone_index].parent = self.bones[parent_index] if self.version_major >= 4: self.name = s.p32() self.ik_chains = [] cChains = s.i32() for i in range(cChains): chain = IKChain(self) chain.read(stream) self.ik_chains.append(chain)
def read_rcol(self, stream, rcol): s = StreamReader(stream) self.read_tag(stream) self.version = s.u32() self.framerate = s.f32() cFrames = s.i32() offsets = [s.u32() for i in range(cFrames)] offsets.append(-1) for frame_index in range(cFrames): offset = offsets[frame_index] next = offsets[frame_index + 1] cBytes = next - offset if next > 0 else -1 data = stream.read(cBytes) self.frames.append(data)
def read(self, stream, resource=None): Light.read(self, stream) s = StreamReader(stream) self.at = [s.f32() for i in range(3)] self.right = [s.f32() for i in range(3)] self.width = s.f32() self.height = s.f32() self.falloff_angle = s.f32() self.window_top_bottom_angle = s.f32()
def read(self, stream, resource=None): s = StreamReader(stream) self.version_major = s.u32() self.version_minor = s.u32() cBones = s.i32() self.bones = [] opposites = [] parents = [] self.__hashes = {} for i in range(cBones): bone = Bone(self) bone.position = [s.f32() for i in range(3)] bone.orientation = [s.f32() for i in range(4)] bone.scale = [s.f32() for i in range(3)] bone.name = s.p32() opposites.append(s.i32()) parents.append(s.i32()) hash_name = s.u32() if not hash_name == FNV32.hash(bone.name): print("WARNING: Bone %s should have matching hash 0x%08X, but has 0x%08X",bone.name, FNV32.hash(bone.name),hash_name) self.__hashes[hash] = bone bone.flags = s.u32() self.bones.append(bone) for bone_index, opposite_index in enumerate(opposites): if opposite_index >= 0: self.bones[bone_index].opposite = self.bones[opposite_index] for bone_index, parent_index in enumerate(parents): if parent_index >= 0: self.bones[bone_index].parent = self.bones[parent_index] if self.version_major >= 4: self.name = s.p32() self.ik_chains = [] cChains = s.i32() for i in range(cChains): chain = IKChain(self) chain.read(stream) self.ik_chains.append(chain)
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(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())
class Buffer: def __init__(self): self.stream = BytesIO() self.reader = StreamReader(self.stream) self.writer = StreamWriter(self.stream) def delete_vertices(self, offset, vrtf, count): end_offset = offset + vrtf.stride * count self.stream.seek(end_offset, SEEK_SET) end_data = self.stream.read(-1) self.stream.seek(offset, SEEK_SET) self.stream.truncate() self.stream.writable(end_data) def read_vertices(self, offset, vrtf, count,uvscales): self.stream.seek(offset, SEEK_SET) return [self.read_vertex(vrtf,uvscales) for i in range(count)] def read_vertex(self, vrtf, uvscales): vertex = Vertex() start = self.stream.tell() end = start + vrtf.stride for declaration in vrtf.declarations: u = declaration.usage value = self.read_element(declaration,uvscales[declaration.usage_index]) if u == VertexFormat.USAGE.POSITION: vertex.position = value elif u == VertexFormat.USAGE.NORMAL: vertex.normal = value elif u == VertexFormat.USAGE.UV: if vertex.uv == None: vertex.uv = [] vertex.uv.append(value) elif u == VertexFormat.USAGE.BLEND_INDEX: vertex.blend_indices = value elif u == VertexFormat.USAGE.BLEND_WEIGHT: vertex.blend_weights = value elif u == VertexFormat.USAGE.COLOR: vertex.colour = value elif u == VertexFormat.USAGE.TANGENT: vertex.tangent = value else: raise Exception("Unknown usage %s", declaration.usage) actual = self.stream.tell() return vertex def write_vertices(self, vrtf, vertices, uvscales=None): self.stream.seek(0, SEEK_END) offset = self.stream.tell() for vertex in vertices: self.write_vertex(vrtf, vertex) def write_vertex(self, vrtf, v): for declaration in vrtf.declarations: u = declaration.usage if u == VertexFormat.USAGE.POSITION: data = v.position elif u == VertexFormat.USAGE.NORMAL: data = v.normal elif u == VertexFormat.USAGE.UV: data = v.uv[vrtf.usage_index] elif u == VertexFormat.USAGE.BLEND_INDEX: data = v.blend_indices elif u == VertexFormat.USAGE.BLEND_WEIGHT: data = v.blend_weights elif u == VertexFormat.USAGE.COLOR: data = v.colour elif u == VertexFormat.USAGE.TANGENT: data = v.tangents else: raise Exception('Unknown VRTF usage type %i' % u) self.write_element(declaration, data) def write_element(self, declaration, value): pass def read_element(self, declaration, uvscale): float_count = VertexFormat.FORMAT.float_count(declaration.format) value = [0.0] * float_count f = declaration.format u = declaration.usage if u == VertexFormat.USAGE.UV: if f == VertexFormat.FORMAT.SHORT2: for i in range(float_count): value[i] = self.reader.i16() * uvscale elif f == VertexFormat.FORMAT.SHORT4: shorts = [self.reader.i16() for i in range(4)] assert shorts[2] == 0 value = [shorts[0] /0x7FFF, shorts[1]/0x7FFF, shorts[3] /0x1FF] elif f in (VertexFormat.FORMAT.FLOAT, VertexFormat.FORMAT.FLOAT2, VertexFormat.FORMAT.FLOAT3, VertexFormat.FORMAT.FLOAT4): for i in range(float_count): value[i] = self.reader.f32() elif f == VertexFormat.FORMAT.UBYTE4: for i in range(float_count): value[i] = self.reader.i8() elif f == VertexFormat.FORMAT.COLOR_UBYTE4: if u == VertexFormat.USAGE.COLOR: for i in range(float_count): value[i] = self.reader.u8() / 0xFF elif u == VertexFormat.USAGE.BLEND_WEIGHT: for i in range(float_count): value[VertexFormat.FORMAT.UBYTE_MAP[i]] = self.reader.u8() / 0xFF elif u in (VertexFormat.USAGE.NORMAL, VertexFormat.USAGE.TANGENT): bytes = [self.reader.u8() for i in range(4)] for i in range(float_count - 1): value[i] = -1 if bytes[2 - i] == 0 else ( ((bytes[2 - i] + 1) / 128.0) - 1) determinant = 0.0 if not bytes[3]: determinant = -1.0 elif bytes[3] == 127.0: determinant = 0.0 elif bytes[3] == 255.0: determinant = 1.0 else: print("Unexpected handedness %i " % bytes[3]) value[float_count - 1] = determinant else: raise Exception("Unhandled usage %s for format %s" % (u, f)) elif f == VertexFormat.FORMAT.SHORT2: for i in range(float_count): value[i] = self.reader.i16() / 0xFFFF elif f == VertexFormat.FORMAT.SHORT4: shorts = [self.reader.i16() for i in range(3)] scalar = self.reader.u16() if not scalar: scalar = 0x7FFF for i in range(float_count): value[i] = float(shorts[i]) / float(scalar) elif f == VertexFormat.FORMAT.USHORT4N: shorts = [self.reader.i16() for i in range(3)] scalar = self.reader.u16() if not scalar: scalar = 511 for i in range(float_count): value[i] = shorts[i] / scalar elif f == VertexFormat.FORMAT.UBYTE4: data = [self.reader.i8() for i in range(4)] else: raise Exception("Unhandled format %s" % f) return value def __del__(self): if self.stream != None: self.stream.close()
def read(self, stream, tgi): s = StreamReader(stream) self.age_gender_flags = s.u32() self.amount = s.f32() self.geom = tgi.get_resource(s.u32())
def read(self, stream, resource=None): s = StreamReader(stream) Light.read(self, stream) self.at = [s.f32() for i in range(3)] self.falloff_angle = s.f32() self.blur_scale = s.f32()
def read(self, stream, resources=None): s = StreamReader(stream) self.position = [s.f32() for i in range(3)] self.scale = [s.f32() for i in range(3)] self.orientation = [s.f32() for i in range(4)]
def read(self, stream, resource=None): Light.read(self, stream) s = StreamReader(stream) self.at = [s.f32() for i in range(3)] self.right = [s.f32() for i in range(3)] self.radius = s.f32()
def read(self, stream, resource=None): s = StreamReader(stream) self.transform = [s.f32() for i in range(3)] self.colour = [s.f32() for i in range(3)] self.intensity = s.f32()
def read(self, stream, resource=None): Light.read(self, stream) s = StreamReader(stream) self.at = [s.f32() for i in range(3)] self.tube_length = s.f32() self.blur_scale = s.f32()
def read(self, stream, resource=None): Event.read(self, stream) s = StreamReader(stream) self.visibility = s.f32()
class Buffer: def __init__(self): self.stream = BytesIO() self.reader = StreamReader(self.stream) self.writer = StreamWriter(self.stream) def delete_vertices(self, offset, vrtf, count): end_offset = offset + vrtf.stride * count self.stream.seek(end_offset, SEEK_SET) end_data = self.stream.read(-1) self.stream.seek(offset, SEEK_SET) self.stream.truncate() self.stream.writable(end_data) def read_vertices(self, offset, vrtf, count, uvscales): self.stream.seek(offset, SEEK_SET) return [self.read_vertex(vrtf, uvscales) for i in range(count)] def read_vertex(self, vrtf, uvscales): vertex = Vertex() start = self.stream.tell() end = start + vrtf.stride for declaration in vrtf.declarations: u = declaration.usage value = self.read_element(declaration, uvscales[declaration.usage_index]) if u == VertexFormat.USAGE.POSITION: vertex.position = value elif u == VertexFormat.USAGE.NORMAL: vertex.normal = value elif u == VertexFormat.USAGE.UV: if vertex.uv == None: vertex.uv = [] vertex.uv.append(value) elif u == VertexFormat.USAGE.BLEND_INDEX: vertex.blend_indices = value elif u == VertexFormat.USAGE.BLEND_WEIGHT: vertex.blend_weights = value elif u == VertexFormat.USAGE.COLOR: vertex.colour = value elif u == VertexFormat.USAGE.TANGENT: vertex.tangent = value else: raise Exception("Unknown usage %s", declaration.usage) actual = self.stream.tell() return vertex def write_vertices(self, vrtf, vertices, uvscales=None): self.stream.seek(0, SEEK_END) offset = self.stream.tell() for vertex in vertices: self.write_vertex(vrtf, vertex) def write_vertex(self, vrtf, v): for declaration in vrtf.declarations: u = declaration.usage if u == VertexFormat.USAGE.POSITION: data = v.position elif u == VertexFormat.USAGE.NORMAL: data = v.normal elif u == VertexFormat.USAGE.UV: data = v.uv[vrtf.usage_index] elif u == VertexFormat.USAGE.BLEND_INDEX: data = v.blend_indices elif u == VertexFormat.USAGE.BLEND_WEIGHT: data = v.blend_weights elif u == VertexFormat.USAGE.COLOR: data = v.colour elif u == VertexFormat.USAGE.TANGENT: data = v.tangents else: raise Exception('Unknown VRTF usage type %i' % u) self.write_element(declaration, data) def write_element(self, declaration, value): pass def read_element(self, declaration, uvscale): float_count = VertexFormat.FORMAT.float_count(declaration.format) value = [0.0] * float_count f = declaration.format u = declaration.usage if u == VertexFormat.USAGE.UV: if f == VertexFormat.FORMAT.SHORT2: for i in range(float_count): value[i] = self.reader.i16() * uvscale elif f == VertexFormat.FORMAT.SHORT4: shorts = [self.reader.i16() for i in range(4)] assert shorts[2] == 0 value = [ shorts[0] / 0x7FFF, shorts[1] / 0x7FFF, shorts[3] / 0x1FF ] elif f in (VertexFormat.FORMAT.FLOAT, VertexFormat.FORMAT.FLOAT2, VertexFormat.FORMAT.FLOAT3, VertexFormat.FORMAT.FLOAT4): for i in range(float_count): value[i] = self.reader.f32() elif f == VertexFormat.FORMAT.UBYTE4: for i in range(float_count): value[i] = self.reader.i8() elif f == VertexFormat.FORMAT.COLOR_UBYTE4: if u == VertexFormat.USAGE.COLOR: for i in range(float_count): value[i] = self.reader.u8() / 0xFF elif u == VertexFormat.USAGE.BLEND_WEIGHT: for i in range(float_count): value[VertexFormat.FORMAT. UBYTE_MAP[i]] = self.reader.u8() / 0xFF elif u in (VertexFormat.USAGE.NORMAL, VertexFormat.USAGE.TANGENT): bytes = [self.reader.u8() for i in range(4)] for i in range(float_count - 1): value[i] = -1 if bytes[2 - i] == 0 else (( (bytes[2 - i] + 1) / 128.0) - 1) determinant = 0.0 if not bytes[3]: determinant = -1.0 elif bytes[3] == 127.0: determinant = 0.0 elif bytes[3] == 255.0: determinant = 1.0 else: print("Unexpected handedness %i " % bytes[3]) value[float_count - 1] = determinant else: raise Exception("Unhandled usage %s for format %s" % (u, f)) elif f == VertexFormat.FORMAT.SHORT2: for i in range(float_count): value[i] = self.reader.i16() / 0xFFFF elif f == VertexFormat.FORMAT.SHORT4: shorts = [self.reader.i16() for i in range(3)] scalar = self.reader.u16() if not scalar: scalar = 0x7FFF for i in range(float_count): value[i] = float(shorts[i]) / float(scalar) elif f == VertexFormat.FORMAT.USHORT4N: shorts = [self.reader.i16() for i in range(3)] scalar = self.reader.u16() if not scalar: scalar = 511 for i in range(float_count): value[i] = shorts[i] / scalar elif f == VertexFormat.FORMAT.UBYTE4: data = [self.reader.i8() for i in range(4)] else: raise Exception("Unhandled format %s" % f) return value def __del__(self): if self.stream != None: self.stream.close()
def read(self, stream, resources=None): s = StreamReader(stream) self.min = [s.f32() for i in range(self.dimensions)] self.max = [s.f32() for i in range(self.dimensions)]