def set_bone_transforms(self, bone, node, parent):
        obj = bpy.data.objects[self.blender_armature_name]
        delta = Quaternion((0.7071068286895752, 0.7071068286895752, 0.0, 0.0))

        mat = Matrix()
        if not parent:
            transform = node.get_transforms()
            mat = transform * delta.to_matrix().to_4x4()
        else:
            if not self.gltf.scene.nodes[
                    parent].is_joint:  # TODO if Node in another scene
                transform = node.get_transforms()
                parent_mat = bpy.data.objects[
                    self.gltf.scene.nodes[parent].blender_object].matrix_world
                mat = transform * parent_mat.inverted()
            else:
                transform = node.get_transforms()
                parent_mat = obj.data.edit_bones[self.gltf.scene.nodes[
                    parent].blender_bone_name].matrix  # Node in another scene

                mat = (parent_mat.to_quaternion() * delta.inverted() *
                       transform.to_quaternion() * delta).to_matrix().to_4x4()
                mat = Matrix.Translation(parent_mat.to_translation() +
                                         (parent_mat.to_quaternion() *
                                          delta.inverted() *
                                          transform.to_translation())) * mat
                #TODO scaling of bones

        bone.matrix = mat
        return bone.matrix
Beispiel #2
0
class Eyes:

    def __init__(self, cross_eye=0.0, default_look_distance=200, eye_fov=40):
        self.default_look_target = Vector((0, default_look_distance, 0))
        self.look_target = self.default_look_target
        self.rotation = Quaternion((1, 0, 0, 0))
        self.position = Vector((0, 0, 0))
        self.leye_pos = Vector((-5.96898, 6.09201, 3.69949))
        self.reye_pos = Vector((5.96898, 6.09201, 3.69949))
        self.leye_norm = Vector((cross_eye, 1, 0))
        self.reye_norm = Vector((-cross_eye, 1, 0))
        self.pupil_pos = np.zeros(4)  # lx ly rx ry
        self.eye_fov = eye_fov

    def set_rotation(self, rotation):
        self.rotation = rotation

    def update(self):
        self.update_pupil_pos()
        new_look_target = self.update_look_target()

        if new_look_target:
            print("blonk")
            self.look_target = new_look_target
            self.update()
        else:
            print(self.pupil_pos)

    def update_pupil_pos(self):

        leye_pos = self.leye_pos.copy()
        leye_pos.rotate(self.rotation)
        leye_pos += self.position

        reye_pos = self.reye_pos.copy()
        reye_pos.rotate(self.rotation)
        reye_pos += self.position

        leye_beam = self.look_target.copy() - leye_pos
        reye_beam = self.look_target.copy() - reye_pos

        leye_beam.rotate(self.rotation.inverted())
        leye_beam_angle = self.leye_norm.rotation_difference(leye_beam)

        reye_beam.rotate(self.rotation.inverted())
        reye_beam_angle = self.reye_norm.rotation_difference(reye_beam)

        self.pupil_pos = -1*np.degrees([leye_beam_angle.z, leye_beam_angle.x, reye_beam_angle.z, reye_beam_angle.x])

    def update_look_target(self, forced=False):
        fov = np.full(4, self.eye_fov) / np.array([2, 4, 2, 4])

        if forced or np.any(self.pupil_pos < -1*fov) or np.any(self.pupil_pos > fov):
            new_look_target = self.default_look_target.copy()
            new_look_target.rotate(self.rotation)
            new_look_target += self.position
            return new_look_target
        else:
            return False
Beispiel #3
0
    def execute(self, context):
        scn = context.scene
        if 'localgrid_menu_items_strings' in scn and \
           'localgrid_menu_items_float' in scn:
            strings_dict = scn['localgrid_menu_items_strings']
            float_dict = scn['localgrid_menu_items_float']
            for i in range(len(strings_dict.keys())):
                strings = strings_dict[str(i)]
                icon, name = strings.split(',', 1)
                ls = float_dict[str(i)]
                orig = Vector([ls[0], ls[1], ls[2]])
                quat = Quaternion([ls[3], ls[4], ls[5], ls[6]])

                item = scn.local_grid.items.add()
                item.item_name = name
                item.icon = icon
                item.orig = orig
                item.quat = quat.inverted()
        if 'localgrid_menu_items_strings' in scn:
            del (scn['localgrid_menu_items_strings'])
        if 'localgrid_menu_items_float' in scn:
            del (scn['localgrid_menu_items_float'])
        if hasattr(scn, 'localgrid_menu_items_strings'):
            del (scn.localgrid_menu_items_strings)
        if hasattr(scn, 'localgrid_menu_items_float'):
            del (scn.localgrid_menu_items_float)
        return {'FINISHED'}
    def execute(self, context):
        scn = context.scene
        if 'localgrid_menu_items_strings' in scn and \
           'localgrid_menu_items_float' in scn:
            strings_dict = scn['localgrid_menu_items_strings']
            float_dict = scn['localgrid_menu_items_float']
            for i in range(len(strings_dict.keys())):
                strings = strings_dict[str(i)]
                icon, name = strings.split(',', 1)
                ls = float_dict[str(i)]
                orig = Vector([ls[0], ls[1], ls[2]])
                quat = Quaternion([ls[3], ls[4], ls[5], ls[6]])


                item = scn.local_grid.items.add()
                item.item_name = name
                item.icon = icon
                item.orig = orig
                item.quat = quat.inverted()
        if 'localgrid_menu_items_strings' in scn:
            del(scn['localgrid_menu_items_strings'])
        if 'localgrid_menu_items_float' in scn:
            del(scn['localgrid_menu_items_float'])
        if hasattr(scn, 'localgrid_menu_items_strings'):
            del(scn.localgrid_menu_items_strings)
        if hasattr(scn, 'localgrid_menu_items_float'):
            del(scn.localgrid_menu_items_float)
        return {'FINISHED'}
Beispiel #5
0
def write_track(xml, anm_data, fps):
    xml.tag_open_format(TRACK, bone=anm_data.name)
    xml.tag_open("keyframes")

    loc0, rot0_inv, first_frame = None, None, True

    for kfpts in anm_data:
        assert is_same_time(kfpts)

        loc = Vector(kfp.co.y for kfp in kfpts[0:3])
        rot = Quaternion(kfp.co.y for kfp in kfpts[3:7])
        loc, rot = calc_keyframe(anm_data.bone, loc, rot)

        if first_frame:
            loc0 = loc
            rot0_inv = rot.inverted()
            first_frame = False

        loc = loc - loc0
        rot = rot0_inv * rot

        write_keyframe(xml, kfpts[0].co.x / fps, loc, rot)

    xml.tag_close("keyframes")
    xml.tag_close("track")
 def set_transforms(gltf_node, obj, parent):
     obj.rotation_mode = 'QUATERNION'
     if hasattr(gltf_node, 'matrix'):
         obj.matrix_world = Conversion.matrix(gltf_node.matrix)
     elif gltf_node.is_joint:
         delta = Quaternion(
             (0.7071068286895752, 0.7071068286895752, 0.0, 0.0))
         obj.matrix_world = Conversion.get_node_matrix(
             gltf_node) * delta.inverted().to_matrix().to_4x4()
     else:
         obj.location = Conversion.location(gltf_node.translation)
         obj.rotation_quaternion = Conversion.quaternion(gltf_node.rotation)
         obj.scale = Conversion.scale(gltf_node.scale)
Beispiel #7
0
	def compute_pose(self, world_poses, local_rotations, joint_offsets, index):
		"""
		Compute a pose for an index. Returns the resulting mat4
		"""

		parent_quat = Quaternion([1, 0, 0, 0])
		parent_pose = Matrix()

		if index > 0:
			parent_quat = local_rotations[index - 1]
			parent_pose = world_poses[index - 1]

		local_pose = (parent_quat.inverted() * local_rotations[index]).to_matrix()
		local_pose.resize_4x4()
		return parent_pose * joint_offsets[index] * local_pose
    def set_transforms(self, obj, parent):
        if parent is None:
            obj.matrix_world = self.transform
            return

        for node in self.gltf.scene.nodes.values(
        ):  # TODO if parent is in another scene
            if node.index == parent:
                if node.is_joint == True:
                    delta = Quaternion(
                        (0.7071068286895752, 0.7071068286895752, 0.0, 0.0))
                    obj.matrix_world = self.transform * delta.inverted(
                    ).to_matrix().to_4x4()
                    return
                else:
                    obj.matrix_world = self.transform
                    return
Beispiel #9
0
def createTPose(context):
    rig = context.object
    scn = context.scene
    if rig.McpHasTPose:
        setTPose(context)
        return

    filepath = os.path.join(os.path.dirname(__file__), "t_pose.json")
    struct = loadJson(filepath)

    for name,value in struct:
        pb = rig.pose.bones[name]
        quat = Quaternion(value)
        pb.matrix_basis = quat.to_matrix().to_4x4()
        rest = quat.inverted()
        pb["McpRestW"] = rest.w
        pb["McpRestX"] = rest.x
        pb["McpRestY"] = rest.y
        pb["McpRestZ"] = rest.z

    children = []
    for ob in scn.objects:
        if ob.type != 'MESH':
            continue
        for mod in ob.modifiers:
            if (mod.type == 'ARMATURE' and
                mod.object == rig):
                children.append((ob, mod.name))
                scn.objects.active = ob
                bpy.ops.object.modifier_apply(apply_as='SHAPE', modifier=mod.name)
                ob.data.shape_keys.key_blocks[mod.name].value = 1

    scn.objects.active = rig
    bpy.ops.pose.armature_apply()
    for ob,name in children:
        scn.objects.active = ob
        mod = ob.modifiers.new(name, 'ARMATURE')
        mod.object = rig
        mod.use_vertex_groups = True
        bpy.ops.object.modifier_move_up(modifier=name)
        setShapeKey(ob, name, 1.0)

    scn.objects.active = rig
    rig.McpHasTPose = True
    print("Created T-pose")
def extract_current_pose():
    """
    Convert current object's pose to OpenCV's "rvec" and "tvec".
    """

    ob = bpy.context.object
    if ob.rotation_mode == "QUATERNION":
        q = ob.rotation_quaternion
    elif ob.rotation_mode == "AXIS_ANGLE":
        q = Quaternion(ob.rotation_axis_angle[1:4], ob.rotation_axis_angle[0])
    else:
        assert ob.rotation_mode in ("XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX")
        q = ob.rotation_euler.to_quaternion()

    # Rotate 180 deg around local X because a blender camera has Y and Z axes opposite to OpenCV's
    q *= Quaternion((1.0, 0.0, 0.0), radians(180.0))

    aa = q.to_axis_angle()
    rvec = [c * -aa[1] for c in aa[0]]
    tvec = list(q.inverted() * (-ob.location))

    return rvec, tvec
def extract_current_pose():
    """
    Convert current object's pose to OpenCV's "rvec" and "tvec".
    """
    
    ob = bpy.context.object
    if ob.rotation_mode == "QUATERNION":
        q = ob.rotation_quaternion
    elif ob.rotation_mode == "AXIS_ANGLE":
        q = Quaternion(ob.rotation_axis_angle[1:4], ob.rotation_axis_angle[0])
    else:
        assert ob.rotation_mode in ("XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX")
        q = ob.rotation_euler.to_quaternion()
    
    # Rotate 180 deg around local X because a blender camera has Y and Z axes opposite to OpenCV's
    q *= Quaternion((1.0, 0.0, 0.0), radians(180.0))
    
    aa = q.to_axis_angle()
    rvec = [c * -aa[1] for c in aa[0]]
    tvec = list(q.inverted() * (-ob.location))
    
    return rvec, tvec
    def anim(self):
        obj = bpy.data.objects[self.animation.gltf.skins[
            self.animation.node.skin_id].blender_armature_name]
        bone = obj.pose.bones[self.animation.node.blender_bone_name]
        fps = bpy.context.scene.render.fps
        delta = Quaternion((0.7071068286895752, 0.7071068286895752, 0.0, 0.0))

        for anim in self.animation.anims.keys():
            if not self.animation.gltf.animations[anim].blender_action:
                if self.animation.gltf.animations[anim].name:
                    name = self.animation.gltf.animations[anim].name
                else:
                    name = "Animation_" + str(
                        self.animation.gltf.animations[anim].index)
                action = bpy.data.actions.new(name)
                self.animation.gltf.animations[
                    anim].blender_action = action.name
            if not obj.animation_data:
                obj.animation_data_create()
            obj.animation_data.action = bpy.data.actions[
                self.animation.gltf.animations[anim].blender_action]

            for channel in self.animation.anims[anim]:
                if channel.path == "translation":
                    blender_path = "location"
                    for key in channel.data:
                        transform = Matrix.Translation(
                            self.animation.gltf.convert.location(list(key[1])))
                        if not self.animation.node.parent:
                            mat = transform * delta.to_matrix().to_4x4()
                        else:
                            if not self.animation.gltf.scene.nodes[
                                    self.animation.node.
                                    parent].is_joint:  # TODO if Node in another scene
                                parent_mat = bpy.data.objects[
                                    self.animation.gltf.scene.nodes[
                                        self.animation.node.parent].
                                    blender_object].matrix_world
                                mat = transform * parent_mat.inverted()
                            else:
                                parent_mat = self.animation.gltf.scene.nodes[
                                    self.animation.node.
                                    parent].blender_bone_matrix

                                mat = (parent_mat.to_quaternion() *
                                       delta.inverted() *
                                       transform.to_quaternion() *
                                       delta).to_matrix().to_4x4()
                                mat = Matrix.Translation(
                                    parent_mat.to_translation() +
                                    (parent_mat.to_quaternion() *
                                     delta.inverted() *
                                     transform.to_translation())) * mat
                                #TODO scaling of bones

                        bone.location = self.animation.node.blender_bone_matrix.to_translation(
                        ) - mat.to_translation()
                        bone.keyframe_insert(blender_path,
                                             frame=key[0] * fps,
                                             group='location')

                    # Setting interpolation
                    for fcurve in [
                            curve
                            for curve in obj.animation_data.action.fcurves
                            if curve.group.name == "rotation"
                    ]:
                        for kf in fcurve.keyframe_points:
                            self.animation.set_interpolation(
                                channel.interpolation, kf)

                elif channel.path == "rotation":
                    blender_path = "rotation_quaternion"
                    for key in channel.data:
                        transform = (self.animation.gltf.convert.quaternion(
                            key[1])).to_matrix().to_4x4()
                        if not self.animation.node.parent:
                            mat = transform * delta.to_matrix().to_4x4()
                        else:
                            if not self.animation.gltf.scene.nodes[
                                    self.animation.node.
                                    parent].is_joint:  # TODO if Node in another scene
                                parent_mat = bpy.data.objects[
                                    self.animation.gltf.scene.nodes[
                                        self.animation.node.parent].
                                    blender_object].matrix_world
                                mat = transform * parent_mat.inverted()
                            else:
                                parent_mat = self.animation.gltf.scene.nodes[
                                    self.animation.node.
                                    parent].blender_bone_matrix

                                mat = (parent_mat.to_quaternion() *
                                       delta.inverted() *
                                       transform.to_quaternion() *
                                       delta).to_matrix().to_4x4()
                                mat = Matrix.Translation(
                                    parent_mat.to_translation() +
                                    (parent_mat.to_quaternion() *
                                     delta.inverted() *
                                     transform.to_translation())) * mat
                                #TODO scaling of bones

                        bone.rotation_quaternion = self.animation.node.blender_bone_matrix.to_quaternion(
                        ).inverted() * mat.to_quaternion()
                        bone.keyframe_insert(blender_path,
                                             frame=key[0] * fps,
                                             group='rotation')

                    # Setting interpolation
                    for fcurve in [
                            curve
                            for curve in obj.animation_data.action.fcurves
                            if curve.group.name == "rotation"
                    ]:
                        for kf in fcurve.keyframe_points:
                            self.animation.set_interpolation(
                                channel.interpolation, kf)

                elif channel.path == "scale":
                    blender_path = "scale"
                    for key in channel.data:
                        s = self.animation.gltf.convert.scale(list(key[1]))
                        transform = Matrix([[s[0], 0, 0, 0], [0, s[1], 0, 0],
                                            [0, 0, s[2], 0], [0, 0, 0, 1]])

                        if not self.animation.node.parent:
                            mat = transform * delta.to_matrix().to_4x4()
                        else:
                            if not self.animation.gltf.scene.nodes[
                                    self.animation.node.
                                    parent].is_joint:  # TODO if Node in another scene
                                parent_mat = bpy.data.objects[
                                    self.animation.gltf.scene.nodes[
                                        self.animation.node.parent].
                                    blender_object].matrix_world
                                mat = transform * parent_mat.inverted()
                            else:
                                parent_mat = self.animation.gltf.scene.nodes[
                                    self.animation.node.
                                    parent].blender_bone_matrix

                                mat = (parent_mat.to_quaternion() *
                                       delta.inverted() *
                                       transform.to_quaternion() *
                                       delta).to_matrix().to_4x4()
                                mat = Matrix.Translation(
                                    parent_mat.to_translation() +
                                    (parent_mat.to_quaternion() *
                                     delta.inverted() *
                                     transform.to_translation())) * mat
                                #TODO scaling of bones

                        #bone.scale # TODO
                        bone.keyframe_insert(blender_path,
                                             frame=key[0] * fps,
                                             group='scale')

                    # Setting interpolation
                    for fcurve in [
                            curve
                            for curve in obj.animation_data.action.fcurves
                            if curve.group.name == "rotation"
                    ]:
                        for kf in fcurve.keyframe_points:
                            self.animation.set_interpolation(
                                channel.interpolation, kf)
    def execute(self, context):
        if self.type == 'ACTIVE':
            actob = context.active_object
            if actob:
                rotation = actob.matrix_world.to_quaternion()
            else:
                return {'FINISHED'}
        elif self.type == 'GRID':
            v3d = context.space_data
            if v3d.use_local_grid:
                rotation = v3d.local_grid_rotation
            else:
                rotation = Quaternion((1, 0, 0, 0))
        else:
            rotation = self.rotation

        # world_rot = parent_mat * parent_inv * delta_rot * rot
        override = context.copy()
        for ob in vaob.sorted_objects(context.selected_objects):
            if self.type == 'ACTIVE' and ob == context.active_object:
                continue

            # オペレータのソース部分を見ないと判らないってのはどうなのよ
            override['selected_objects'] = [ob]
            override['selected_editable_objects'] = [ob]

            if ob.parent:
                parent_mat = ob.parent.matrix_world.to_3x3()
                parent_inv = ob.matrix_parent_inverse.to_3x3()
                mat = parent_mat * parent_inv
                target_quat = mat.inverted().to_quaternion() * rotation
            else:
                target_quat = rotation

            if ob.rotation_mode == 'AXIS_ANGLE':

                def rotate(quat):
                    angle, *axis = ob.rotation_axis_angle
                    local_quat = Quaternion(axis, angle)
                    q = quat * local_quat
                    axis, angle = q.to_axis_angle()
                    ob.rotation_axis_angle = [angle] + list(axis)

                rotate(target_quat.inverted())
                context.scene.update()

                bpy.ops.object.transform_apply(override, rotation=True)

                rotate(target_quat)

            elif ob.rotation_mode == 'QUATERNION':
                # transform_apply()は
                # delta_rotation_quaternion * rotation_quaternion の回転状態で
                # 計算される。その後rotation_quaternionはクリアされるが
                # delta_rotation_quaternionの数値はそのまま残る
                if self.use_delta:
                    delta = ob.delta_rotation_quaternion
                    # normalize()必要?
                else:
                    delta = Quaternion([1, 0, 0, 0])
                rot = ob.rotation_quaternion

                # target_quatの逆回転を行いtransform_apply()、
                # そしてtarget_quat分回転する
                # target.inverted() * delta * rot = delta * quat
                # quat = delta.inverted() * target.inverted() * delta * rot

                quat = delta.inverted() * target_quat.inverted() * delta * rot
                ob.rotation_quaternion = quat

                # ob.update_tag({'OBJECT', 'DATA'})
                context.scene.update()

                bpy.ops.object.transform_apply(override, rotation=True)

                ob.rotation_quaternion = target_quat * ob.rotation_quaternion
                # ob.update_tag({'OBJECT', 'DATA'})

            else:
                if self.use_delta:
                    delta = ob.delta_rotation_euler.to_quaternion()
                else:
                    delta = Quaternion([1, 0, 0, 0])
                rot = ob.rotation_euler.to_quaternion()

                quat = delta.inverted() * target_quat.inverted() * delta * rot
                ob.rotation_euler = quat.to_euler(ob.rotation_mode)
                context.scene.update()

                bpy.ops.object.transform_apply(override, rotation=True)

                ob.rotation_euler = target_quat.to_euler(ob.rotation_mode)

            context.scene.update()

        return {'FINISHED'}
Beispiel #14
0
    def blender_bone_create_anim(self):
        obj = bpy.data.objects[self.gltf.skins[
            self.skin_id].blender_armature_name]
        bone = obj.pose.bones[self.blender_bone_name]
        fps = bpy.context.scene.render.fps
        delta = Quaternion((0.7071068286895752, 0.7071068286895752, 0.0, 0.0))

        first_anim = True
        for anim in self.anims:

            if anim.path == "translation":
                blender_path = "location"
                for key in anim.data:
                    transform = Matrix.Translation(
                        self.convert_location(list(key[1])))
                    if not self.parent:
                        mat = transform
                    else:
                        if not self.gltf.scene.nodes[self.parent].is_joint:
                            parent_mat = self.gltf.scene.nodes[
                                self.parent].get_transforms()
                        else:
                            parent_mat = obj.pose.bones[
                                self.gltf.scene.nodes[self.parent].
                                blender_bone_name].matrix  # Node in another scene

                        mat = (parent_mat.to_quaternion() * delta.inverted() *
                               transform.to_quaternion() *
                               delta).to_matrix().to_4x4()
                        mat = Matrix.Translation(
                            parent_mat.to_translation() +
                            (parent_mat.to_quaternion() * delta.inverted() *
                             transform.to_translation())) * mat

                    mat = obj.convert_space(bone, mat, 'WORLD', 'LOCAL')
                    bone.location = mat.to_translation()
                    bone.keyframe_insert(blender_path,
                                         frame=key[0] * fps,
                                         group='location')

                # Setting interpolation
                for fcurve in [
                        curve for curve in obj.animation_data.action.fcurves
                        if curve.group.name == "rotation"
                ]:
                    for kf in fcurve.keyframe_points:
                        self.set_interpolation(anim.interpolation, kf)

            elif anim.path == "rotation":
                blender_path = "rotation_quaternion"
                for key in anim.data:
                    transform = (self.convert_quaternion(
                        key[1])).to_matrix().to_4x4()
                    if not self.parent:
                        mat = transform
                    else:
                        if not self.gltf.scene.nodes[self.parent].is_joint:
                            parent_mat = self.gltf.scene.nodes[
                                self.parent].get_transforms()
                        else:
                            parent_mat = obj.pose.bones[
                                self.gltf.scene.nodes[self.parent].
                                blender_bone_name].matrix  # Node in another scene

                        mat = (parent_mat.to_quaternion() * delta.inverted() *
                               transform.to_quaternion() *
                               delta).to_matrix().to_4x4()
                        mat = Matrix.Translation(
                            parent_mat.to_translation() +
                            (parent_mat.to_quaternion() * delta.inverted() *
                             transform.to_translation())) * mat

                    mat = obj.convert_space(bone, mat, 'WORLD', 'LOCAL')
                    bone.rotation_quaternion = mat.to_quaternion()
                    bone.keyframe_insert(blender_path,
                                         frame=key[0] * fps,
                                         group='rotation')

                # Setting interpolation
                for fcurve in [
                        curve for curve in obj.animation_data.action.fcurves
                        if curve.group.name == "rotation"
                ]:
                    for kf in fcurve.keyframe_points:
                        self.set_interpolation(anim.interpolation, kf)

            elif anim.path == "scale":
                blender_path = "scale"
                for key in anim.data:
                    s = self.convert_scale(list(key[1]))
                    transform = Matrix([[s[0], 0, 0, 0], [0, s[1], 0, 0],
                                        [0, 0, s[2], 0], [0, 0, 0, 1]])

                    if not self.parent:
                        mat = transform
                    else:
                        if not self.gltf.scene.nodes[self.parent].is_joint:
                            parent_mat = self.gltf.scene.nodes[
                                self.parent].get_transforms()
                        else:
                            parent_mat = obj.pose.bones[
                                self.gltf.scene.nodes[self.parent].
                                blender_bone_name].matrix  # Node in another scene

                        mat = (parent_mat.to_quaternion() * delta.inverted() *
                               transform.to_quaternion() *
                               delta).to_matrix().to_4x4()
                        mat = Matrix.Translation(
                            parent_mat.to_translation() +
                            (parent_mat.to_quaternion() * delta.inverted() *
                             transform.to_translation())) * mat

                    mat = obj.convert_space(bone, mat, 'WORLD', 'LOCAL')
                    bone.scale = mat.to_scale()
                    bone.keyframe_insert(blender_path,
                                         frame=key[0] * fps,
                                         group='scale')

                # Setting interpolation
                for fcurve in [
                        curve for curve in obj.animation_data.action.fcurves
                        if curve.group.name == "rotation"
                ]:
                    for kf in fcurve.keyframe_points:
                        self.set_interpolation(anim.interpolation, kf)

            if first_anim == True:
                first_anim = False
                if anim.anim.name and obj.animation_data and obj.animation_data.action:
                    obj.animation_data.action.name = anim.anim.name
    def get_vector(loop_act, loop_prev, f_normal_act=None, f_normal_prev=None, rotaxis=None, threshold=1.0e-4):
        vec_edge_act = loop_act.link_loop_next.vert.co - loop_act.vert.co
        vec_edge_act.normalize()

        vec_edge_prev = loop_prev.vert.co - loop_prev.link_loop_next.vert.co
        vec_edge_prev.normalize()

        f_cross = None
        rotated = False
        if f_normal_act and f_normal_prev:
            f_normal_act = f_normal_act.normalized()
            f_normal_prev = f_normal_prev.normalized()

            f_angle = f_normal_act.angle(f_normal_prev)
            if threshold < f_angle < ANGLE_180 - threshold:
                vec_normal = f_normal_act + f_normal_prev
                vec_normal.normalize()
                f_cross = f_normal_act.cross(f_normal_prev)
                f_cross.normalize()
            elif f_angle > ANGLE_180 - threshold and rotaxis:
                # vec_edge and f_normal are slightly rotated
                # in order to manage folding faces.
                vec_edge_act_orig = vec_edge_act.copy()
                vec_edge_prev_orig = vec_edge_prev.copy()

                rot_act = Quaternion(rotaxis, 2 * threshold)
                rot_prev = rot_act.inverted()
                vec_edge_act.rotate(rot_act)
                vec_edge_prev.rotate(rot_prev)
                f_normal_act.rotate(rot_act)
                f_normal_prev.rotate(rot_prev)

                vec_normal = f_normal_act + f_normal_prev
                vec_normal.normalize()
                rotated = True
            else:
                vec_normal = f_normal_act
        elif f_normal_act or f_normal_prev:
            vec_normal = (f_normal_act or f_normal_prev).normalized()
        else:
            vec_normal = loop_act.face.normal.copy()
            if vec_normal.length == 0.0:
                if threshold < vec_edge_act.angle(Z_UP) < ANGLE_180 - threshold:
                    vec_normal = Z_UP - Z_UP.project(vec_edge_act)
                    vec_normal.normalize()
                else:
                    # vec_edge is parallel to Z_UP
                    vec_normal = Vector((0.0, 1.0, 0.0))

        # 2d edge vectors are perpendicular to vec_normal
        vec_edge_act2d = vec_edge_act - vec_edge_act.project(vec_normal)
        vec_edge_act2d.normalize()

        vec_edge_prev2d = vec_edge_prev - vec_edge_prev.project(vec_normal)
        vec_edge_prev2d.normalize()

        angle2d = vec_edge_act2d.angle(vec_edge_prev2d)
        if angle2d < threshold:
            # folding corner
            corner_type = "FOLD"
            vec_tangent = vec_edge_act2d
            vec_angle2d = ANGLE_360
        elif angle2d > ANGLE_180 - threshold:
            # straight corner
            corner_type = "STRAIGHT"
            vec_tangent = vec_edge_act2d.cross(vec_normal)
            vec_angle2d = ANGLE_180
        else:
            direction = vec_edge_act2d.cross(vec_edge_prev2d).dot(vec_normal)
            if direction > 0.0:
                # convex corner
                corner_type = "CONVEX"
                vec_tangent = -(vec_edge_act2d + vec_edge_prev2d)
                vec_angle2d = angle2d
            else:
                # concave corner
                corner_type = "CONCAVE"
                vec_tangent = vec_edge_act2d + vec_edge_prev2d
                vec_angle2d = ANGLE_360 - angle2d

        if vec_tangent.dot(vec_normal):
            # Make vec_tangent perpendicular to vec_normal
            vec_tangent -= vec_tangent.project(vec_normal)

        vec_tangent.normalize()

        if f_cross:
            if vec_tangent.dot(f_cross) < 0.0:
                f_cross *= -1

            angle_a = f_cross.angle(vec_edge_act2d)
            angle_p = f_cross.angle(vec_edge_prev2d)
            angle_sum = vec_angle2d + angle_a + angle_p
            if angle_a < threshold or angle_p < threshold or angle_sum > ANGLE_360 + threshold:
                # For the case in which vec_tangent is not
                # between vec_edge_act2d and vec_edge_prev2d.
                # Probably using 3d edge vectors is
                # more intuitive than 2d edge vectors.
                if corner_type == "CONVEX":
                    vec_tangent = -(vec_edge_act + vec_edge_prev)
                else:
                    # CONCAVE
                    vec_tangent = vec_edge_act + vec_edge_prev
                vec_tangent.normalize()
            else:
                vec_tangent = f_cross

        if rotated:
            vec_edge_act = vec_edge_act_orig
            vec_edge_prev = vec_edge_prev_orig

        if corner_type == "FOLD":
            factor_act = factor_prev = 0
        else:
            factor_act = 1.0 / sin(vec_tangent.angle(vec_edge_act))
            factor_prev = 1.0 / sin(vec_tangent.angle(vec_edge_prev))

        return vec_tangent, factor_act, factor_prev
    def get_vector(loop_act,
                   loop_prev,
                   f_normal_act=None,
                   f_normal_prev=None,
                   rotaxis=None,
                   threshold=1.0e-4):
        vec_edge_act = loop_act.link_loop_next.vert.co - loop_act.vert.co
        vec_edge_act.normalize()

        vec_edge_prev = loop_prev.vert.co - loop_prev.link_loop_next.vert.co
        vec_edge_prev.normalize()

        f_cross = None
        rotated = False
        if f_normal_act and f_normal_prev:
            f_normal_act = f_normal_act.normalized()
            f_normal_prev = f_normal_prev.normalized()

            f_angle = f_normal_act.angle(f_normal_prev)
            if threshold < f_angle < ANGLE_180 - threshold:
                vec_normal = f_normal_act + f_normal_prev
                vec_normal.normalize()
                f_cross = f_normal_act.cross(f_normal_prev)
                f_cross.normalize()
            elif f_angle > ANGLE_180 - threshold and rotaxis:
                # vec_edge and f_normal are slightly rotated
                # in order to manage folding faces.
                vec_edge_act_orig = vec_edge_act.copy()
                vec_edge_prev_orig = vec_edge_prev.copy()

                rot_act = Quaternion(rotaxis, 2 * threshold)
                rot_prev = rot_act.inverted()
                vec_edge_act.rotate(rot_act)
                vec_edge_prev.rotate(rot_prev)
                f_normal_act.rotate(rot_act)
                f_normal_prev.rotate(rot_prev)

                vec_normal = f_normal_act + f_normal_prev
                vec_normal.normalize()
                rotated = True
            else:
                vec_normal = f_normal_act
        elif f_normal_act or f_normal_prev:
            vec_normal = (f_normal_act or f_normal_prev).normalized()
        else:
            vec_normal = loop_act.face.normal.copy()
            if vec_normal.length == .0:
                if threshold < vec_edge_act.angle(
                        Z_UP) < ANGLE_180 - threshold:
                    vec_normal = Z_UP - Z_UP.project(vec_edge_act)
                    vec_normal.normalize()
                else:
                    # vec_edge is parallel to Z_UP
                    vec_normal = Vector((.0, 1.0, .0))

        # 2d edge vectors are perpendicular to vec_normal
        vec_edge_act2d = vec_edge_act - vec_edge_act.project(vec_normal)
        vec_edge_act2d.normalize()

        vec_edge_prev2d = vec_edge_prev - vec_edge_prev.project(vec_normal)
        vec_edge_prev2d.normalize()

        angle2d = vec_edge_act2d.angle(vec_edge_prev2d)
        if angle2d < threshold:
            # folding corner
            corner_type = 'FOLD'
            vec_tangent = vec_edge_act2d
            vec_angle2d = ANGLE_360
        elif angle2d > ANGLE_180 - threshold:
            # straight corner
            corner_type = 'STRAIGHT'
            vec_tangent = vec_edge_act2d.cross(vec_normal)
            vec_angle2d = ANGLE_180
        else:
            direction = vec_edge_act2d.cross(vec_edge_prev2d).dot(vec_normal)
            if direction > .0:
                # convex corner
                corner_type = 'CONVEX'
                vec_tangent = -(vec_edge_act2d + vec_edge_prev2d)
                vec_angle2d = angle2d
            else:
                # concave corner
                corner_type = 'CONCAVE'
                vec_tangent = vec_edge_act2d + vec_edge_prev2d
                vec_angle2d = ANGLE_360 - angle2d

        if vec_tangent.dot(vec_normal):
            # Make vec_tangent perpendicular to vec_normal
            vec_tangent -= vec_tangent.project(vec_normal)

        vec_tangent.normalize()

        if f_cross:
            if vec_tangent.dot(f_cross) < .0:
                f_cross *= -1

            angle_a = f_cross.angle(vec_edge_act2d)
            angle_p = f_cross.angle(vec_edge_prev2d)
            angle_sum = vec_angle2d + angle_a + angle_p
            if (angle_a < threshold or angle_p < threshold
                    or angle_sum > ANGLE_360 + threshold):
                # For the case in which vec_tangent is not
                # between vec_edge_act2d and vec_edge_prev2d.
                # Probably using 3d edge vectors is
                # more intuitive than 2d edge vectors.
                if corner_type == 'CONVEX':
                    vec_tangent = -(vec_edge_act + vec_edge_prev)
                else:
                    # CONCAVE
                    vec_tangent = vec_edge_act + vec_edge_prev
                vec_tangent.normalize()
            else:
                vec_tangent = f_cross

        if rotated:
            vec_edge_act = vec_edge_act_orig
            vec_edge_prev = vec_edge_prev_orig

        if corner_type == 'FOLD':
            factor_act = factor_prev = 0
        else:
            factor_act = 1. / sin(vec_tangent.angle(vec_edge_act))
            factor_prev = 1. / sin(vec_tangent.angle(vec_edge_prev))

        return vec_tangent, factor_act, factor_prev
Beispiel #17
0
def invertQuats(rig):
    for pb in rig.pose.bones:
        quat = Quaternion((pb.McpQuatW, pb.McpQuatX, pb.McpQuatY, pb.McpQuatZ))
        pb.McpQuatW, pb.McpQuatX, pb.McpQuatY, pb.McpQuatZ = quat.inverted()
Beispiel #18
0
def invertQuats(rig):
    for pb in rig.pose.bones:
        quat = Quaternion((pb.McpQuatW, pb.McpQuatX, pb.McpQuatY, pb.McpQuatZ))
        pb.McpQuatW, pb.McpQuatX, pb.McpQuatY, pb.McpQuatZ = quat.inverted()
    def execute(self, context):
        if self.type == "ACTIVE":
            actob = context.active_object
            if actob:
                rotation = actob.matrix_world.to_quaternion()
            else:
                return {"FINISHED"}
        elif self.type == "GRID":
            v3d = context.space_data
            if v3d.use_local_grid:
                rotation = v3d.local_grid_rotation
            else:
                rotation = Quaternion((1, 0, 0, 0))
        else:
            rotation = self.rotation

        # world_rot = parent_mat * parent_inv * delta_rot * rot
        override = context.copy()
        for ob in vaob.sorted_objects(context.selected_objects):
            if self.type == "ACTIVE" and ob == context.active_object:
                continue

            # オペレータのソース部分を見ないと判らないってのはどうなのよ
            override["selected_objects"] = [ob]
            override["selected_editable_objects"] = [ob]

            if ob.parent:
                parent_mat = ob.parent.matrix_world.to_3x3()
                parent_inv = ob.matrix_parent_inverse.to_3x3()
                mat = parent_mat * parent_inv
                target_quat = mat.inverted().to_quaternion() * rotation
            else:
                target_quat = rotation

            if ob.rotation_mode == "AXIS_ANGLE":

                def rotate(quat):
                    angle, *axis = ob.rotation_axis_angle
                    local_quat = Quaternion(axis, angle)
                    q = quat * local_quat
                    axis, angle = q.to_axis_angle()
                    ob.rotation_axis_angle = [angle] + list(axis)

                rotate(target_quat.inverted())
                context.scene.update()

                bpy.ops.object.transform_apply(override, rotation=True)

                rotate(target_quat)

            elif ob.rotation_mode == "QUATERNION":
                # transform_apply()は
                # delta_rotation_quaternion * rotation_quaternion の回転状態で
                # 計算される。その後rotation_quaternionはクリアされるが
                # delta_rotation_quaternionの数値はそのまま残る
                if self.use_delta:
                    delta = ob.delta_rotation_quaternion
                    # normalize()必要?
                else:
                    delta = Quaternion([1, 0, 0, 0])
                rot = ob.rotation_quaternion

                # target_quatの逆回転を行いtransform_apply()、
                # そしてtarget_quat分回転する
                # target.inverted() * delta * rot = delta * quat
                # quat = delta.inverted() * target.inverted() * delta * rot

                quat = delta.inverted() * target_quat.inverted() * delta * rot
                ob.rotation_quaternion = quat

                # ob.update_tag({'OBJECT', 'DATA'})
                context.scene.update()

                bpy.ops.object.transform_apply(override, rotation=True)

                ob.rotation_quaternion = target_quat * ob.rotation_quaternion
                # ob.update_tag({'OBJECT', 'DATA'})

            else:
                if self.use_delta:
                    delta = ob.delta_rotation_euler.to_quaternion()
                else:
                    delta = Quaternion([1, 0, 0, 0])
                rot = ob.rotation_euler.to_quaternion()

                quat = delta.inverted() * target_quat.inverted() * delta * rot
                ob.rotation_euler = quat.to_euler(ob.rotation_mode)
                context.scene.update()

                bpy.ops.object.transform_apply(override, rotation=True)

                ob.rotation_euler = target_quat.to_euler(ob.rotation_mode)

            context.scene.update()

        return {"FINISHED"}