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
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