vpoteryaev Posted February 18, 2017 Author Posted February 18, 2017 In addition to issue with flickering. Some thoughts and calculations Skyrim uses ZYX-Euler (i don't remember correct left or right) system. All transforms to Blender's system while import and back while export sometimes makes me crazy.Why flickering happens with Thigh bones more frequently. Maybe because they default data in skeleton. For example, LThig has X: 177.877319; Y: -5.655318; Z: 177.616911 in Euler rotation.With transforming it to axis-angle system we got x: -0.01985; y: 0.99965; z: -0.01747, but angle IS: 185.70, and exceeds 180 degrees. In 'common' cases this is not 'normal', like counting angles over 360 degrees, but accepted. For example while animating some mesh in blender with using 3600 in Eulers data for some of the axis will cause this mesh to rotate exactly 10 times.Quaternion can be created from this rough data with two ways:quat1 = Quaternion(-0.049721, -0.01985, 0.99965, -0.01747))i.e. via direct using w-x-y-z from Nifscope, ORquat2 = Quaternion((-0.01985, 0.99965, -0.01747), radians(185.7))i.e. via axis-angle data. They ARE EQUAL, but NEGATIVE to each-other.
gsll Posted February 18, 2017 Posted February 18, 2017 To Vpoteryaev : Sorry for the misunderstanding about flickering. I am afraid I cannot be of much help. I have attempted to use your tool to make a paired animation. Basically, here is the attempt to make a paired animation rig in blender (base on the information by kentington) The first step involves importing two sets of skeletons - either two humans or a human and a creature, depending on your intended animation - into Max. You'll need to link both skeletons beneath a bone named PairedRoot, then apply the prefix "2_" to the second skeleton's bones, as shown below:[PairedRoot]->[NPC]->->[NPC Root]->[2_]->->[2_NPC Root]Since the NifTools importer will overwrite any bone with a duplicate name, your best bet is to import the second skeleton first and apply the prefix (highlight all bones, click Tools->Rename Objects, check Prefix and enter "2_" into the box). Make sure to change "2_NPC" to "2_" if it exists, or create it if it does not. Move the second skeleton to its desired starting position and orientation, import meshes if desired, and animate the two actors as you normally would. Thus : 1 - import a nif skeleton in blender using Skyrim nif-data utils 2 - select the skeleton, move it and rotate 180° (so that the two imported skeletons won't be at the same place) 3 - rename 'NPC' bone as '2_' and prefix other bones name's with '2_'This can be achieved running the following script :import bpy# Active objectob = bpy.context.objectif ob.type == 'ARMATURE': armature = ob.data for bone in armature.bones: print(bone.name) temp=bone.name if temp='NPC' bone.name='2_' else bone.name='2_'+temp print(bone.name)4- import a second nif skeleton in blender using Skyrim nif-data utils 5 - add a new bone, name it [PairedRoot] 6 - Make bone [2_] and bone [NPC] children of bone [PairedRoot] 7- Export the skeleton as a nif file using Skyrim nif-data utils 8 - Create a basic animation (frame by frame) on each of the imported skeleton. 9 - Export the animation as a kf file using Skyrim nif-data utils. For now, I have only tested the result in NIFSKOPE (SKYRIM not yet reinstalled). The paired skeleton seem to open alright in NIFSKOPE. The animation on the skeleton without prefix imports in NIFSKOPE The other animation does not show. I have to think it over a bit. Best regards PS : I don't intend to hijack the thread. If you feel this should be continued elsewhere, I'll move it. Your wonderful tool just re-opened this perspective of paired animation.
gsll Posted February 18, 2017 Posted February 18, 2017 To Vpoteryaev : It seems to me these information may be appropriate for "baking" animation from IK constraints : http://blender.stackexchange.com/questions/40711/how-to-convert-quaternions-keyframes-to-euler-ones-in-several-actions The script referenced below is more or less equivalent to : OBJECT MODE : menu object -> animation -> bake action POSE MODE : menu pose -> animation -> bake action automate baking of armature actions in python Better to work on the copy of an action as all constraints are deleted in the process.... Best regards
vpoteryaev Posted February 19, 2017 Author Posted February 19, 2017 Yay!!! My first animation was completely done - "Strip Manager" is updated with "standing strip feet" animation.
vpoteryaev Posted February 19, 2017 Author Posted February 19, 2017 To Vpoteryaev : Sorry for the misunderstanding about flickering. I am afraid I cannot be of much help. I have attempted to use your tool to make a paired animation. Basically, here is the attempt to make a paired animation rig in blender (base on the information by kentington) The first step involves importing two sets of skeletons - either two humans or a human and a creature, depending on your intended animation - into Max. You'll need to link both skeletons beneath a bone named PairedRoot, then apply the prefix "2_" to the second skeleton's bones, as shown below: [PairedRoot] ->[NPC] ->->[NPC Root] ->[2_] ->->[2_NPC Root] Since the NifTools importer will overwrite any bone with a duplicate name, your best bet is to import the second skeleton first and apply the prefix (highlight all bones, click Tools->Rename Objects, check Prefix and enter "2_" into the box). Make sure to change "2_NPC" to "2_" if it exists, or create it if it does not. Move the second skeleton to its desired starting position and orientation, import meshes if desired, and animate the two actors as you normally would. Thus : 1 - import a nif skeleton in blender using Skyrim nif-data utils 2 - select the skeleton, move it and rotate 180° (so that the two imported skeletons won't be at the same place) 3 - rename 'NPC' bone as '2_' and prefix other bones name's with '2_' This can be achieved running the following script : import bpy # Active object ob = bpy.context.object if ob.type == 'ARMATURE': armature = ob.data for bone in armature.bones: print(bone.name) temp=bone.name if temp='NPC' bone.name='2_' else bone.name='2_'+temp print(bone.name) 4- import a second nif skeleton in blender using Skyrim nif-data utils 5 - add a new bone, name it [PairedRoot] 6 - Make bone [2_] and bone [NPC] children of bone [PairedRoot] 7- Export the skeleton as a nif file using Skyrim nif-data utils 8 - Create a basic animation (frame by frame) on each of the imported skeleton. 9 - Export the animation as a kf file using Skyrim nif-data utils. For now, I have only tested the result in NIFSKOPE (SKYRIM not yet reinstalled). The paired skeleton seem to open alright in NIFSKOPE. The animation on the skeleton without prefix imports in NIFSKOPE The other animation does not show. I have to think it over a bit. Best regards PS : I don't intend to hijack the thread. If you feel this should be continued elsewhere, I'll move it. Your wonderful tool just re-opened this perspective of paired animation. I'm very glad that you give me ideas. Please, don't hesistate to post new ones. Even they a bit forwarding current stages of my work, but this thread will not disappears at moment. At any time I can reread that have been posted by you or someone else. My first animation is out - so tested last fix with 'flickering', seems work. Next step - import bodies. And of course, catching BUGs. Kind Regards.
vpoteryaev Posted February 23, 2017 Author Posted February 23, 2017 To Vpoteryaev : Well, you are right. The IK bones will probably have no effect on the displayed animation in game as the mesh is only weight painted against the deform bones of the skeleton.As I understand it, the 'blender nif plugin' is said to be able to import mesh and skeleton and export mesh and skeleton.I refer to this one : blender_nif_plugin-2.6.0a0.dev4-20-jun-16 The 'skyrim nif-data utils' allows to import skeleton and export skeleton and animation. Thus, with these two tools installed, I should be able to import a model from skyrim with its skeleton, make an animation and export it as a kf file without ever using blender 2.49. Then, use khxcmd on the kf animation file and the nif skeleton file to produce the hkx animation file that can be used in SKYRIM. I am interested in making wrestling animation. I've read about a trick to make paired animation : zaz paired animation rig and paired animation export tutorial by kentington It is roughly based on creating a paired root then importing a first skeleton prefixing its bone by 2_and then importing a second skeleton. I have unfortunately not found any rig demonstrating this in blender. Have you ? Do you think this approach is compatible with your tool (I am thinking of the xpmse limitation you wrote about) ? For further export of the paired animation, I have read the limitation of hkxcmd can be overriden by an appropriate "switch" -s. The method is described further in the tutorial : animating in skyrim with custom bones (blender/hkxcmd) Normally, green light : all the tools are available an newest blender. Time for testing... Best regards After a short rest i did quick test Even at current stage you can create PAIRED animations. How I did test.blend with canine and human. 1. Import human skeleton, attach to it body 2. IN ANOTHER Blender instance import wolf's skeleton, in 'object mode' copy it to buffer 3. Switch to first window, paste wolf's skeleton, attach to it wolf's body-parts As nif-data utils CAN IMPORT ANY skeleton this can be made with any creature (even for creature-creature animations) I see no limit to create tripple-foursome, up to 5 actors that SL supports (if you plan to create SL-animations) 4. Create animation For quick test I have to used SexLab functionality. 5. With wolf's skeleton selected export animation as 'paired_test_canine.kf' 6. select humans skeleton, export as 'paired_test_human.kf' 7. convert them to .hkx with named accordingly: 'paired_test_canine_A2_S1.hkx' and 'paired_test_human_A1_S1.hkx' The way to integrate them into SL - your troubles. I see no reason to reastrain from usage of my 'AnimTester' that i created somehow for llabsky and simple attached test animations to it. All FNIS praparations (i.e. behavior files created.....) After installation just re-run 'FNIS for Users'. Go to 'AnimTester' MCM and ensure that '(AT) paired_test nif-data (wolf)' and '(AT) paired_test nif-data (dog)' are selected. Re-register SexLab animations. For testing in-game look for, or summon, or PlaceAtMe any dog or wolf (even DeathHound) Select it with 'N' key for SexLab selection Goto SexLab's 'Animation Editor' tab, select in animation '(AT) paired_test nif-data (dog)' or '(AT) paired_test nif-data (wolf)' and play. Everything works. NOTE: I see no restrictions with copy-paste buffer to move already fully created rigs between .blend files Kind Regards. blend and kfs.7z AnimTester.7z
gsll Posted February 25, 2017 Posted February 25, 2017 To Vpoteryaev : Thank you for the information. I have to try this. I am presently trying to build a rig (FK/IK) to prepare for animation. Looking at the imported rig, I realized some of the bones had weird angles. At the moment, I have spotted : - NPC R PreBreast or NPC L preBreast (asymetry) - Belly - NPC L PreButt or NPC R Prebutt (asymetry) - NPC R ForearmTwist1, NPC R ForearmTwist2 - NPC R Hand - NPC L ForearmTwist1, NPC L ForearmTwist2 - NPC L Hand - NPC Spine I won't be using wings bones, skirtbones and special bones. So, my check is not thorough and there might be more bones to consider. An advanced rigger expertise would be needed to spot all of them. The forearm twist bones should be aligned with Forearm bone, just like the upperarm twist bones are aligned with upperarm bone. The hand bones should be aligned with the hand. The spine bone should be more vertical. The prebutt and prebreast bone should be symetrical L & R. belly should be pointing towards front. I have not experimented enough to find a work around. Need to experiment with the rig further. Best regards.
vpoteryaev Posted February 25, 2017 Author Posted February 25, 2017 To Vpoteryaev : Thank you for the information. I have to try this. I am presently trying to build a rig (FK/IK) to prepare for animation. Looking at the imported rig, I realized some of the bones had weird angles. At the moment, I have spotted : - NPC R PreBreast or NPC L preBreast (asymetry) - Belly - NPC L PreButt or NPC R Prebutt (asymetry) - NPC R ForearmTwist1, NPC R ForearmTwist2 - NPC R Hand - NPC L ForearmTwist1, NPC L ForearmTwist2 - NPC L Hand - NPC Spine I won't be using wings bones, skirtbones and special bones. So, my check is not thorough and there might be more bones to consider. An advanced rigger expertise would be needed to spot all of them. The forearm twist bones should be aligned with Forearm bone, just like the upperarm twist bones are aligned with upperarm bone. The hand bones should be aligned with the hand. The spine bone should be more vertical. The prebutt and prebreast bone should be symetrical L & R. belly should be pointing towards front. I have not experimented enough to find a work around. Need to experiment with the rig further. Best regards. In Blender it mostly has no matter how bones are aligned. In current NifTools builds (I tried them) bones alignment in Blender works only one way, regardless settings due logical errors in scripts. But in Blender 2.49 NifTools you can choose "Tail" or "Tail+Roll". This choice works in my scripts too. Even in my .blend 'example' files is used "Tail", for myself i prefer "Tail+Roll". It's done for 'visual' kindness. Also, how else 'zero'-length bone can be displayed in Blender? While exporting a reverce convertation to 'original' skeleton data is performed. Anyway, mostly for animations exact 'default' bone's position has no matter (sometimes for me is too hard to explain smth. with English), because relative rotations/offsets from 'default' position are taken into account. Kind Regards.
gsll Posted February 26, 2017 Posted February 26, 2017 To Vpoteryaev : I found it is possible to call other programs within blender. With this script, I managed to run hkxcmd for blender, provided all the necessary files are in the same root as the blend file. import bpyimport osimport sysimport subprocessFileName_hkxcmd = os.path.join(os.path.dirname(bpy.data.filepath), 'hkxcmd.exe')FileName_skeletonhkx=os.path.join(os.path.dirname(bpy.data.filepath), 'skeleton.hkx')FileName_empty_newkf=os.path.join(os.path.dirname(bpy.data.filepath), 'empty_new.kf')FileName_empty_newhkx=os.path.join(os.path.dirname(bpy.data.filepath), 'empty_new.hkx')subprocess.call([FileName_hkxcmd,'convertkf',FileName_skeletonhkx,FileName_empty_newkf,FileName_empty_newhkx]) It is still not very convenient. I have tried to use blender GUI to allow the use of file browser (hkxcmd.exe is supposed to be in the same directory as blend file). Hereafter is my attempt. import bpyfrom bpy.props import (StringProperty, PointerProperty, )from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup, ) import osimport sysimport subprocess# ------------------------------------------------------------------------# ui# ------------------------------------------------------------------------class Path_shkx(PropertyGroup): path_shkx = StringProperty( name="truc", description="Path to hkx skeleton file", default="", maxlen=1024, subtype='FILE_PATH') class Path_akf(PropertyGroup): path_akf = StringProperty( name="", description="Path to kf animaton file", default="", maxlen=1024, subtype='FILE_PATH')class Path_ahkx(PropertyGroup): path_ahkx= StringProperty( name="", description="Path to hkx animaton file", default="", maxlen=1024, subtype='FILE_PATH') class OBJECT_PT_my_panel(Panel): bl_idname = "OBJECT_PT_my_panel" bl_label = "hkxcmd convert kf file to hkx file" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_category = "Tools" bl_context = "objectmode" def draw(self, context): layout = self.layout scn = context.scene col = layout.column(align=True) col.prop(scn.shkx, "path_shkx", text="Skeleton hkx file") col = layout.column(align=True) col.prop(scn.akf, "path_akf", text="Animation kf file") col = layout.column(align=True) col.prop(scn.ahkx, "path_ahkx", text="Animation hkx file") col = layout.column(align=True) col.operator("convert2.hkx") ## The OK button in the error dialog#class OkOperator(bpy.types.Operator): bl_idname = "convert2.hkx" bl_label = "OK" def execute(self, context): # print the path to the console scn = context.scene FileName_hkxcmd = os.path.join(os.path.dirname(bpy.data.filepath), 'hkxcmd.exe') FileName_skeletonhkx = bpy.path.abspath(scn.shkx.path_shkx) FileName_animationkf = bpy.path.abspath(scn.akf.path_akf) FileName_animationhkx = bpy.path.abspath(scn.ahkx.path_ahkx) subprocess.call([FileName_hkxcmd,'convertkf', FileName_skeletonhkx,FileName_animationkf,FileName_animationhkx]) print('passed') return {'FINISHED'} # ------------------------------------------------------------------------# register and unregister functions# ------------------------------------------------------------------------def register(): bpy.utils.register_module(__name__) bpy.types.Scene.shkx = PointerProperty(type=Path_shkx) bpy.types.Scene.akf = PointerProperty(type=Path_akf) bpy.types.Scene.ahkx = PointerProperty(type=Path_ahkx)def unregister(): bpy.utils.unregister_module(__name__) del bpy.types.Scene.shkx del bpy.types.Scene.ahkx del bpy.types.Scene.akf if __name__ == "__main__": register() I suspect the file browser gives a relative path whereas hkxcmd expects an absolute path. Do you have any clue about solving the problem ? Edit : I feel I have solved the problem.... My bad knowledgde of blender python Best regards
gsll Posted February 27, 2017 Posted February 27, 2017 To Vpoteryaev : I thank you for your useful advice and explanations. I think I can find a way to create rig bones on top of the skeleton to simplfy the animation job. Best regards Edit : I found the kind of rig I intended to work on already exists for blender. Animation Tools N3 Rig Custom 1.5 This custom rig is provided with a script that allows to get a hkx animation file directly. In fact, some steps with KFmaker.exe and hkxcmd.exe are scripted. I wish I had screened the script earlier. I would have acquired some knowledge about filepath handling in blender. Still need to translate the web pages and understand the rig functionality. I seems to me this rig is not based on XPMSE.
gsll Posted February 27, 2017 Posted February 27, 2017 To vpoteryaev : Your work on the nif data utils is very inspiring. Your breaktrough gave me the energy to make this little script tu use hkcmd from blender. - ahkx -> kf - ahkx -> akhx xml - ahkx xml -> ahkx - ahkx + shkx -> kf import bpyfrom bpy.props import (StringProperty, PointerProperty, )from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup, ) import osimport sysimport subprocess# ------------------------------------------------------------------------# ui# ------------------------------------------------------------------------class Path_shkx(PropertyGroup): path_shkx = StringProperty( name="", description="Path to hkx skeleton file", default="", maxlen=1024, subtype='FILE_PATH') class Path_akf(PropertyGroup): path_akf = StringProperty( name="", description="Path to kf animaton file", default="*.kf", options={'HIDDEN'}, maxlen=1024, subtype='FILE_PATH')class Path_ahkx(PropertyGroup): path_ahkx= StringProperty( name="", description="Path to hkx animaton file", default="*.hkx", maxlen=1024, subtype='FILE_PATH') class OBJECT_PT_Converthkx2kf_panel(Panel): bl_idname = "OBJECT_PT_Converthkx2kf_panel" bl_label = "hkxcmd convert hkx file to kf file" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_category = "HKXCMD" bl_context = "objectmode" def draw(self, context): layout = self.layout scn = context.scene col = layout.column(align=True) col.prop(scn.ahkx, "path_ahkx", text="Animation hkx file") col = layout.column(align=True) col.operator("convert2.kf") ## The <Convert to kf> button in the error dialog#class RunConvertkf(bpy.types.Operator): bl_idname = "convert2.kf" bl_label = "Convert to kf" def execute(self, context): # print the path to the console scn = context.scene print(scn.ahkx.path_ahkx) FileName_hkxcmd = os.path.join(os.path.dirname(bpy.data.filepath), 'hkxcmd.exe') FileName_animationhkx = bpy.path.abspath(scn.ahkx.path_ahkx) print(FileName_animationhkx) FileName_skeletonhkx=os.path.join(os.path.dirname(bpy.data.filepath), 'skeleton.hkx') # convert hkx files to kf files subprocess.call([FileName_hkxcmd,'exportkf',FileName_animationhkx]) print('passed') return {'FINISHED'} class OBJECT_PT_Convert2hkx_panel(Panel): bl_idname = "OBJECT_PT_Convert2hkx_panel" bl_label = "hkxcmd convert kf file to hkx file" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_category = "HKXCMD" bl_context = "objectmode" def draw(self, context): layout = self.layout scn = context.scene col = layout.column(align=True) col.prop(scn.shkx, "path_shkx", text="Skeleton hkx file") col = layout.column(align=True) col.prop(scn.akf, "path_akf", text="Animation kf file") col = layout.column(align=True) col.prop(scn.ahkx, "path_ahkx", text="Animation hkx file") col = layout.column(align=True) col.operator("convertkf2.hkx") ## The <Convert to hkx> button in the error dialog#class RunConvert2hkx(bpy.types.Operator): bl_idname = "convertkf2.hkx" bl_label = "Convert to hkx" def execute(self, context): # print the path to the console scn = context.scene print(scn.shkx.path_shkx) FileName_hkxcmd = os.path.join(os.path.dirname(bpy.data.filepath), 'hkxcmd.exe') FileName_skeletonhkx = bpy.path.abspath(scn.shkx.path_shkx) # FileName_skeletonhkx = os.path.abspath(scn.shkx.path_shkx) FileName_animationkf = bpy.path.abspath(scn.akf.path_akf) FileName_animationhkx = bpy.path.abspath(scn.ahkx.path_ahkx) print(FileName_skeletonhkx) print(FileName_animationkf) print(FileName_animationhkx) subprocess.call([FileName_hkxcmd,'convertkf',FileName_skeletonhkx,FileName_animationkf,FileName_animationhkx]) print('passed') return {'FINISHED'} class OBJECT_PT_Converthkx2xml_panel(Panel): bl_idname = "OBJECT_PT_Converthkx2xml_panel" bl_label = "hkxcmd convert hkx file to xml file" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_category = "HKXCMD" bl_context = "objectmode" def draw(self, context): layout = self.layout scn = context.scene col = layout.column(align=True) col.prop(scn.ahkx, "path_ahkx", text="hkx file") col = layout.column(align=True) col.operator("convert2.xml") ## The <Convert to xml> button in the error dialog#class RunConvertxml(bpy.types.Operator): bl_idname = "convert2.xml" bl_label = "Convert to xml" def execute(self, context): # print the path to the console scn = context.scene print(scn.ahkx.path_ahkx) FileName_hkxcmd = os.path.join(os.path.dirname(bpy.data.filepath), 'hkxcmd.exe') FileName_animationhkx = bpy.path.abspath(scn.ahkx.path_ahkx) print(FileName_animationhkx) FileName_skeletonhkx=os.path.join(os.path.dirname(bpy.data.filepath), 'skeleton.hkx') # convert hkx files to xml hkx files subprocess.call([FileName_hkxcmd,'convert',FileName_animationhkx]) print('passed') return {'FINISHED'} class OBJECT_PT_Convertxml2hkx_panel(Panel): bl_idname = "OBJECT_PT_Convertxml2hkx_panel" bl_label = "hkxcmd convert xml file to hkx file" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_category = "HKXCMD" bl_context = "objectmode" def draw(self, context): layout = self.layout scn = context.scene col = layout.column(align=True) col.prop(scn.ahkx, "path_ahkx", text="Animation hkx file") # placeholder : modify this col = layout.column(align=True) col.operator("convertxml2.hkx") ## The <Convert to xml> button in the error dialog#class RunConvertxml(bpy.types.Operator): bl_idname = "convertxml2.hkx" bl_label = "Convert to hkx" def execute(self, context): # print the path to the console scn = context.scene print(scn.ahkx.path_ahkx) FileName_hkxcmd = os.path.join(os.path.dirname(bpy.data.filepath), 'hkxcmd.exe') FileName_animationhkx = bpy.path.abspath(scn.ahkx.path_ahkx) print(FileName_animationhkx) FileName_skeletonhkx=os.path.join(os.path.dirname(bpy.data.filepath), 'skeleton.hkx') # convert hkx files to xml hkx files subprocess.call([FileName_hkxcmd,'convert -v: win32',FileName_animationhkx]) print('passed') return {'FINISHED'} # ------------------------------------------------------------------------# register and unregister functions# ------------------------------------------------------------------------def register(): bpy.utils.register_module(__name__) bpy.types.Scene.shkx = PointerProperty(type=Path_shkx) bpy.types.Scene.akf = PointerProperty(type=Path_akf) bpy.types.Scene.ahkx = PointerProperty(type=Path_ahkx)def unregister(): bpy.utils.unregister_module(__name__) del bpy.types.Scene.shkx del bpy.types.Scene.ahkx del bpy.types.Scene.akf if __name__ == "__main__": register() Still needs testing, polishing and advices. edit : I forgot about the handbook, this is a blender script, copy the script, paste it in a text window in blender run the script, you get a new panel. This panel allows to browse for the files and run hkxcmd from blender. It allows to perform the following conversion : - hkx animation file -> kf animation file, - hkx animation file -> hkx xml animation file - hkx xml animation file -> hkx animation file - kf animation file + skeleton animation file -> hkx animation file About this one, does the '-s' switch really allows to export all bones ? See this post Best regards
gsll Posted March 2, 2017 Posted March 2, 2017 To vpoteryaev : Thank you for the tip of copying/pasting skeleton from one instanciation of blender to another. I am gathering the required elements to start animation. I think I'll try to animate basic moves of the viking wrestling GLIMA. My work flow should be : - open animation N3 custom rig (see upwards) in blender, - animate with it, - open an other instanciation of blender, - import XPMSE skeleton in this instanciation with your tool, - copy/paste XPMSE skeleton - copy bone position from the animate rig to XPMSE rig (probably script), - export animation with your tool as a kf file, - ... Best regards
gsll Posted March 6, 2017 Posted March 6, 2017 To vpoteryaev : I found some interesting stuff about hkx animation format : havok binary files some example code from havok a good explanation of spline compressed animation an other interesting explanation (less illustrated) from first article and other readings, I understand skyrim uses spline compression to store skeletal animation. It means there is no simple correspondance between hkx compressed format and input animation. One has to use the compression/decompression algorithms. The two last links describe the type of algorithm that cab be used for spline compression and data storage. From second link, a demo of spline compression in havok, I guess the spline compression may use 40-48 bits to store rotation as quaternions. In the thread "havok binary file", the fifth page reports a C# code that allows to convert hkx skeleton to smd format hkx2smd edit : volfin quotation : "This is a project I started last year for Alien:Isolation, it's a HKX converter that outputs SMD skeleton. It works with 2012.2.0 and 2010.2.0, I had intended to take it all the way with support for many versions, and animation output, but I simply moved on to other projects. It's written in C#, a lot of the file structure is defined at the top of Program.cs, and maybe will help people, so I'm making the code public." edit edit : I forgot to add the smd file can be imported in blender using blender source tool from steamreview.org It is still a two step partial import (skeleton only). Like many others I would prefer to select my files, press a button and get the result. Unfortunalety, this program hkx2smd is beyond my present understanding of coding : generic class, MarshalAs,... I probably won't be able to make use of these pieces of information to build a code within blender in a reasonable time. But making it available here, I hope one of the talented people here will be able to use it somehow. Best regards
Tweens Posted March 11, 2017 Posted March 11, 2017 (edited) Would someone be kind enough to explain to me (ELI5) how to install the prerequisites for this? The link to github for Pyffi 2.2.3 and nifxml-0.7.1.0 seems to be for source code. I have no idea how to build a Python Module or what is to be done with the nifxml. I have Pyffi 2.2.2 installed and I have the nifxml that is bundled with Nif Tools; but I presume that that isn't enough, since Blender will not install the plugin. I'm an artist, not a programmer, dammit........LOL. Any assistance will be greatly appreciated. NM... I got it installed. Aaaaaaaaand....... I get this error, so I don't have it installed correctly.... <sigh> Traceback (most recent call last):File "C:\Blender Foundation 276\2.78\scripts\modules\addon_utils.py", line 330, in enablemod = __import__(module_name)File "C:\Users\Jim-2\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\io_nifdata\__init__.py", line 47, in from . import import_nifdataFile "C:\Users\Jim-2\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\io_nifdata\import_nifdata.py", line 43, in import pyffi.spells.nifImportError: No module named 'pyffi' Edited March 11, 2017 by Tweens
vpoteryaev Posted March 12, 2017 Author Posted March 12, 2017 Would someone be kind enough to explain to me (ELI5) how to install the prerequisites for this? The link to github for Pyffi 2.2.3 and nifxml-0.7.1.0 seems to be for source code. I have no idea how to build a Python Module or what is to be done with the nifxml. I have Pyffi 2.2.2 installed and I have the nifxml that is bundled with Nif Tools; but I presume that that isn't enough, since Blender will not install the plugin. I'm an artist, not a programmer, dammit........LOL. Any assistance will be greatly appreciated. NM... I got it installed. Aaaaaaaaand....... I get this error, so I don't have it installed correctly.... <sigh> Traceback (most recent call last): File "C:\Blender Foundation 276\2.78\scripts\modules\addon_utils.py", line 330, in enable mod = __import__(module_name) File "C:\Users\Jim-2\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\io_nifdata\__init__.py", line 47, in from . import import_nifdata File "C:\Users\Jim-2\AppData\Roaming\Blender Foundation\Blender\2.78\scripts\addons\io_nifdata\import_nifdata.py", line 43, in import pyffi.spells.nif ImportError: No module named 'pyffi' Unpack downloaded 'pyffi-pyffi-2.2.3.zip', inside unpacked data run 'pyffi-pyffi-2.2.3\install.bat'. To check that all installed, goto '[blender_folder]\2.78\python\lib\site-packages\' and check 'pyffi' folder exists. To continue you have to go to path '[blender_folder]\2.78\python\lib\site-packages\pyffi\formats\nif\nifxml\' and place into 'nif.xml' from 'nifxml-0.7.1.0.zip' In your case [blender_folder] is 'C:\Users\Jim-2\AppData\Roaming\Blender Foundation\Blender' Kind Regards.
Tweens Posted March 12, 2017 Posted March 12, 2017 Unpack downloaded 'pyffi-pyffi-2.2.3.zip', inside unpacked data run 'pyffi-pyffi-2.2.3\install.bat'. To check that all installed, goto '[blender_folder]\2.78\python\lib\site-packages\' and check 'pyffi' folder exists. To continue you have to go to path '[blender_folder]\2.78\python\lib\site-packages\pyffi\formats\nif\nifxml\' and place into 'nif.xml' from 'nifxml-0.7.1.0.zip' In your case [blender_folder] is 'C:\Users\Jim-2\AppData\Roaming\Blender Foundation\Blender' Kind Regards. When I run the bat file I get this error: ERROR: The system was unable to find the specified registry key or value. Traceback (most recent call last): File "setup.py", line 2, in from setuptools import setup ImportError: No module named setuptools Press any key to continue . . .
vpoteryaev Posted March 12, 2017 Author Posted March 12, 2017 When I run the bat file I get this error: ERROR: The system was unable to find the specified registry key or value. Traceback (most recent call last): File "setup.py", line 2, in from setuptools import setup ImportError: No module named setuptools Press any key to continue . . . Then simpliest way will be de-install Blender via 'Programs and Features'. Delete 'C:\Users\Jim-2\AppData\Roaming\Blender Foundation\'. And install Blender again to be sure all pathes and registry entries are correct. Kind Regards.
vpoteryaev Posted March 13, 2017 Author Posted March 13, 2017 Thanks to Tweens with post and to gsll for keeping me still interested with this work Quick fix for work with baking - eliminated restriction to use only 'LocRot' keyframes.Not tested myself in-game, but exporting to .kf was successful. I tried 'Pose->Animation->Bake Action...' with 'Only Selected' and 'Visual Keying' are checked.NOTES:1. Anyway, first frame for animated bone must have Location and Rotation data. Seems baking always do that. Maybe I'm wrong...2. Scaling f-curve's data simply ignored.3. Acton name restriction is removed, but anyway must be ONE action per skeleton.Bug reports are very-very-welcome.If script works OK, I'll try to find solution to reduce .kf size with not exporting unnecessary entries. For example if animation has 60 frames, .kf has 60 equal each other Translation Keys too, or if bone some time stays in rest, but all Rotation Keys in this range are duplicated. Unpack in '\io_nifdata\animation\' with replacement.bake_fix.7z Kind Regards.
gsll Posted March 14, 2017 Posted March 14, 2017 To vpoteryaev : I have downloaded your new import script. I will take a look. My wrestling project seems out of reach ATM. It requires advanced rigging to be efficient. I need to try and succeed more simple things before. I think a script that issues a custom rig out of an imported skeleton (similar to anton custom rig) should be a reachable target. Should be : - DEF bones : imported skeleton on which mesh will be skinned (*) - IK bones : custom bones for IK chains, - FK bones : custom bones for FK, - IK/FK switch based on drivers and bones so that a rig can be copy/pasted without loss (or so I expect) - mechanism bones to ease some complex movements. In the end, only DEF bones have to be exported (or so it seems in Skyrim). For now, I have studied the anton custom rig and started to gather information about rigging and scripting. and started to build a custom rig without scripting. I hope to come up with something to show within the week. Best regards (*) rotation constraint should be implemented on this one and weight painted accordingly. For example, rotation along bone axis of UpperArmtwist1 , and UpperArmtwist2 should be an half of rotation along axis of UpperArm to avoid "bad twisting".
Kulu YaCock Posted May 4, 2017 Posted May 4, 2017 So I contacted vpoteryaev about the flickering issue and he replied: I don't have enough free time to create new anims myself and with it catch bugs in nif-utils. Functionality uses blender's nif-plugin algorithm. I adapt it to modern versions only. With some improvements to allow copy-paste between instances without loosing anything. I didn't create anims in 2.49 but seems this jerking/fleckering must happens too. When I created nif-utils and catch this issue, i just used T-pose and rotate one thigh left-right to pass z-axis. At first i thought it's my fault. Then i downloaded 'anton animations tools' and did same things. Result was exactly the same (I'm just curious: why nobody noticed it?). Then i dig into resulting .kf and noticed quaternion's 'switch'. In your video i noticed this jerk only once in second loop and it's not really noticeable if passing z-axis are not too often. Seems there is no common solution for this issue - at least for me. I'm not animator or too enough skilled in high mathematics (about 20 years passed when i studied in university). Maybe sometimes 'my solution' must be turned off? Or realated to 'particular' bones? Just open in any text-editor '2.78\scripts\addons\io_nifdata\animation\export_data.py'. Locate lines: if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: quat.negate() They about 210-211 numbers and put in '#' to BEGINNING of lines: if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: # quat.negate() prev_quat = quat rot_frame.value.w = quat.w rot_frame.value.x = quat.x Same things must be done with 'frame-by-frame' part, lines 276: #vlk test with quaternion's vector don't jump over 90 degrees quat = Quaternion((rot_curve[frame].w, rot_curve[frame].x, rot_curve[frame].y, rot_curve[frame].z)) # if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: # self.nif_export.dbg("bone {}, frame {} found jump".format(bone.name, frame)) # self.nif_export.dbg("prev {}\ncurr {}".format(prev_quat.axis, quat.axis)) # quat.negate() prev_quat = quat Be carefull, Python is sensitive to 'space' and 'TAB' symbols (even i'm programmer, i really HATE this language with his stupid 'tabulating' format rules and not strictly assigned to types variables... LOL, i'm going away...). DO NOT use 'Enter', 'Space', 'TAB' on keyboard, just put '#'s. Save file, launch Blender. Kind Regards Video I linked him: *It "flickers" right as "ROOT COM" (the bone I'm oscillating here, but it occurs with all bones) passes through a certain orientation. From what I can understand through his reply, he thinks that his quaternion-flip check might sometimes need to be skipped; however, even after commenting out those bits, the flicker still occurs. Further, I experimented by typing in a bunch of gibberish that I was sure would spit out an error somewhere. #vlk test with quaternion's vector don't jump over 90 degrees quat = Quaternion((rot_curve[frame].w, rot_curve[frame].x, rot_curve[frame].y, rot_curve[frame].z)) # if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: # self.nif_export.dbg("bone {}, frame {} found jump".format(bone.name, frame)) # self.nif_export.dbg("prev {}\ncurr {}".format(prev_quat.axis, quat.axis)) # quat.negate() afafafafakfgdjsagd djiosajgoidjsa there's no way that the interpreter can compile this ifjdoisajfg;idas320q5039809 0195ui093ut09asi98v[9538a908f05302ai9tj3poiajtpoidsakfpod6546468465841fd685sa41f58484f843864a864f83a46 prev_quat = quat Yet to my surprise, it managed a perfectly usable .kf that I converted to .hkx and tested without a problem (except for the fact that it still flickered). Seeing as how it didn't error, I might have put the script in the wrong directory where it isn't being used at all. Can anyone confirm? I put the plugin inside: ...Blender 2.78\2.78\scripts\addons and the "patched" export_data.py into: ...Blender 2.78\2.78\scripts\addons\io_nifdata\animation "Blender 2.78" is the root folder that contains the launch executable. I export using frame-by-frame and I bake the action beforehand. EDIT: If someone were to point me in the right direction for where the plugin outputs debug information, that'd be great. EDIT2: Turns out, a restart of blender is required whenever a plugin script is changed. Commenting out the quaternion flipping fixed the flickering from NPC COM rotating on global Y. Gonna test with other rotations later.
vpoteryaev Posted May 5, 2017 Author Posted May 5, 2017 So I contacted vpoteryaev about the flickering issue and he replied: I don't have enough free time to create new anims myself and with it catch bugs in nif-utils. Functionality uses blender's nif-plugin algorithm. I adapt it to modern versions only. With some improvements to allow copy-paste between instances without loosing anything. I didn't create anims in 2.49 but seems this jerking/fleckering must happens too. When I created nif-utils and catch this issue, i just used T-pose and rotate one thigh left-right to pass z-axis. At first i thought it's my fault. Then i downloaded 'anton animations tools' and did same things. Result was exactly the same (I'm just curious: why nobody noticed it?). Then i dig into resulting .kf and noticed quaternion's 'switch'. In your video i noticed this jerk only once in second loop and it's not really noticeable if passing z-axis are not too often. Seems there is no common solution for this issue - at least for me. I'm not animator or too enough skilled in high mathematics (about 20 years passed when i studied in university). Maybe sometimes 'my solution' must be turned off? Or realated to 'particular' bones? Just open in any text-editor '2.78\scripts\addons\io_nifdata\animation\export_data.py'. Locate lines: if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: quat.negate() They about 210-211 numbers and put in '#' to BEGINNING of lines: if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: # quat.negate() prev_quat = quat rot_frame.value.w = quat.w rot_frame.value.x = quat.x Same things must be done with 'frame-by-frame' part, lines 276: #vlk test with quaternion's vector don't jump over 90 degrees quat = Quaternion((rot_curve[frame].w, rot_curve[frame].x, rot_curve[frame].y, rot_curve[frame].z)) # if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: # self.nif_export.dbg("bone {}, frame {} found jump".format(bone.name, frame)) # self.nif_export.dbg("prev {}\ncurr {}".format(prev_quat.axis, quat.axis)) # quat.negate() prev_quat = quat Be carefull, Python is sensitive to 'space' and 'TAB' symbols (even i'm programmer, i really HATE this language with his stupid 'tabulating' format rules and not strictly assigned to types variables... LOL, i'm going away...). DO NOT use 'Enter', 'Space', 'TAB' on keyboard, just put '#'s. Save file, launch Blender. Kind Regards Video I linked him: *It "flickers" right as "ROOT COM" (the bone I'm oscillating here, but it occurs with all bones) passes through a certain orientation. From what I can understand through his reply, he thinks that his quaternion-flip check might sometimes need to be skipped; however, even after commenting out those bits, the flicker still occurs. Further, I experimented by typing in a bunch of gibberish that I was sure would spit out an error somewhere. #vlk test with quaternion's vector don't jump over 90 degrees quat = Quaternion((rot_curve[frame].w, rot_curve[frame].x, rot_curve[frame].y, rot_curve[frame].z)) # if degrees(abs(prev_quat.axis.angle(quat.axis))) > 90: # self.nif_export.dbg("bone {}, frame {} found jump".format(bone.name, frame)) # self.nif_export.dbg("prev {}\ncurr {}".format(prev_quat.axis, quat.axis)) # quat.negate() afafafafakfgdjsagd djiosajgoidjsa there's no way that the interpreter can compile this ifjdoisajfg;idas320q5039809 0195ui093ut09asi98v[9538a908f05302ai9tj3poiajtpoidsakfpod6546468465841fd685sa41f58484f843864a864f83a46 prev_quat = quat Yet to my surprise, it managed a perfectly usable .kf that I converted to .hkx and tested without a problem (except for the fact that it still flickered). Seeing as how it didn't error, I might have put the script in the wrong directory where it isn't being used at all. Can anyone confirm? I put the plugin inside: ...Blender 2.78\2.78\scripts\addons and the "patched" export_data.py into: ...Blender 2.78\2.78\scripts\addons\io_nifdata\animation "Blender 2.78" is the root folder that contains the launch executable. I export using frame-by-frame and I bake the action beforehand. EDIT: If someone were to point me in the right direction for where the plugin outputs debug information, that'd be great. EDIT2: Turns out, a restart of blender is required whenever a plugin script is changed. Commenting out the quaternion flipping fixed the flickering from NPC COM rotating on global Y. Gonna test with other rotations later. Here little update that allows to disable my 'solution' for quaternion jumping in export dialog. So you don't need waste time to edit scripts and restore backups. Just overwrite existing files. It will be very helpfull if 'jumps' for particular bones were tested. Then I will add checks for that bones and don't use 'solution' for them directly in script. Or will add text-property like 'Moved Bones' where bones that don't require 'jump' check are listed. Kind Regards switch_option_update.7z UPDATED: By the way, debug info you can view in Blender's internal 'Text Editor' with 'Nif_IO_Debug' named.
Kulu YaCock Posted May 6, 2017 Posted May 6, 2017 I still don't understand why disabling what is supposed to "fix" the flipping fixed the flipping... Well after a few more animation tests I couldn't reproduce the flickering so I'm just going to leave it as is and hope it stays that way. Hopefully that update will help others in the future. Thanks for this amazing plugin. EDIT: Adjectives.
vpoteryaev Posted May 9, 2017 Author Posted May 9, 2017 Version 1.00 beta.Added functionality to import animations from .kf file. I didn't perform tests but with a pair tries I got correct 'mt_idle' in blender.To use:1. goto 'File->Import->Skyrim nif-format Data (.nif)'.2. in left file-select panel choose .nif with skeleton3. Choose "Import skeleton"4. In '.kf file' window type name with extension, for example 'mt_idle.kf'. Animation file and skeletion file MUST be placed AT SAME DIRECTORY!5. Choose import.6. After that a body may be attached like. 'File-Import....' again, clear '.kf file' window, choose 'Import Body' and select .nif.7. When done, select imported body, "Alt-P"->'Clear Parent'. Delete in outliner useless now 'Scene Root', add Armature Modifier to imported body with selecting imported with animation skeleton.8. Repeat step 7 for hands, e.t.c.Sorry, but for now i have no time to make more user-friendly inerface, but will do someday.Again, bug-reports are very welcome!!!Kind Regards.
vpoteryaev Posted May 9, 2017 Author Posted May 9, 2017 I found some time with testing.I don't know what to do with non-uniform scaling. Seems most of 3DsMax-created animations have this warning in hkxcmd, and not accepted by my plug-in.I never used 3dxMax, and tools for them and can't understand scaling jumping around 1.0. All vanilla animations have no this issue.As example here a mix of my 'strip_boots' animation with wolf's 'aggrowarning1.hkx'. No problems.What do you think? Even scaling is unnatural, maybe will add they handling? wolf_aggrowarning1_strip_boots_mix.blend.7z Kind Regards.
gsll Posted May 11, 2017 Posted May 11, 2017 congratulations ! You made it ! I wish I had more time.... gsll
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now