def import_object_animation(self, n_block, b_obj):
     """
     Loads an animation attached to a nif block (non-skeletal).
     Becomes the object level animation of the blender object.
     """
     NifLog.debug('Importing animation for object %s'.format(b_obj.name))
     
     kfc = nif_utils.find_controller(n_block, NifFormat.NiKeyframeController)
     if kfc:
         self.nif_import.animationhelper.create_action(b_obj, b_obj.name+"-Anim" )
         self.import_keyframe_controller(kfc, b_obj)
 def import_material_alpha_controller(self, b_material, n_material):
     # find alpha controller
     n_alphactrl = nif_utils.find_controller(n_material, NifFormat.NiAlphaController)
     if not(n_alphactrl and n_alphactrl.data):
         return
     NifLog.info("Importing alpha controller")
     
     b_mat_action = self.nif_import.animationhelper.create_action( b_material, "MaterialAction")
     fcurves = self.nif_import.animationhelper.create_fcurves(b_mat_action, "alpha", (0,), n_alphactrl.flags)
     interp = self.nif_import.animationhelper.get_b_interp_from_n_interp( n_alphactrl.data.data.interpolation)
     for key in n_alphactrl.data.data.keys:
         self.nif_import.animationhelper.add_key(fcurves, key.time, (key.value, ), interp)
    def import_morph_controller(self, n_node, b_obj, v_map):
        """Import NiGeomMorpherController as shape keys for blender object."""
        
        morphCtrl = nif_utils.find_controller(n_node, NifFormat.NiGeomMorpherController)
        if morphCtrl:
            b_mesh = b_obj.data
            morphData = morphCtrl.data
            if morphData.num_morphs:
                b_obj_action = self.nif_import.animationhelper.create_action( b_obj, b_obj.name + "-Morphs")
                fps = bpy.context.scene.render.fps
                # get name for base key
                keyname = morphData.morphs[0].frame_name.decode()
                if not keyname:
                    keyname = 'Base'
                
                # insert base key at frame 1, using relative keys
                sk_basis = b_obj.shape_key_add(keyname)
                
                # get base vectors and import all morphs
                baseverts = morphData.morphs[0].vectors
                
                for idxMorph in range(1, morphData.num_morphs):
                    # get name for key
                    keyname = morphData.morphs[idxMorph].frame_name.decode()
                    if not keyname:
                        keyname = 'Key %i' % idxMorph
                    NifLog.info("Inserting key '{0}'".format(keyname))
                    # get vectors
                    morphverts = morphData.morphs[idxMorph].vectors
                    self.morph_mesh(b_mesh, baseverts, morphverts, v_map)
                    shape_key = b_obj.shape_key_add(keyname, from_mix=False)

                    # first find the keys
                    # older versions store keys in the morphData
                    morphdata = morphData.morphs[idxMorph]
                    # newer versions store keys in the controller
                    if not morphdata.keys:
                        try:
                            if morphCtrl.interpolators:
                                morphdata = morphCtrl.interpolators[idxMorph].data.data
                            elif morphCtrl.interpolator_weights:
                                morphdata = morphCtrl.interpolator_weights[idxMorph].interpolator.data.data
                        except:
                            NifLog.info("Unsupported interpolator '{0}'".format( type(morphCtrl.interpolator_weights[idxMorph].interpolator) ))
                            continue
                    # TODO [anim] can we create the fcurve manually - does not seem to work here?
                    # as b_obj.data.shape_keys.animation_data is read-only
                    
                    # FYI shape_key = b_mesh.shape_keys.key_blocks[-1]
                    # set keyframes
                    for key in morphdata.keys:
                        shape_key.value = key.value
                        shape_key.keyframe_insert(data_path="value", frame=round(key.time * fps))
 def import_bone_animation(self, n_block, b_armature_obj, bone_name):
     """
     Loads an animation attached to a nif block (skeletal).
     Becomes the pose bone level animation of the blender object.
     """
     NifLog.debug('Importing animation for bone %s'.format(bone_name))
     
     kfc = nif_utils.find_controller(n_block, NifFormat.NiKeyframeController)
     if kfc:
         bone_bm = nif_utils.import_matrix(n_block) # base pose
         niBone_bind_scale, niBone_bind_rot, niBone_bind_trans = nif_utils.decompose_srt(bone_bm)
         niBone_bind_rot_inv = niBone_bind_rot.to_4x4().inverted()
         self.import_keyframe_controller(kfc, b_armature_obj, bone_name, niBone_bind_scale, niBone_bind_rot_inv, niBone_bind_trans)
    def import_object_vis_controller(self, n_node, b_obj ):
        """Import vis controller for blender object."""
        
        n_vis_ctrl = nif_utils.find_controller(n_node, NifFormat.NiVisController)
        if not(n_vis_ctrl and n_vis_ctrl.data):
            return
        NifLog.info("Importing vis controller")
        
        b_obj_action = self.nif_import.animationhelper.create_action( b_obj, b_obj.name + "-Anim")

        fcurves = self.nif_import.animationhelper.create_fcurves(b_obj_action, "hide", (0,), n_vis_ctrl.flags)
        for key in n_vis_ctrl.data.keys:
            self.nif_import.animationhelper.add_key(fcurves, key.time, (key.value, ), "CONSTANT")
 def import_material_uv_controller(self, b_material, n_geom):
     """Import UV controller data."""
     # search for the block
     n_ctrl = nif_utils.find_controller(n_geom, NifFormat.NiUVController)
     if not(n_ctrl and n_ctrl.data):
         return
     NifLog.info("Importing UV controller")
     
     b_mat_action = self.nif_import.animationhelper.create_action( b_material, "MaterialAction")
     
     dtypes = ("offset", 0), ("offset", 1), ("scale", 0), ("scale", 1)
     for n_uvgroup, (data_path, array_ind) in zip(n_ctrl.data.uv_groups, dtypes):
         if n_uvgroup.keys:
             interp = self.nif_import.animationhelper.get_b_interp_from_n_interp( n_uvgroup.interpolation )
             #in blender, UV offset is stored per texture slot
             #so we have to repeat the import for each used tex slot
             for i, texture_slot in enumerate(b_material.texture_slots):
                 if texture_slot:
                     fcurves = self.nif_import.animationhelper.create_fcurves(b_mat_action, "texture_slots["+str(i)+"]."+data_path, (array_ind,), n_ctrl.flags )
                     for key in n_uvgroup.keys:
                         if "offset" in data_path:
                             self.nif_import.animationhelper.add_key(fcurves, key.time, (-key.value, ), interp)
                         else:
                             self.nif_import.animationhelper.add_key(fcurves, key.time, (key.value, ), interp)