Esempio n. 1
0
    def test_loc_rot_scale(self):
        euler = Euler((math.radians(90), 0, math.radians(90)), 'ZYX')
        expected = Matrix(
            ((0, -5, 0, 1), (0, 0, -6, 2), (4, 0, 0, 3), (0, 0, 0, 1)))

        result = Matrix.LocRotScale((1, 2, 3), euler, (4, 5, 6))
        self.assertAlmostEqualMatrix(result, expected, 4)

        result = Matrix.LocRotScale((1, 2, 3), euler.to_quaternion(),
                                    (4, 5, 6))
        self.assertAlmostEqualMatrix(result, expected, 4)

        result = Matrix.LocRotScale((1, 2, 3), euler.to_matrix(), (4, 5, 6))
        self.assertAlmostEqualMatrix(result, expected, 4)
Esempio n. 2
0
    def draw(self, context):
        selected_archetype = get_selected_archetype(context)
        selected_portal = get_selected_portal(context)
        portal = self.linked_portal
        asset = selected_archetype.asset

        self.color = 0, 0.6, 1

        if selected_portal != portal:
            self.alpha = 0

        if selected_portal == portal:
            self.alpha = 0.3

            if portal and asset:
                corners = [
                    portal.corner1, portal.corner2, portal.corner3,
                    portal.corner4
                ]
                x = [p[0] for p in corners]
                y = [p[1] for p in corners]
                z = [p[2] for p in corners]
                centroid = Vector(
                    (sum(x) / len(corners), sum(y) / len(corners),
                     sum(z) / len(corners)))
                normal = -(corners[2] - corners[0]
                           ).cross(corners[1] - corners[0]).normalized()
                default_axis = Vector((0, 0, 1))
                rot = default_axis.rotation_difference(normal)
                arrow_mat = Matrix.LocRotScale(centroid, rot,
                                               Vector((0.3, 0.3, 0.3)))
                self.draw_preset_arrow(matrix=asset.matrix_world @ arrow_mat)
Esempio n. 3
0
def gem_transform(dup: DepsgraphObjectInstance) -> LocRadMat:
    loc, rot, sca = dup.matrix_world.decompose()

    if dup.is_instance:
        bbox = dup.instance_object.original.bound_box
        x, y, z = bbox[0]
        dim = Vector((
            bbox[4][0] - x,
            bbox[3][1] - y,
            bbox[1][2] - z,
        ))
        rad = max(dim.xy * sca.xy) / 2
    else:
        dim = dup.object.original.dimensions
        rad = max(dim.xy) / 2

    mat = Matrix.LocRotScale(loc, rot, (1.0, 1.0, 1.0))
    loc.freeze()
    mat.freeze()

    return loc, rad, mat
Esempio n. 4
0
def obj_to_bone(obj, rig, bone_name, bone_transform_name=None):
    """ Places an object at the location/rotation/scale of the given bone.
    """
    if bpy.context.mode == 'EDIT_ARMATURE':
        raise MetarigError("obj_to_bone(): does not work while in edit mode")

    bone = rig.pose.bones[bone_name]

    loc = bone.custom_shape_translation
    rot = bone.custom_shape_rotation_euler
    scale = Vector(bone.custom_shape_scale_xyz)

    if bone.use_custom_shape_bone_size:
        scale *= bone.length

    if bone_transform_name is not None:
        bone = rig.pose.bones[bone_transform_name]
    elif bone.custom_shape_transform:
        bone = bone.custom_shape_transform

    shape_mat = Matrix.LocRotScale(loc, Euler(rot), scale)

    obj.rotation_mode = 'XYZ'
    obj.matrix_basis = rig.matrix_world @ bone.bone.matrix_local @ shape_mat
Esempio n. 5
0
def _draw(self, context):
    if not context.space_data.overlay.show_overlays:
        return

    props = context.scene.jewelcraft
    show_all = props.overlay_show_all
    use_ovrd = props.overlay_use_overrides
    default_spacing = props.overlay_spacing

    is_gem = False
    is_df = context.mode == "EDIT_MESH" and context.edit_object.is_instancer

    if is_df:
        df = context.edit_object
        for ob1 in df.children:
            if "gem" in ob1:
                is_gem = True
                break
    else:
        ob1 = context.object
        if ob1:
            is_gem = "gem" in ob1 and ob1.select_get()

    if not (show_all or is_gem):
        return

    global _font_loc

    prefs = context.preferences.addons[var.ADDON_ID].preferences
    default_color = prefs.overlay_color
    default_linewidth = prefs.overlay_linewidth

    diplay_thold = default_spacing + 0.5
    gems_count = 0
    depsgraph = context.evaluated_depsgraph_get()

    # Gem 1 transform
    # -----------------------------------

    if is_gem:

        if use_ovrd and "gem_overlay" in ob1:
            spacing1 = ob1["gem_overlay"].get("spacing", default_spacing)
        else:
            spacing1 = default_spacing

        from_scene_scale = unit.Scale().from_scene

        if is_df:
            df_pass = False
            loc1, _rot = _get_df_transform(df, context, depsgraph)
        else:
            loc1 = ob1.matrix_world.to_translation()
            _rot = ob1.matrix_world.to_quaternion()

        rad1 = max(ob1.dimensions.xy) / 2
        mat1 = Matrix.LocRotScale(loc1, _rot, (1.0, 1.0, 1.0))
        mat1.freeze()

    # Shader
    # -----------------------------------

    gpu.state.blend_set("ALPHA")
    gpu.state.depth_mask_set(True)
    if not props.overlay_show_in_front:
        gpu.state.depth_test_set("LESS_EQUAL")

    shader = gpu.shader.from_builtin("3D_POLYLINE_UNIFORM_COLOR")
    shader.bind()
    shader.uniform_float("viewportSize",
                         (context.area.width, context.area.height))

    # Main loop
    # -----------------------------------

    for dup, ob2, _ in iter_gems(depsgraph):
        gems_count += 1
        loc2, rad2, mat2 = gem_transform(dup)

        # Filter out by distance
        # -----------------------------------

        use_diplay_dis = False

        if is_gem:
            dis_obs = (loc1 - loc2).length
            proximity_dis = from_scene_scale(dis_obs - (rad1 + rad2))
            proximity_thold = proximity_dis < diplay_thold

            if not (show_all or proximity_thold):
                continue

            is_act = False

            if is_df:
                if not df_pass:
                    df_pass = is_act = dup.matrix_world.translation == loc1
            else:
                if not dup.is_instance:
                    is_act = ob2 is ob1

            use_diplay_dis = not is_act and proximity_thold

        # Gem 2 shader and spacing overrride
        # -----------------------------------

        if show_all or use_diplay_dis:

            if use_ovrd and "gem_overlay" in ob2:
                _color = ob2["gem_overlay"].get("color", default_color)
                _linewidth = ob2["gem_overlay"].get("linewidth",
                                                    default_linewidth)
                spacing2 = ob2["gem_overlay"].get("spacing", default_spacing)
            else:
                _color = default_color
                _linewidth = default_linewidth
                spacing2 = default_spacing

            shader.uniform_float("color", _color)
            shader.uniform_float("lineWidth", _linewidth)

        # Show distance
        # -----------------------------------

        spacing_thold = False

        if use_diplay_dis:

            if dis_obs:
                co1, co2 = nearest_coords(rad1, rad2, mat1, mat2)
                dis_gap = from_scene_scale(
                    calc_gap(co1, co2, loc1, dis_obs, rad1))
                gap_thold = dis_gap < diplay_thold

                if not (show_all or gap_thold):
                    continue

                spacing_thold = dis_gap < (spacing2 + 0.3)
                mid = co1.lerp(co2, 0.5)
            else:
                co1 = co2 = mid = loc2
                dis_gap = proximity_dis
                gap_thold = spacing_thold = True

            if gap_thold:

                if dis_gap < 0.1:
                    shader.uniform_float("color", (1.0, 0.0, 0.0, 1.0))
                elif dis_gap < spacing2:
                    shader.uniform_float("color", (1.0, 0.9, 0.0, 1.0))

                _font_loc.append(
                    (dis_gap, mid, from_scene_scale(max(spacing1, spacing2))))

                batch = batch_for_shader(shader, "LINES", {"pos": (co1, co2)})
                batch.draw(shader)

        # Show spacing
        # -----------------------------------

        if show_all or spacing_thold:
            batch = batch_for_shader(
                shader, "LINE_LOOP",
                {"pos": _circle_cos(rad2 + spacing2, mat2)})
            batch.draw(shader)

    _CC.set(show_all, gems_count)

    gpu.state.blend_set("NONE")
    gpu.state.depth_test_set("NONE")
    gpu.state.depth_mask_set(False)