diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-04-22 14:28:39 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-04-22 14:34:04 +0300 |
commit | f4ecd24f96b158cb6b3c21686ebd048a9cca2c71 (patch) | |
tree | 123b737b33c162d4c701253c6d0b6ad0d78e8360 /source/blender/editors | |
parent | c12e1a09ec7e76455d81fe4114e91a1561cbdb6d (diff) |
Fix curve snap to surface w/ offset & taper
Adjusting the pressure wasn't re-adjusting the offset.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/curve/editcurve_paint.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 5a4cd871feb..bc54d27b171 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -170,6 +170,11 @@ struct StrokeElem { float mval[2]; float location_world[3]; float location_local[3]; + + /* surface normal, may be zero'd */ + float normal_world[3]; + float normal_local[3]; + float pressure; }; @@ -225,10 +230,26 @@ struct CurveDrawData { void *draw_handle_view; }; -static float stroke_elem_radius(const struct CurveDrawData *cdd, const struct StrokeElem *selem) +static float stroke_elem_radius_from_pressure(const struct CurveDrawData *cdd, const float pressure) { const Curve *cu = cdd->vc.obedit->data; - return ((selem->pressure * cdd->radius.range) + cdd->radius.min) * cu->ext2; + return ((pressure * cdd->radius.range) + cdd->radius.min) * cu->ext2; +} + +static float stroke_elem_radius(const struct CurveDrawData *cdd, const struct StrokeElem *selem) +{ + return stroke_elem_radius_from_pressure(cdd, selem->pressure); +} + +static void stroke_elem_pressure_set(const struct CurveDrawData *cdd, struct StrokeElem *selem, float pressure) +{ + if ((cdd->radius.offset != 0.0f) && !is_zero_v3(selem->normal_local)) { + const float adjust = stroke_elem_radius_from_pressure(cdd, pressure) - + stroke_elem_radius_from_pressure(cdd, selem->pressure); + madd_v3_v3fl(selem->location_local, selem->normal_local, adjust); + mul_v3_m4v3(selem->location_world, cdd->vc.obedit->obmat, selem->location_local); + } + selem->pressure = pressure; } static void stroke_elem_interp( @@ -249,7 +270,7 @@ static bool stroke_elem_project( const struct CurveDrawData *cdd, const int mval_i[2], const float mval_fl[2], const float radius_offset, const float radius, - float r_location_world[3]) + float r_location_world[3], float r_normal_world[3]) { View3D *v3d = cdd->vc.v3d; ARegion *ar = cdd->vc.ar; @@ -266,6 +287,9 @@ static bool stroke_elem_project( float lambda; if (isect_ray_plane_v3(ray_origin, ray_direction, cdd->project.plane, &lambda, true)) { madd_v3_v3v3fl(r_location_world, ray_origin, ray_direction, lambda); + if (r_normal_world) { + zero_v3(r_normal_world); + } is_location_world_set = true; } } @@ -279,11 +303,17 @@ static bool stroke_elem_project( if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { if (depth_unproject(ar, &cdd->mats, mval_i, depth, r_location_world)) { is_location_world_set = true; + if (r_normal_world) { + zero_v3(r_normal_world); + } if (radius_offset != 0.0f) { float normal[3]; if (depth_read_normal(&cdd->vc, &cdd->mats, mval_i, normal)) { madd_v3_v3fl(r_location_world, normal, radius_offset * radius); + if (r_normal_world) { + copy_v3_v3(r_normal_world, normal); + } } } } @@ -305,17 +335,28 @@ static bool stroke_elem_project_fallback( const int mval_i[2], const float mval_fl[2], const float radius_offset, const float radius, const float location_fallback_depth[3], - float r_location_world[3], float r_location_local[3]) + float r_location_world[3], float r_location_local[3], + float r_normal_world[3], float r_normal_local[3]) { bool is_depth_found = stroke_elem_project( cdd, mval_i, mval_fl, radius_offset, radius, - r_location_world); + r_location_world, r_normal_world); if (is_depth_found == false) { ED_view3d_win_to_3d(cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world); + zero_v3(r_normal_local); } mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world); + if (!is_zero_v3(r_normal_world)) { + copy_v3_v3(r_normal_local, r_normal_world); + mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local); + normalize_v3(r_normal_local); + } + else { + zero_v3(r_normal_local); + } + return is_depth_found; } @@ -333,7 +374,8 @@ static bool stroke_elem_project_fallback_elem( cdd, mval_i, selem->mval, cdd->radius.offset, radius, location_fallback_depth, - selem->location_world, selem->location_local); + selem->location_world, selem->location_local, + selem->normal_world, selem->normal_local); } /** \} */ @@ -602,7 +644,7 @@ static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event) if (stroke_elem_project( cdd, event->mval, mval_fl, 0.0f, 0.0f, - location_no_offset)) + location_no_offset, NULL)) { sub_v3_v3v3(cdd->project.offset, cdd->prev.location_world_valid, location_no_offset); if (!is_zero_v3(cdd->project.offset)) { @@ -739,19 +781,19 @@ static void curve_draw_exec_precalc(wmOperator *op) } if (cps->radius_taper_start != 0.0f) { - selem_array[0]->pressure = 0.0f; const float len_taper_max = cps->radius_taper_start * len_3d; - for (i = 1; i < stroke_len && lengths[i] < len_taper_max; i++) { - selem_array[i]->pressure *= lengths[i] / len_taper_max; + for (i = 0; i < stroke_len && lengths[i] < len_taper_max; i++) { + const float pressure_new = selem_array[i]->pressure * (lengths[i] / len_taper_max); + stroke_elem_pressure_set(cdd, selem_array[i], pressure_new); } } if (cps->radius_taper_end != 0.0f) { - selem_array[stroke_len - 1]->pressure = 0.0f; const float len_taper_max = cps->radius_taper_end * len_3d; const float len_taper_min = len_3d - len_taper_max; - for (i = stroke_len - 2; i > 0 && lengths[i] > len_taper_min; i--) { - selem_array[i]->pressure *= (len_3d - lengths[i]) / len_taper_max; + for (i = stroke_len - 1; i > 0 && lengths[i] > len_taper_min; i--) { + const float pressure_new = selem_array[i]->pressure * ((len_3d - lengths[i]) / len_taper_max); + stroke_elem_pressure_set(cdd, selem_array[i], pressure_new); } } |