Newer
Older
Bastien Montagne
committed
hymat = Quaternion((0.707, -0.707, 0, 0)).inverted().to_matrix().to_4x4()
children_infos = {}
childrens = pose_bone.children
for child in childrens:
Bastien Montagne
committed
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()
Bastien Montagne
committed
children_infos[child] = (armmat, pos, rotmat)
#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()
Bastien Montagne
committed
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:
Bastien Montagne
committed
whirlSingleBone(bone,Quaternion((0.707, 0, 0, -0.707)))
Bastien Montagne
committed
bone.rotation_quaternion *= Quaternion((0.707, -0.707, 0, 0)) * Quaternion((0.707, 0, 0, -0.707))
bone.keyframe_insert("rotation_quaternion")
Bastien Montagne
committed
Bastien Montagne
committed
context.scene.frame_set(0)
if(debug):
logf.close()
Bastien Montagne
committed
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
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)
Bastien Montagne
committed
return {'RUNNING_MODAL'}
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
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)
Bastien Montagne
committed
return {'RUNNING_MODAL'}
bpy.types.Scene.udk_importpsk = StringProperty(
Bastien Montagne
committed
name = "Import .psk",
description = "Skeleton mesh file path for psk",
default = "")
bpy.types.Scene.udk_importpsa = StringProperty(
Bastien Montagne
committed
name = "Import .psa",
description = "Animation Data to Action Set(s) file path for psa",
default = "")
bpy.types.Scene.udk_importarmatureselect = BoolProperty(
Bastien Montagne
committed
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(
Bastien Montagne
committed
#@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)
Bastien Montagne
committed
layout.template_list("UI_UL_list", "udkimportarmature_list", context.scene, "udkimportarmature_list",
Bastien Montagne
committed
context.scene, "udkimportarmature_list_idx", rows=5)
layout.operator(OBJECT_OT_PSAPath.bl_idname)
class OBJECT_OT_PSKPath(bpy.types.Operator):
Bastien Montagne
committed
"""Select .psk file path to import for skeleton mesh"""
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
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,
)
Bastien Montagne
committed
def execute(self, context):
#context.scene.importpskpath = self.properties.filepath
bpy.types.Scene.unrealbonesize = self.unrealbonesize
Bastien Montagne
committed
getInputFilenamepsk(self, self.filepath, self.importmesh, self.importbone, self.bDebugLogPSK,
self.importmultiuvtextures)
Bastien Montagne
committed
def invoke(self, context, event):
#bpy.context.window_manager.fileselect_add(self)
wm = context.window_manager
wm.fileselect_add(self)
return {'RUNNING_MODAL'}
Bastien Montagne
committed
class UDKImportArmaturePG(bpy.types.PropertyGroup):
Bastien Montagne
committed
#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):
Bastien Montagne
committed
"""Select .psa file path to import for animation data"""
bl_idname = "object.psapath"
bl_label = "Import PSA Path"
Bastien Montagne
committed
filepath = StringProperty(name="PSA File Path", description="Filepath used for importing the PSA file",
maxlen=1024, default="")
filter_glob = StringProperty(
default="*.psa",
options={'HIDDEN'},
)
Bastien Montagne
committed
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):
Bastien Montagne
committed
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
"""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):
Bastien Montagne
committed
"""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)
Bastien Montagne
committed
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')
Bastien Montagne
committed
#getInputFilename('C:\\blenderfiles\\AA.PSK')