Пример #1
0
    def create_animation(self, blender_context, ms3d_model,
                         blender_mesh_objects, blender_to_ms3d_bones):
        ##########################
        # setup scene
        blender_scene = blender_context.scene

        if not self.options_use_animation:
            ms3d_model.animation_fps = 24
            ms3d_model.number_total_frames = 1
            ms3d_model.current_time = 0
            return

        frame_start = blender_scene.frame_start
        frame_end = blender_scene.frame_end
        frame_total = (frame_end - frame_start) + 1
        frame_step = blender_scene.frame_step
        frame_offset = 0

        fps = blender_scene.render.fps * blender_scene.render.fps_base
        time_base = 1.0 / fps

        base_bone_correction = Matrix.Rotation(pi / 2, 4, 'Z')

        for blender_mesh_object in blender_mesh_objects:
            blender_bones = None
            blender_action = None
            blender_nla_tracks = None

            # note: only one armature modifier/parent will be handled.
            #   if the parent is an armature, it will be handled irrespective
            #   of existence of any armature modifier

            # question: maybe it is better to handle
            #   all existing armature sources (parent / modifier)
            #   as a merged animation...
            #   what is best practice in case of multiple animation sources?

            # take parent to account if it is an armature
            if blender_mesh_object.parent and \
                    blender_mesh_object.parent_type == 'ARMATURE' and \
                    blender_mesh_object.parent.pose:
                blender_bones = blender_mesh_object.parent.data.bones
                blender_pose_bones = blender_mesh_object.parent.pose.bones
                if blender_mesh_object.parent.animation_data:
                    blender_action = \
                            blender_mesh_object.parent.animation_data.action
                    blender_nla_tracks = \
                            blender_mesh_object.parent.animation_data.nla_tracks

                # apply transform
                if self.options_apply_transform:
                    matrix_transform = blender_mesh_object.parent.matrix_basis
                else:
                    matrix_transform = 1

            # search for animation modifier
            else:
                for blender_modifier in blender_mesh_object.modifiers:
                    if blender_modifier.type == 'ARMATURE' \
                            and blender_modifier.object.pose:
                        blender_bones = blender_modifier.object.data.bones
                        blender_pose_bones = blender_modifier.object.pose.bones
                        if blender_modifier.object.animation_data:
                            blender_action = \
                                    blender_modifier.object.animation_data.action
                            blender_nla_tracks = \
                                    blender_modifier.object.animation_data.nla_tracks

                        # apply transform
                        if self.options_apply_transform:
                            matrix_transform = blender_modifier.object.matrix_basis
                        else:
                            matrix_transform = 1

                        break

            # skip animation/bone handling, if no animation data is available
            if blender_bones is None \
                    and (blender_action is None and blender_nla_tracks is None):
                continue

            ##########################
            # bones
            blender_bones_ordered = []
            self.build_blender_bone_dependency_order(blender_bones,
                                                     blender_bones_ordered)
            for blender_bone_name in blender_bones_ordered:
                blender_bone_oject = blender_bones[blender_bone_name]
                ms3d_joint = Ms3dJoint()
                ms3d_joint.__index = len(ms3d_model._joints)

                blender_bone_ms3d = blender_bone_oject.ms3d
                blender_bone = blender_bone_oject

                ms3d_joint.flags = Ms3dUi.flags_to_ms3d(
                    blender_bone_ms3d.flags)
                if blender_bone_ms3d.comment:
                    ms3d_joint._comment_object = Ms3dCommentEx()
                    ms3d_joint._comment_object.comment = \
                            blender_bone_ms3d.comment
                    ms3d_joint._comment_object.index = ms3d_joint.__index

                ms3d_joint.joint_ex_object._color = blender_bone_ms3d.color[:]

                ms3d_joint.name = blender_bone.name

                if blender_bone.parent:
                    ms3d_joint.parent_name = blender_bone.parent.name
                    ms3d_joint.__matrix = matrix_difference(
                        matrix_transform * blender_bone.matrix_local,
                        matrix_transform * blender_bone.parent.matrix_local)
                else:
                    ms3d_joint.__matrix = base_bone_correction \
                            * matrix_transform * blender_bone.matrix_local

                mat = ms3d_joint.__matrix
                loc = mat.to_translation()
                rot = mat.to_euler('XZY')
                ms3d_joint._position = self.joint_correction(loc)
                ms3d_joint._rotation = self.joint_correction(rot)

                ms3d_model._joints.append(ms3d_joint)
                blender_to_ms3d_bones[blender_bone.name] = ms3d_joint

            ##########################
            # animation
            frames = None
            frames_location = set()
            frames_rotation = set()
            frames_scale = set()

            if blender_action:
                self.fill_keyframe_sets(blender_action.fcurves,
                                        frames_location, frames_rotation,
                                        frames_scale, 0)

            if blender_nla_tracks:
                for nla_track in blender_nla_tracks:
                    if nla_track.mute:
                        continue
                    for strip in nla_track.strips:
                        if strip.mute:
                            continue
                        frame_correction = strip.frame_start \
                                - strip.action_frame_start
                        self.fill_keyframe_sets(strip.action.fcurves,
                                                frames_location,
                                                frames_rotation, frames_scale,
                                                frame_correction)

            frames = set(frames_location)
            frames = frames.union(frames_rotation)
            frames = frames.union(frames_scale)

            if not self.options_shrink_to_keys:
                frames = frames.intersection(
                    range(blender_scene.frame_start,
                          blender_scene.frame_end + 1))

            frames_sorted = list(frames)
            frames_sorted.sort()

            if self.options_shrink_to_keys and len(frames_sorted) >= 2:
                frame_start = frames_sorted[0]
                frame_end = frames_sorted[len(frames_sorted) - 1]
                frame_total = (frame_end - frame_start) + 1
                frame_offset = frame_start - 1

            if self.options_bake_each_frame:
                frames_sorted = range(int(frame_start), int(frame_end + 1),
                                      int(frame_step))

            frame_temp = blender_scene.frame_current

            for current_frame in frames_sorted:
                blender_scene.frame_set(current_frame)

                current_time = (current_frame - frame_offset) * time_base
                for blender_bone_name in blender_bones_ordered:
                    blender_bone = blender_bones[blender_bone_name]
                    blender_pose_bone = blender_pose_bones[blender_bone_name]
                    ms3d_joint = blender_to_ms3d_bones[blender_bone_name]

                    m1 = blender_bone.matrix_local.inverted()
                    if blender_pose_bone.parent:
                        m2 = blender_pose_bone.parent.matrix_channel.inverted()
                    else:
                        m2 = 1
                    m3 = blender_pose_bone.matrix.copy()
                    m = ((m1 * m2) * m3)
                    loc = m.to_translation()
                    rot = m.to_euler('XZY')

                    ms3d_joint.translation_key_frames.append(
                        Ms3dTranslationKeyframe(current_time,
                                                self.joint_correction(loc)))
                    ms3d_joint.rotation_key_frames.append(
                        Ms3dRotationKeyframe(current_time,
                                             self.joint_correction(rot)))

            blender_scene.frame_set(frame_temp)

        ms3d_model.animation_fps = fps
        if ms3d_model.number_joints > 0:
            ms3d_model.number_total_frames = int(frame_total)
            ms3d_model.current_time = ((blender_scene.frame_current \
                    - blender_scene.frame_start) + 1) * time_base
        else:
            ms3d_model.number_total_frames = 1
            ms3d_model.current_time = 0
Пример #2
0
    def create_animation(self, blender_context, ms3d_model,
            blender_mesh_objects, blender_to_ms3d_bones):
        ##########################
        # setup scene
        blender_scene = blender_context.scene

        if not self.options_use_animation:
            ms3d_model.animation_fps = 24
            ms3d_model.number_total_frames = 1
            ms3d_model.current_time = 0
            return

        frame_start = blender_scene.frame_start
        frame_end = blender_scene.frame_end
        frame_total = (frame_end - frame_start) + 1
        frame_step = blender_scene.frame_step
        frame_offset = 0

        fps = blender_scene.render.fps * blender_scene.render.fps_base
        time_base = 1.0 / fps

        base_bone_correction = Matrix.Rotation(pi / 2, 4, 'Z')

        for blender_mesh_object in blender_mesh_objects:
            blender_bones = None
            blender_action = None
            blender_nla_tracks = None
            for blender_modifier in blender_mesh_object.modifiers:
                if blender_modifier.type == 'ARMATURE' \
                        and blender_modifier.object.pose:
                    blender_bones = blender_modifier.object.data.bones
                    blender_pose_bones = blender_modifier.object.pose.bones
                    if blender_modifier.object.animation_data:
                        blender_action = \
                                blender_modifier.object.animation_data.action
                        blender_nla_tracks = \
                                blender_modifier.object.animation_data.nla_tracks

                    # apply transform
                    if self.options_apply_transform:
                        matrix_transform = blender_modifier.object.matrix_basis
                    else:
                        matrix_transform = 1

                    break

            if blender_bones is None \
                    and (blender_action is None and blender_nla_tracks is None):
                continue

            ##########################
            # bones
            blender_bones_ordered = []
            self.build_blender_bone_dependency_order(
                    blender_bones, blender_bones_ordered)
            for blender_bone_name in blender_bones_ordered:
                blender_bone_oject = blender_bones[blender_bone_name]
                ms3d_joint = Ms3dJoint()
                ms3d_joint.__index = len(ms3d_model._joints)

                blender_bone_ms3d = blender_bone_oject.ms3d
                blender_bone = blender_bone_oject

                ms3d_joint.flags = Ms3dUi.flags_to_ms3d(blender_bone_ms3d.flags)
                if blender_bone_ms3d.comment:
                    ms3d_joint._comment_object = Ms3dCommentEx()
                    ms3d_joint._comment_object.comment = \
                            blender_bone_ms3d.comment
                    ms3d_joint._comment_object.index = ms3d_joint.__index

                ms3d_joint.joint_ex_object._color = blender_bone_ms3d.color[:]

                ms3d_joint.name = blender_bone.name

                if blender_bone.parent:
                    ms3d_joint.parent_name = blender_bone.parent.name
                    ms3d_joint.__matrix = matrix_difference(
                            matrix_transform * blender_bone.matrix_local,
                            matrix_transform * blender_bone.parent.matrix_local)
                else:
                    ms3d_joint.__matrix = base_bone_correction \
                            * matrix_transform * blender_bone.matrix_local

                mat = ms3d_joint.__matrix
                loc = mat.to_translation()
                rot = mat.to_euler('XZY')
                ms3d_joint._position = self.joint_correction(loc)
                ms3d_joint._rotation = self.joint_correction(rot)

                ms3d_model._joints.append(ms3d_joint)
                blender_to_ms3d_bones[blender_bone.name] = ms3d_joint

            ##########################
            # animation
            frames = None
            frames_location = set()
            frames_rotation = set()
            frames_scale = set()

            if blender_action:
                self.fill_keyframe_sets(
                        blender_action.fcurves,
                        frames_location, frames_rotation, frames_scale,
                        0)

            if blender_nla_tracks:
                for nla_track in blender_nla_tracks:
                    if nla_track.mute:
                        continue
                    for strip in nla_track.strips:
                        if strip.mute:
                            continue
                        frame_correction = strip.frame_start \
                                - strip.action_frame_start
                        self.fill_keyframe_sets(
                                strip.action.fcurves,
                                frames_location, frames_rotation, frames_scale,
                                frame_correction)

            frames = set(frames_location)
            frames = frames.union(frames_rotation)
            frames = frames.union(frames_scale)

            if not self.options_shrink_to_keys:
                frames = frames.intersection(range(
                        blender_scene.frame_start, blender_scene.frame_end + 1))

            frames_sorted = list(frames)
            frames_sorted.sort()

            if self.options_shrink_to_keys and len(frames_sorted) >= 2:
                frame_start = frames_sorted[0]
                frame_end = frames_sorted[len(frames_sorted)-1]
                frame_total = (frame_end - frame_start) + 1
                frame_offset = frame_start - 1

            if self.options_bake_each_frame:
                frames_sorted = range(int(frame_start), int(frame_end + 1),
                        int(frame_step))

            frame_temp = blender_scene.frame_current

            for current_frame in frames_sorted:
                blender_scene.frame_set(current_frame)

                current_time = (current_frame - frame_offset) * time_base
                for blender_bone_name in blender_bones_ordered:
                    blender_bone = blender_bones[blender_bone_name]
                    blender_pose_bone = blender_pose_bones[blender_bone_name]
                    ms3d_joint = blender_to_ms3d_bones[blender_bone_name]

                    m1 = blender_bone.matrix_local.inverted()
                    if blender_pose_bone.parent:
                        m2 = blender_pose_bone.parent.matrix_channel.inverted()
                    else:
                        m2 = 1
                    m3 = blender_pose_bone.matrix.copy()
                    m = ((m1 * m2) * m3)
                    loc = m.to_translation()
                    rot = m.to_euler('XZY')

                    ms3d_joint.translation_key_frames.append(
                            Ms3dTranslationKeyframe(
                                    current_time, self.joint_correction(loc)
                                    )
                            )
                    ms3d_joint.rotation_key_frames.append(
                            Ms3dRotationKeyframe(
                                    current_time, self.joint_correction(rot)
                                    )
                            )

            blender_scene.frame_set(frame_temp)

        ms3d_model.animation_fps = fps
        if ms3d_model.number_joints > 0:
            ms3d_model.number_total_frames = int(frame_total)
            ms3d_model.current_time = ((blender_scene.frame_current \
                    - blender_scene.frame_start) + 1) * time_base
        else:
            ms3d_model.number_total_frames = 1
            ms3d_model.current_time = 0