def read_element(s, tgi_list): def read_complate_string(s): a = s.i8() if not a: return None if a & 0x80: return s.chars(s.i8() if a & 0x40 else a & 0x3F) if a & 0x40: a = (a & 0x3F) + s.i8() return self.complate_string_lookup[a] def read_typecode(s, tgi_list): tc = s.u8() if tc == 1: return read_complate_string(s) elif tc == 0x02: return [s.u8() for i in range(4)] elif tc == 0x03: return tgi_list.get_resource(s.i8()) elif tc == 0x04: return s.f32() elif tc == 0x05: return [s.f32() for i in range(2)] elif tc == 0x06: return [s.f32() for i in range(3)] elif tc == 0x07: return bool(s.i8()) else: raise Exception("Unknown typecode %02X" % tc) element = Preset.Element() element.resource = tgi_list.get_resource(s.u8()) element.name = read_complate_string(s) element.variable = read_complate_string(s) for i in range(s.i32()): name = read_complate_string(s) value = read_typecode(s, tgi_list) element.values[name] = value element.patterns = [ read_element(s, tgi_list) for i in range(s.i32()) ] return element
def load_object(objd, package): print('Loading object!') assert isinstance(objd, BuildBuyProduct) vpxy = first(package.find_all_type(VisualProxy.ID)).fetch(VisualProxy) armature_rig = None rig = package.find_key( first( vpxy.entries, lambda e: isinstance(e, VisualProxy.MiscEntry) and e. resource.key.t == SkeletonRig.ID).resource.key) if rig: try: rig = rig.fetch(SkeletonRig) armature_rig = load_rig(rig) except: print('Unable to load rig, please patch your game...') if not armature_rig: print('No rig found') armature_rig = create_marker_node(objd.resource_name, True) print('Loading Model...') modl = package.find_key( first( vpxy.entries, lambda e: isinstance(e, VisualProxy.MiscEntry) and e. resource.key.t == Model.ID).resource.key).fetch(Model) if any(objd.presets): preset = objd.presets[0] else: preset = package.find_key( ResourceKey(t=PackedPreset.ID, g=1, i=modl.key.i)) if preset: preset = preset.fetch(PackedPreset) else: preset = Preset() ml = MaterialLoader(package, preset) load_model(package, modl, armature_rig, ml) return armature_rig
def __init__(self, stream=None, resources=None): self.unknown = 0 Preset.__init__(self) Serializable.__init__(self,stream,resources)
def __init__(self): self.id = 0 self.unk1 = 1 self.unk2 = 0 Preset.__init__(self)
def load_caspart(caspart, package, armature_rig, morphs=False, expressions=False): print('Loading CASPart %s...' % caspart.resource_name) bgeo = {} preset = None loaded_morphs = [] # Loads a BlendGeometry and add it to the dictionary. If a key was already loaded, skip it. Either key or index must be specified. # If a name is provided, it will be used, otherwise it will default to the package name or the instance id def load_bgeo(key=None, name=None, index=None): if index: assert isinstance(index, Package.IndexEntry) key = index.key print('Loading %s %s' % (key, index)) if not key.i: print( 'Skipping invalid BlendGeometry %s: Instance must not be 0.' % key) return if key in loaded_morphs: print('Skipping BlendGeometry %s: Already loaded.' % key) return try: if not index: if key.t == BlendData.ID: blend_data = package.find_key(key).fetch(BlendData) assert isinstance(blend_data, BlendData) key = blend_data.blend_geometry.key index = package.find_key(key) if not index: print( 'Skipping BlendGeometry %s: Resource not found in package' % key) return assert isinstance(index, Package.IndexEntry) resource = index.fetch(BlendGeometry) assert isinstance(resource, BlendGeometry) if not name: name = resource.resource_name if not name: name = '%16X' % key.i bgeo[name] = resource loaded_morphs.append(key) except Exception as ex: print('Skipping BlendGeometry %s: Error loading' % key) print(ex) pass pass # Maps blend LOD vertex by it's id def map_blend_vertex(blend_lod): bvmap = {} for v in blend_lod.vertices: bvmap[v.id] = v return bvmap # Adds a bone to the skeleton def create_armature_bone(bone_name, parent_bone=None, min_bone=.001): set_context('EDIT', armature_rig) armature_bone = find_bone(armature_rig.data.edit_bones, bone_name) if not armature_bone: armature_bone = armature_rig.data.edit_bones.new(bone_name) armature_bone.use_connect = False armature_bone.tail = [0, min_bone, 0] if parent_bone: armature_bone.parent = armature_rig.data.edit_bones[parent_bone] set_context('POSE', armature_rig) return armature_bone if caspart: print('CASP found...') preset = package.find_key( ResourceKey(t=PackedPreset.ID, g=caspart.key.g, i=caspart.key.i)) if preset: preset = preset.fetch(PackedPreset) elif any(caspart.presets): preset = caspart.presets[0] part_name = caspart.part_name assert isinstance(caspart, CASPart) vpxy = package.get_resource(key=caspart.sources[0].key, wrapper=VisualProxy) # Load standard morphs if specified with user friendly name if morphs: if caspart.blend_fat.key.i: load_bgeo(name='Fat', key=caspart.blend_fat.key) if caspart.blend_fit.key.i: load_bgeo(name='Fit', key=caspart.blend_fit.key) if caspart.blend_thin.key.i: load_bgeo(name='Thin', key=caspart.blend_thin.key) if caspart.blend_special.key.i: load_bgeo(name='Pregnant', key=caspart.blend_special.key) else: print('No CASP found, defaulting to first VPXY') vpxy = first(package.find_all_type(VisualProxy.ID)) if vpxy: vpxy = vpxy.fetch(VisualProxy) assert isinstance(vpxy, VisualProxy) part_name = vpxy.resource_name print('Loading morphs...') for bgeo_index in package.find_all_type(BlendGeometry.ID): try: load_bgeo(index=bgeo_index) except Exception as ex: print("Unable to load morph %s" % bgeo_index) print(ex) if not preset: preset = Preset() ml = MaterialLoader(package, preset) lod_hi = first(vpxy.entries, lambda e: e.TYPE == VisualProxy.LodEntry.TYPE) assert isinstance(lod_hi, VisualProxy.LodEntry) # Arrange morph data for processing blend_vertex_lod_map = {} for blend_name in bgeo: cur_bgeo = bgeo[blend_name] for blend in cur_bgeo.blends: blend_vertex_lod_map[blend_name] = map_blend_vertex( blend.lods[lod_hi.index]) # Load face morphs for animal meshes. Loads any BodyGeometry matching the name 'Expression' as a morph if expressions: driver_root = 'b__DRIVERS__' create_armature_bone(driver_root) print('creating root: %s' % driver_root) for index in package.find_all_type(BodyGeometry.ID): assert isinstance(index, Package.IndexEntry) geom = index.fetch(BodyGeometry) assert isinstance(geom, BodyGeometry) if not 'Expressions' in geom.resource_name: continue blend_name = geom.resource_name[17:-2] create_armature_bone(blend_name, parent_bone=driver_root) blend_vertex_lod_map[blend_name] = map_blend_vertex(geom) meshes = [] for lod_sub_index, geom in enumerate( package.find_key(item.key).fetch(BodyGeometry) for item in lod_hi.resources): material = ml.generate('%s_%i' % (part_name, lod_sub_index), geom.material) meshes.append( load_geom(part_name + '_' + str(lod_sub_index), geom, blend_vertex_lod_map, armature_rig, material)) return meshes
def __init__(self): self.id = 0 Preset.__init__(self)
def __init__(self): self.type = 0 self.unk1 = 0 self.unk2 = 0 Preset.__init__(self)