Skip to content
Snippets Groups Projects
io_import_scene_unreal_psa_psk.py 48.7 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 hymat = Quaternion((0.707, -0.707, 0, 0)).inverted().to_matrix().to_4x4()
    
                    children_infos = {}
                    childrens = pose_bone.children
                    for child in childrens:
    
                        armmat = bpy.data.armatures['armaturedata'].bones[child.name].matrix.copy().to_4x4()
    
                        cmat = child.matrix.copy() * armmat.inverted() * hymat.inverted()
                        pos = cmat.to_translation()
                        rotmat = cmat.to_3x3()
    
                    #whirl this bone by quat
                    pose_bone.matrix *= quat.to_matrix().to_4x4()
                    pose_bone.keyframe_insert("location")
                    pose_bone.keyframe_insert("rotation_quaternion")
                    bpy.context.scene.update()
                    #set back children bon to original position 
                    #reverse whirl child bone by quat.inverse()
    
                    for child in childrens:
                        armmat = children_infos[child][0]
                        pos = children_infos[child][1]
                        rotmat = children_infos[child][2] 
    
                        child.matrix = Matrix.Translation(pos) * rotmat.to_4x4() * hymat * armmat 
                        child.keyframe_insert("location") 
                        child.keyframe_insert("rotation_quaternion")
    
                for bone in pose_bones:
                    if bone.parent != None:
    
                        whirlSingleBone(bone,Quaternion((0.707, 0, 0, -0.707)))
    
                        bone.rotation_quaternion *= Quaternion((0.707, -0.707, 0, 0)) * Quaternion((0.707, 0, 0, -0.707))
    
                        bone.keyframe_insert("rotation_quaternion")
    
        context.scene.frame_set(0)
        if(debug):
            logf.close()
    
    class IMPORT_OT_psa(bpy.types.Operator):
        '''Load a skeleton anim psa File'''
        bl_idname = "import_scene.psa"
        bl_label = "Import PSA"
        bl_space_type = "PROPERTIES"
        bl_region_type = "WINDOW"
    
        filepath = StringProperty(
                subtype='FILE_PATH',
                )
        filter_glob = StringProperty(
                default="*.psa",
                options={'HIDDEN'},
                )
    
        def execute(self, context):
            getInputFilenamepsa(self,self.filepath,context)
            return {'FINISHED'}
    
        def invoke(self, context, event):
            wm = context.window_manager
            wm.fileselect_add(self)
    
    
    class IMPORT_OT_psa(bpy.types.Operator):
        '''Load a skeleton anim psa File'''
        bl_idname = "import_scene.psa"
        bl_label = "Import PSA"
        bl_space_type = "PROPERTIES"
        bl_region_type = "WINDOW"
    
        filepath = StringProperty(
                subtype='FILE_PATH',
                )
        filter_glob = StringProperty(
                default="*.psa",
                options={'HIDDEN'},
                )
    
        def execute(self, context):
            getInputFilenamepsa(self,self.filepath,context)
            return {'FINISHED'}
    
        def invoke(self, context, event):
            wm = context.window_manager
            wm.fileselect_add(self)
    
    bpy.types.Scene.udk_importpsk = StringProperty(
    
            name = "Import .psk",
            description = "Skeleton mesh file path for psk",
            default = "")
    
    bpy.types.Scene.udk_importpsa = StringProperty(
    
            name = "Import .psa",
            description = "Animation Data to Action Set(s) file path for psa",
            default = "")
    
    bpy.types.Scene.udk_importarmatureselect = BoolProperty(
    
            name = "Armature Selected",
            description = "Select Armature to Import psa animation data",
            default = False)
    
    class Panel_UDKImport(bpy.types.Panel):
        bl_label = "UDK Import"
        bl_idname = "OBJECT_PT_udk_import"
        bl_space_type = "VIEW_3D"
        bl_region_type = "TOOLS"
    
        filepath = StringProperty(
    
                subtype='FILE_PATH',
                )
    
    
        #@classmethod
        #def poll(cls, context):
        #   return context.active_object
    
        def draw(self, context):
            layout = self.layout
            layout.operator(OBJECT_OT_PSKPath.bl_idname)
    
            layout.prop(context.scene, "udk_importarmatureselect")
            if bpy.context.scene.udk_importarmatureselect:
                layout.operator(OBJECT_OT_UDKImportArmature.bl_idname)
    
                layout.template_list("UI_UL_list", "udkimportarmature_list", context.scene, "udkimportarmature_list",
    
                                     context.scene, "udkimportarmature_list_idx", rows=5)
            layout.operator(OBJECT_OT_PSAPath.bl_idname)
    
    
    class OBJECT_OT_PSKPath(bpy.types.Operator):
    
        """Select .psk file path to import for skeleton mesh"""
    
        bl_idname = "object.pskpath"
        bl_label = "Import PSK Path"
    
        filepath = StringProperty(
                subtype='FILE_PATH',
                )
        filter_glob = StringProperty(
                default="*.psk",
                options={'HIDDEN'},
                )
        importmesh = BoolProperty(
                name="Mesh",
                description="Import mesh only. (not yet build.)",
                default=True,
                )
        importbone = BoolProperty(
                name="Bones",
                description="Import bones only. Current not working yet",
                default=True,
                )
        importmultiuvtextures = BoolProperty(
                name="Single UV Texture(s)",
                description="Single or Multi uv textures",
                default=True,
                )
        bDebugLogPSK = BoolProperty(
                name="Debug Log.txt",
                description="Log the output of raw format. It will save in " \
                            "current file dir. Note this just for testing",
                default=False,
                )
        unrealbonesize = FloatProperty(
                name="Bone Length",
                description="Bone Length from head to tail distance",
                default=1,
                min=0.001,
                max=1000,
                )
    
        def execute(self, context):
            #context.scene.importpskpath = self.properties.filepath
            bpy.types.Scene.unrealbonesize = self.unrealbonesize
    
            getInputFilenamepsk(self, self.filepath, self.importmesh, self.importbone, self.bDebugLogPSK,
                                self.importmultiuvtextures)
    
            return {'FINISHED'}
    
        def invoke(self, context, event):
            #bpy.context.window_manager.fileselect_add(self)
            wm = context.window_manager
            wm.fileselect_add(self)
            return {'RUNNING_MODAL'}
    
    class UDKImportArmaturePG(bpy.types.PropertyGroup):
    
        #boolean = BoolProperty(default=False)
        string = StringProperty()
        bexport = BoolProperty(default=False, name="Export", options={"HIDDEN"},
                               description = "This will be ignore when exported")
        bselect = BoolProperty(default=False, name="Select", options={"HIDDEN"},
                               description = "This will be ignore when exported")
        otype = StringProperty(name="Type",description = "This will be ignore when exported")
    
    
    bpy.utils.register_class(UDKImportArmaturePG)
    bpy.types.Scene.udkimportarmature_list = CollectionProperty(type=UDKImportArmaturePG)
    bpy.types.Scene.udkimportarmature_list_idx = IntProperty()
    
    class OBJECT_OT_PSAPath(bpy.types.Operator):
    
        """Select .psa file path to import for animation data"""
        bl_idname = "object.psapath"
        bl_label = "Import PSA Path"
    
        filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file",
                                  maxlen=1024, default="")
        filter_glob = StringProperty(
    
                default="*.psa",
                options={'HIDDEN'},
                )
    
    
        def execute(self, context):
            #context.scene.importpsapath = self.properties.filepath
            getInputFilenamepsa(self,self.filepath,context)
            return {'FINISHED'}
    
        def invoke(self, context, event):
            bpy.context.window_manager.fileselect_add(self)
            return {'RUNNING_MODAL'}
    
    
    class OBJECT_OT_UDKImportArmature(bpy.types.Operator):
    
        """This will update the filter of the mesh and armature"""
        bl_idname = "object.udkimportarmature"
        bl_label = "Update Armature"
    
        def execute(self, context):
            my_objlist = bpy.context.scene.udkimportarmature_list
            objectl = []
            for objarm in bpy.context.scene.objects:#list and filter only mesh and armature
                if objarm.type == 'ARMATURE':
                    objectl.append(objarm)
            for _objd in objectl:#check if list has in udk list
                bfound_obj = False
                for _obj in my_objlist:
                    if _obj.name == _objd.name and _obj.otype == _objd.type:
                        _obj.bselect = _objd.select
                        bfound_obj = True
                        break
                if bfound_obj == False:
                    #print("ADD ARMATURE...")
                    my_item = my_objlist.add()
                    my_item.name = _objd.name
                    my_item.bselect = _objd.select
                    my_item.otype = _objd.type
            removeobject = []
            for _udkobj in my_objlist:
                bfound_objv = False
                for _objd in bpy.context.scene.objects: #check if there no existing object from sense to remove it
                    if _udkobj.name == _objd.name and _udkobj.otype == _objd.type:
                        bfound_objv = True
                        break
                if bfound_objv == False:
                    removeobject.append(_udkobj)
            #print("remove check...")
            for _item in removeobject: #loop remove object from udk list object
                count = 0
                for _obj in my_objlist:
                    if _obj.name == _item.name and _obj.otype == _item.otype:
                        my_objlist.remove(count)
                        break
                    count += 1
            return{'FINISHED'}
    
    
    class OBJECT_OT_UDKImportA(bpy.types.Operator):
    
        """This will update the filter of the mesh and armature"""
        bl_idname = "object.udkimporta"
        bl_label = "Update Armature"
    
        def execute(self, context):
            for objd in bpy.data.objects:
                print("NAME:",objd.name," TYPE:",objd.type)
                if objd.type == "ARMATURE":
                    print(dir(objd))
                    print((objd.data.name))
            return{'FINISHED'}
    
    
    def menu_func(self, context):
        self.layout.operator(IMPORT_OT_psk.bl_idname, text="Skeleton Mesh (.psk)")
        self.layout.operator(IMPORT_OT_psa.bl_idname, text="Skeleton Anim (.psa)")
    
    def register():
        bpy.utils.register_module(__name__)
        bpy.types.INFO_MT_file_import.append(menu_func)
    
    def unregister():
        bpy.utils.unregister_module(__name__)
        bpy.types.INFO_MT_file_import.remove(menu_func)
    
    if __name__ == "__main__":
        register()
    
    #note this only read the data and will not be place in the scene    
    #getInputFilename('C:\\blenderfiles\\BotA.psk') 
    
    #getInputFilename('C:\\blenderfiles\\AA.PSK')