diff options
7 files changed, 84 insertions, 16 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index a7164e5bf2c..4ce1a903269 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -264,6 +264,12 @@ static void updateDepsgraph(GpencilModifierData *md, else { add_this_collection(ctx->scene->master_collection, ctx, mode); } + if (lmd->calculation_flags & LRT_USE_CUSTOM_CAMERA) { + DEG_add_object_relation( + ctx->node, lmd->source_camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier"); + DEG_add_object_relation( + ctx->node, lmd->source_camera, DEG_OB_COMP_PARAMETERS, "Line Art Modifier"); + } if (ctx->scene->camera) { DEG_add_object_relation( ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier"); @@ -280,6 +286,7 @@ static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, walk(userData, ob, (ID **)&lmd->source_collection, IDWALK_CB_NOP); walk(userData, ob, (ID **)&lmd->source_object, IDWALK_CB_NOP); + walk(userData, ob, (ID **)&lmd->source_camera, IDWALK_CB_NOP); } static void panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -385,7 +392,12 @@ static void options_panel_draw(const bContext *UNUSED(C), Panel *panel) return; } - uiItemR(layout, ptr, "overscan", 0, NULL, ICON_NONE); + uiLayout *row = uiLayoutRowWithHeading(layout, false, IFACE_("Custom Camera")); + uiItemR(row, ptr, "use_custom_camera", 0, "", 0); + uiLayout *subrow = uiLayoutRow(row, true); + uiLayoutSetActive(subrow, RNA_boolean_get(ptr, "use_custom_camera")); + uiLayoutSetPropSep(subrow, true); + uiItemR(subrow, ptr, "source_camera", 0, "", ICON_OBJECT_DATA); uiLayout *col = uiLayoutColumn(layout, true); @@ -684,10 +696,11 @@ static void composition_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemL(layout, IFACE_("Object is shown in front"), ICON_ERROR); } - uiLayout *row = uiLayoutRow(layout, false); - uiLayoutSetActive(row, !show_in_front); + uiLayout *col = uiLayoutColumn(layout, false); + uiLayoutSetActive(col, !show_in_front); - uiItemR(row, ptr, "stroke_depth_offset", UI_ITEM_R_SLIDER, IFACE_("Depth Offset"), ICON_NONE); + uiItemR(col, ptr, "stroke_depth_offset", UI_ITEM_R_SLIDER, IFACE_("Depth Offset"), ICON_NONE); + uiItemR(col, ptr, "offset_towards_custom_camera", 0, IFACE_("Towards Custom Camera"), ICON_NONE); } static void panelRegister(ARegionType *region_type) diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index d170a6033fa..727de381fa4 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -311,6 +311,7 @@ typedef struct LineartRenderBuffer { bool cam_is_persp; float cam_obmat[4][4]; double camera_pos[3]; + double active_camera_pos[3]; /* Stroke offset calculation may use active or selected camera. */ double near_clip, far_clip; float shift_x, shift_y; float crease_threshold; @@ -595,7 +596,9 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb); void MOD_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold); void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad); void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance); -void MOD_lineart_chain_offset_towards_camera(LineartRenderBuffer *rb, float dist); +void MOD_lineart_chain_offset_towards_camera(LineartRenderBuffer *rb, + float dist, + bool use_custom_camera); int MOD_lineart_chain_count(const LineartEdgeChain *ec); void MOD_lineart_chain_clear_picked_flag(LineartCache *lc); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index 57eeeb96541..8b7f53b8a36 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -1009,7 +1009,9 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol } } -void MOD_lineart_chain_offset_towards_camera(LineartRenderBuffer *rb, float dist) +void MOD_lineart_chain_offset_towards_camera(LineartRenderBuffer *rb, + float dist, + bool use_custom_camera) { float dir[3]; float cam[3]; @@ -1017,6 +1019,14 @@ void MOD_lineart_chain_offset_towards_camera(LineartRenderBuffer *rb, float dist float view_clamp[3]; copy_v3fl_v3db(cam, rb->camera_pos); copy_v3fl_v3db(view, rb->view_vector); + + if (use_custom_camera) { + copy_v3fl_v3db(cam, rb->camera_pos); + } + else { + copy_v3fl_v3db(cam, rb->active_camera_pos); + } + if (rb->cam_is_persp) { LISTBASE_FOREACH (LineartEdgeChain *, ec, &rb->chains) { LISTBASE_FOREACH (LineartEdgeChainItem *, eci, &ec->chain) { diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index f8dda2f9174..ea2619a9328 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -2998,7 +2998,7 @@ void MOD_lineart_destroy_render_data(LineartGpencilModifierData *lmd) } } -static LineartCache *lineart_init_cache() +static LineartCache *lineart_init_cache(void) { LineartCache *lc = MEM_callocN(sizeof(LineartCache), "Lineart Cache"); return lc; @@ -3016,6 +3016,8 @@ void MOD_lineart_clear_cache(struct LineartCache **lc) static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene, LineartGpencilModifierData *lmd, + Object *camera, + Object *active_camera, LineartCache *lc) { LineartRenderBuffer *rb = MEM_callocN(sizeof(LineartRenderBuffer), "Line Art render buffer"); @@ -3024,10 +3026,10 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene, lmd->render_buffer_ptr = rb; lc->rb_edge_types = lmd->edge_types_override; - if (!scene || !scene->camera || !lc) { + if (!scene || !camera || !lc) { return NULL; } - Camera *c = scene->camera->data; + Camera *c = camera->data; double clipping_offset = 0; if (lmd->calculation_flags & LRT_ALLOW_CLIPPING_BOUNDARIES) { @@ -3035,8 +3037,11 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene, clipping_offset = 0.0001; } - copy_v3db_v3fl(rb->camera_pos, scene->camera->obmat[3]); - copy_m4_m4(rb->cam_obmat, scene->camera->obmat); + copy_v3db_v3fl(rb->camera_pos, camera->obmat[3]); + if (active_camera) { + copy_v3db_v3fl(rb->active_camera_pos, active_camera->obmat[3]); + } + copy_m4_m4(rb->cam_obmat, camera->obmat); rb->cam_is_persp = (c->type == CAM_PERSP); rb->near_clip = c->clip_start + clipping_offset; rb->far_clip = c->clip_end - clipping_offset; @@ -4082,6 +4087,7 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, LineartRenderBuffer *rb; Scene *scene = DEG_get_evaluated_scene(depsgraph); int intersections_only = 0; /* Not used right now, but preserve for future. */ + Object *use_camera; double t_start; @@ -4091,14 +4097,24 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, BKE_scene_camera_switch_update(scene); - if (!scene->camera) { - return false; + if (lmd->calculation_flags & LRT_USE_CUSTOM_CAMERA) { + if (!lmd->source_camera || + (use_camera = DEG_get_evaluated_object(depsgraph, lmd->source_camera))->type != + OB_CAMERA) { + return false; + } + } + else { + if (!scene->camera) { + return false; + } + use_camera = scene->camera; } LineartCache *lc = lineart_init_cache(); *cached_result = lc; - rb = lineart_create_render_buffer(scene, lmd, lc); + rb = lineart_create_render_buffer(scene, lmd, use_camera, scene->camera, lc); /* Triangle thread testing data size varies depending on the thread count. * See definition of LineartTriangleThread for details. */ @@ -4118,7 +4134,7 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, /* Get view vector before loading geometries, because we detect feature lines there. */ lineart_main_get_view_vector(rb); lineart_main_load_geometries( - depsgraph, scene, scene->camera, rb, lmd->calculation_flags & LRT_ALLOW_DUPLI_OBJECTS); + depsgraph, scene, use_camera, rb, lmd->calculation_flags & LRT_ALLOW_DUPLI_OBJECTS); if (!rb->vertex_buffer_pointers.first) { /* No geometry loaded, return early. */ @@ -4191,7 +4207,8 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph, } if (enable_stroke_depth_offset && lmd->stroke_depth_offset > FLT_EPSILON) { - MOD_lineart_chain_offset_towards_camera(rb, lmd->stroke_depth_offset); + MOD_lineart_chain_offset_towards_camera( + rb, lmd->stroke_depth_offset, lmd->flags & LRT_GPENCIL_OFFSET_TOWARDS_CUSTOM_CAMERA); } /* Finally transfer the result list into cache. */ diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 6ea07163ca8..339714da255 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -978,6 +978,7 @@ typedef enum eLineArtGPencilModifierFlags { LRT_GPENCIL_BINARY_WEIGHTS = (1 << 2) /* Deprecated, this is removed for lack of use case. */, LRT_GPENCIL_IS_BAKED = (1 << 3), LRT_GPENCIL_USE_CACHE = (1 << 4), + LRT_GPENCIL_OFFSET_TOWARDS_CUSTOM_CAMERA = (1 << 5), } eLineArtGPencilModifierFlags; typedef enum eLineartGpencilMaskSwitches { @@ -1004,6 +1005,8 @@ typedef struct LineartGpencilModifierData { short level_start; short level_end; + struct Object *source_camera; + struct Object *source_object; struct Collection *source_collection; diff --git a/source/blender/makesdna/DNA_lineart_types.h b/source/blender/makesdna/DNA_lineart_types.h index bdc9bcb6980..a52c434595c 100644 --- a/source/blender/makesdna/DNA_lineart_types.h +++ b/source/blender/makesdna/DNA_lineart_types.h @@ -49,6 +49,7 @@ typedef enum eLineartMainFlags { LRT_ALLOW_OVERLAP_EDGE_TYPES = (1 << 14), LRT_USE_CREASE_ON_SMOOTH_SURFACES = (1 << 15), LRT_USE_CREASE_ON_SHARP_EDGES = (1 << 16), + LRT_USE_CUSTOM_CAMERA = (1 << 17), } eLineartMainFlags; typedef enum eLineartEdgeFlag { diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index f5865e6ea26..fdce35ba2de 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -3073,6 +3073,12 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) RNA_define_lib_overridable(true); + prop = RNA_def_property(srna, "use_custom_camera", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "calculation_flags", LRT_USE_CUSTOM_CAMERA); + RNA_def_property_ui_text( + prop, "Use Custom Camera", "Use custom camera instead of the active camera"); + RNA_def_property_update(prop, NC_SCENE, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "use_fuzzy_intersections", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "calculation_flags", LRT_INTERSECTION_AS_CONTOUR); RNA_def_property_ui_text(prop, @@ -3209,6 +3215,21 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0f, 0.5f, 0.001f, 4); RNA_def_property_update(prop, NC_SCENE, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "offset_towards_custom_camera", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_GPENCIL_OFFSET_TOWARDS_CUSTOM_CAMERA); + RNA_def_property_ui_text(prop, + "Offset Towards Custom Camera", + "Offset strokes towards selected camera instead of the active camera"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "source_camera", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_struct_type(prop, "Object"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_ui_text( + prop, "Camera Object", "Use specified camera object for generating line art"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update"); + prop = RNA_def_property(srna, "source_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, modifier_lineart_source_type); RNA_def_property_ui_text(prop, "Source Type", "Line art stroke source type"); |