示例#1
0
 def import_geometry_object(self, b_armature, n_block):
     # it's a shape node and we're not importing skeleton only
     b_obj = self.create_mesh_object(n_block)
     b_obj.matrix_local = math.import_matrix(
         n_block)  # set transform matrix for the mesh
     self.mesh.import_mesh(n_block, b_obj)
     bpy.context.view_layer.objects.active = b_obj
     # store flags etc
     self.import_object_flags(n_block, b_obj)
     # skinning? add armature modifier
     if n_block.skin_instance:
         self.append_armature_modifier(b_obj, b_armature)
     return b_obj
 def import_transforms(self, n_block, b_obj, bone_name=None):
     """Loads an animation attached to a nif block."""
     # find keyframe controller
     n_kfc = math.find_controller(n_block, NifFormat.NiKeyframeController)
     # try again
     if not n_kfc:
         n_kfc = math.find_controller(n_block,
                                      NifFormat.NiTransformController)
     if n_kfc:
         # skeletal animation
         if bone_name:
             bone_bm = math.import_matrix(n_block)  # base pose
             n_bone_bind_scale, n_bone_bind_rot, n_bone_bind_trans = math.decompose_srt(
                 bone_bm)
             self.import_keyframe_controller(n_kfc, b_obj, bone_name,
                                             n_bone_bind_scale,
                                             n_bone_bind_rot.inverted(),
                                             n_bone_bind_trans)
         # object-level animation
         else:
             self.create_action(b_obj, b_obj.name + "-Anim")
             self.import_keyframe_controller(n_kfc, b_obj)
示例#3
0
    def import_branch(self, n_block, b_armature=None, n_armature=None):
        """Read the content of the current NIF tree branch to Blender recursively.

        :param n_block: The nif block to import.
        :param b_armature: The blender armature for the current branch.
        :param n_armature: The corresponding nif block for the armature for  the current branch.
        """
        if not n_block:
            return None

        NifLog.info(f"Importing data for block '{n_block.name.decode()}'")
        if isinstance(n_block, NifFormat.NiTriBasedGeom
                      ) and NifOp.props.process != "SKELETON_ONLY":
            return self.objecthelper.import_geometry_object(
                b_armature, n_block)

        elif isinstance(n_block, NifFormat.NiNode):
            # import object
            if self.armaturehelper.is_armature_root(n_block):
                # all bones in the tree are also imported by import_armature
                if NifOp.props.process != "GEOMETRY_ONLY":
                    b_obj = self.armaturehelper.import_armature(n_block)
                else:
                    n_name = block_store.import_name(n_block)
                    b_obj = math.get_armature()
                    NifLog.info(
                        f"Merging nif tree '{n_name}' with armature '{b_obj.name}'"
                    )
                    if n_name != b_obj.name:
                        NifLog.warn(
                            f"Using Nif block '{n_name}' as armature '{b_obj.name}' but names do not match"
                        )
                b_armature = b_obj
                n_armature = n_block

            elif self.armaturehelper.is_bone(n_block):
                # bones have already been imported during import_armature
                n_name = block_store.import_name(n_block)
                if n_name in b_armature.data.bones:
                    b_obj = b_armature.data.bones[n_name]
                else:
                    # this is a fallback for a weird bug, when a node is child of a NiLodNode in a skeletal nif
                    b_obj = self.objecthelper.create_b_obj(n_block,
                                                           None,
                                                           name=n_name)
                b_obj.niftools.flags = n_block.flags

            else:
                # import as an empty
                b_obj = NiTypes.import_empty(n_block)

            # find children
            b_children = []
            n_children = [child for child in n_block.children]
            for n_child in n_children:
                b_child = self.import_branch(n_child,
                                             b_armature=b_armature,
                                             n_armature=n_armature)
                if b_child and isinstance(b_child, bpy.types.Object):
                    b_children.append(b_child)

            # import collision objects & bounding box
            if NifOp.props.process != "SKELETON_ONLY":
                b_children.extend(self.import_collision(n_block))
                b_children.extend(
                    self.boundhelper.import_bounding_box(n_block))

            # set bind pose for children
            self.objecthelper.set_object_bind(b_obj, b_children, b_armature)

            # import extra node data, such as node type
            NiTypes.import_root_collision(n_block, b_obj)
            NiTypes.import_billboard(n_block, b_obj)
            NiTypes.import_range_lod_data(n_block, b_obj, b_children)

            # set object transform, this must be done after all children objects have been parented to b_obj
            if isinstance(b_obj, bpy.types.Object):
                # note: bones and this object's children already have their matrix set
                b_obj.matrix_local = math.import_matrix(n_block)

                # import object level animations (non-skeletal)
                if NifOp.props.animation:
                    # self.animationhelper.import_text_keys(n_block)
                    self.transform_anim.import_transforms(n_block, b_obj)
                    self.object_anim.import_visibility(n_block, b_obj)

            return b_obj

        # all else is currently discarded
        return None