Ejemplo n.º 1
0
        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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
 def __init__(self, stream=None, resources=None):
     self.unknown = 0
     Preset.__init__(self)
     Serializable.__init__(self,stream,resources)
Ejemplo n.º 4
0
 def __init__(self):
     self.id = 0
     self.unk1 = 1
     self.unk2 = 0
     Preset.__init__(self)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
 def __init__(self):
     self.id = 0
     Preset.__init__(self)
Ejemplo n.º 7
0
    def __init__(self):
        self.type = 0
        self.unk1 = 0
        self.unk2 = 0

        Preset.__init__(self)