コード例 #1
0
    def export_bounding_box(self, b_obj, block_parent):
        box_extends = self.calculate_box_extents(b_obj)
        n_bbox = types.create_ninode()
        block_parent.add_child(n_bbox)
        # set name, flags, translation, and radius
        n_bbox.name = "Bounding Box"
        n_bbox.flags = 4

        trans = n_bbox.translation
        trans.x = (box_extends[0][0] +
                   box_extends[0][1]) * 0.5 + b_obj.location[0]
        trans.y = (box_extends[1][0] +
                   box_extends[1][1]) * 0.5 + b_obj.location[1]
        trans.z = (box_extends[2][0] +
                   box_extends[2][1]) * 0.5 + b_obj.location[2]
        n_bbox.rotation.set_identity()
        n_bbox.has_bounding_box = True
        # Ninode's(n_bbox) behaves like a seperate mesh.
        # bounding_box center(n_bbox.bounding_box.trans) is relative to the bound_box
        n_bbox.bounding_box.translation.deepcopy(trans)
        n_bbox.bounding_box.rotation.set_identity()

        largest = self.calculate_largest_value(box_extends)
        radius = n_bbox.bounding_box.radius
        radius.x = largest[0]
        radius.y = largest[1]
        radius.z = largest[2]
コード例 #2
0
    def export_root_node(self, root_objects, filebase):
        """ Exports a nif's root node; use blender root if there is only one, else create a meta root """
        # TODO [collsion] detect root collision -> root collision node (can be mesh or empty)
        #     self.nif_export.collisionhelper.export_collision(b_obj, n_parent)
        #     return None  # done; stop here
        self.n_root = None
        # there is only one root object so that will be our final root
        if len(root_objects) == 1:
            b_obj = root_objects[0]
            self.export_node(b_obj, None)

        # there is more than one root object so we create a meta root
        else:
            NifLog.info("Created meta root because blender scene had multiple root objects")
            self.n_root = types.create_ninode()
            self.n_root.name = "Scene Root"
            for b_obj in root_objects:
                self.export_node(b_obj, self.n_root)

        # TODO [object] How dow we know we are selecting the right node in the case of multi-root?
        # making root block a fade node
        root_type = b_obj.niftools.rootnode
        if bpy.context.scene.niftools_scene.game in ('FALLOUT_3', 'SKYRIM') and root_type == 'BSFadeNode':
            NifLog.info("Making root block a BSFadeNode")
            fade_root_block = NifFormat.BSFadeNode().deepcopy(self.n_root)
            fade_root_block.replace_global_node(self.n_root, fade_root_block)
            self.n_root = fade_root_block

        # various extra datas
        object_property = ObjectDataProperty()
        object_property.export_bsxflags_upb(self.n_root, root_objects)
        object_property.export_inventory_marker(self.n_root, root_objects)
        object_property.export_weapon_location(self.n_root, b_obj)
        types.export_furniture_marker(self.n_root, filebase)
        return self.n_root
コード例 #3
0
    def export_collision(self, b_obj, n_parent):
        """Main function for adding collision object b_obj to a node.
        Returns True if this object is exported as a collision"""

        if b_obj.display_type != "BOUNDS":
            return
        if b_obj.name.lower().startswith('bsbound'):
            # add a bounding box
            self.bs_helper.export_bounds(b_obj, n_parent, bsbound=True)

        elif b_obj.name.lower().startswith("bounding box"):
            # Morrowind bounding box
            self.bs_helper.export_bounds(b_obj, n_parent, bsbound=False)
        if bpy.context.scene.niftools_scene.game in ('OBLIVION', 'FALLOUT_3',
                                                     'SKYRIM'):

            nodes = [n_parent]
            nodes.extend([
                block for block in n_parent.children
                if block.name[:14] == 'collisiondummy'
            ])
            for node in nodes:
                try:
                    self.bhk_helper.export_collision_helper(b_obj, node)
                    break
                except ValueError:  # adding collision failed
                    continue
            else:
                # all nodes failed so add new one
                node = types.create_ninode(b_obj)
                node.name = 'collisiondummy{:d}'.format(n_parent.num_children)
                if b_obj.niftools.flags != 0:
                    node_flag_hex = hex(b_obj.niftools.flags)
                else:
                    node_flag_hex = 0x000E  # default
                node.flags = node_flag_hex
                n_parent.add_child(node)
                self.bhk_helper.export_collision_helper(b_obj, node)

        elif bpy.context.scene.niftools_scene.game in ('ZOO_TYCOON_2', ):
            self.bound_helper.export_nicollisiondata(b_obj, n_parent)
        else:
            NifLog.warn(
                f"Collisions not supported for game '{bpy.context.scene.niftools_scene.game}', skipped collision object '{b_obj.name}'"
            )

        return True
コード例 #4
0
    def export_bone(self, b_obj, b_bone, n_parent_node):
        """Exports a bone and all of its children."""
        # create a new nif block for this b_bone
        n_node = types.create_ninode(b_bone)
        n_node.name = block_store.get_full_name(b_bone)
        # link to nif parent node
        n_parent_node.add_child(n_node)

        self.export_bone_flags(b_bone, n_node)
        # rest pose
        math.set_object_matrix(b_bone, n_node)

        # per-bone animation
        self.transform_anim.export_transforms(n_node, b_obj, self.b_action,
                                              b_bone)
        # continue down the bone tree
        for b_child in b_bone.children:
            self.export_bone(b_obj, b_child, n_node)
コード例 #5
0
    def export_node(self, b_obj, n_parent):
        """Export a mesh/armature/empty object b_obj as child of n_parent.
        Export also all children of b_obj.

        :param n_parent:
        :param b_obj:
        """

        if not b_obj:
            return None

        b_action = self.object_anim.get_active_action(b_obj)

        # can we export this b_obj?
        if b_obj.type not in self.export_types:
            return None
        if b_obj.type == 'MESH':
            if self.export_collision(b_obj, n_parent):
                return
            else:
                # -> mesh data.
                is_multimaterial = len(set([f.material_index for f in b_obj.data.polygons])) > 1

                # determine if object tracks camera
                # nb normally, imported models will have tracking constraints on their parent empty
                # but users may create track_to constraints directly on objects, so keep it for now
                has_track = types.has_track(b_obj)

                # If this has children or animations or more than one material it gets wrapped in a purpose made NiNode.
                if not (b_action or b_obj.children or is_multimaterial or has_track):
                    mesh = self.mesh_helper.export_tri_shapes(b_obj, n_parent, self.n_root, b_obj.name)
                    if not self.n_root:
                        self.n_root = mesh
                    return mesh

                # set transform on trishapes rather than NiNodes for skinned meshes to fix an issue with clothing slots
                if b_obj.parent and b_obj.parent.type == 'ARMATURE' and b_action:
                    # mesh with armature parent should not have animation!
                    NifLog.warn(f"Mesh {b_obj.name} is skinned but also has object animation. "
                                f"The nif format does not support this, ignoring object animation.")
                    b_action = False

        # -> everything else (empty/armature) is a (more or less regular) node
        node = types.create_ninode(b_obj)
        # set parenting here so that it can be accessed
        if not self.n_root:
            self.n_root = node

        # make it child of its parent in the nif, if it has one
        if n_parent:
            n_parent.add_child(node)

        # and fill in this node's non-trivial values
        node.name = block_store.get_full_name(b_obj)
        self.set_node_flags(b_obj, node)
        math.set_object_matrix(b_obj, node)

        # export object animation
        self.transform_anim.export_transforms(node, b_obj, b_action)
        self.object_anim.export_visibility(node, b_action)
        # if it is a mesh, export the mesh as trishape children of this ninode
        if b_obj.type == 'MESH':
            return self.mesh_helper.export_tri_shapes(b_obj, node, self.n_root)
        # if it is an armature, export the bones as ninode children of this ninode
        elif b_obj.type == 'ARMATURE':
            self.armaturehelper.export_bones(b_obj, node)

        # export all children of this b_obj as children of this NiNode
        self.export_children(b_obj, node)

        return node