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