[Bf-blender-cvs] [279f271a0ab] asset-browser-snap-dragging: Snap based on the bounding box when dropping, not origin

Julian Eisel noreply at git.blender.org
Thu May 6 21:45:13 CEST 2021


Commit: 279f271a0abdf9dc138fce76b9144a6f89275163
Author: Julian Eisel
Date:   Thu May 6 21:41:46 2021 +0200
Branches: asset-browser-snap-dragging
https://developer.blender.org/rB279f271a0abdf9dc138fce76b9144a6f89275163

Snap based on the bounding box when dropping, not origin

This makes the dropping use the object's bounding box for snapping, so
that it matches the bounding box we draw while dragging.

Not that this may have to be optional in future, there may be valid
cases to use the origin instead of the bounding box for snapping.

===================================================================

M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/intern/object.c
M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/object/object_add.c
M	source/blender/editors/space_view3d/view3d_placement.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index f3a5c794de8..608dcf524f7 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -163,6 +163,7 @@ struct Object *BKE_object_duplicate(struct Main *bmain,
 
 void BKE_object_obdata_size_init(struct Object *ob, const float size);
 
+void BKE_object_scale_to_vec3(const struct Object *ob, float r_scale[3]);
 void BKE_object_scale_to_mat3(struct Object *ob, float r_mat[3][3]);
 void BKE_object_rot_to_mat3(const struct Object *ob, float r_mat[3][3], bool use_drot);
 void BKE_object_mat3_to_rot(struct Object *ob, float r_mat[3][3], bool use_compat);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 1c1f984b9b4..486babab3e3 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -3082,10 +3082,15 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size)
 /** \name Object Matrix Get/Set API
  * \{ */
 
+void BKE_object_scale_to_vec3(const Object *ob, float r_scale[3])
+{
+  mul_v3_v3v3(r_scale, ob->scale, ob->dscale);
+}
+
 void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
 {
   float vec[3];
-  mul_v3_v3v3(vec, ob->scale, ob->dscale);
+  BKE_object_scale_to_vec3(ob, vec);
   size_to_mat3(mat, vec);
 }
 
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 80b717ad21c..2101e1d971b 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -736,10 +736,27 @@ void ED_view3d_local_collections_reset(struct bContext *C, const bool reset_all)
 
 /* view3d_placement.c */
 
+enum ePlaceDirection {
+  /** Use the negative direction of the plane axis as up-axis for the
+   *  boundbox snapping (snap with front, left or bottom side). */
+  PLACE_DIRECTION_NEG,
+  /** Use the positive direction of the plane axis as up-axis for the
+   *  boundbox snapping (snap with back, right or top side). */
+  PLACE_DIRECTION_POS,
+};
+
 void ED_view3d_placement_plane_calc(struct bContext *C,
                                     const int mval[2],
+                                    const int plane_axis,
                                     float r_co_src[3],
                                     float r_mat_orient[3][3]);
+void ED_view3d_placement_plane_boundbox_calc(struct bContext *C,
+                                             const int mval[2],
+                                             const struct BoundBox *boundbox,
+                                             const enum ePlaceDirection direction,
+                                             const float scale[3],
+                                             float r_co_src[3],
+                                             float r_mat_orient[3][3]);
 
 #ifdef WITH_XR_OPENXR
 void ED_view3d_xr_mirror_update(const struct ScrArea *area,
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 3e0b1d54a70..b21f0c64ec4 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -3415,6 +3415,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
   }
 
   /* prepare dupli */
+  /* TODO don't copy for assets! */
   basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag, 0);
 
   if (basen == NULL) {
@@ -3424,14 +3425,6 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
 
   basen->object->restrictflag &= ~OB_RESTRICT_VIEWPORT;
 
-  int mval[2];
-  if (object_add_drop_xy_get(C, op, &mval)) {
-    float rotmat[3][3];
-    ED_view3d_placement_plane_calc(C, mval, basen->object->loc, rotmat);
-    BLI_assert(basen->object->rotmode == ROT_MODE_XYZ);
-    mat3_to_eul(basen->object->rot, rotmat);
-  }
-
   /* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
    * BKE_view_layer_base_deselect_all(). */
   ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
@@ -3449,6 +3442,25 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
   WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
   ED_outliner_select_sync_from_object_tag(C);
 
+  /* For the placement based on the bounding box to work, the object/object-data has to be
+   * evaulated first. */
+  int mval[2];
+  if (object_add_drop_xy_get(C, op, &mval)) {
+    Object *ob_eval = DEG_get_evaluated_object(CTX_data_ensure_evaluated_depsgraph(C),
+                                               basen->object);
+    BoundBox *boundbox = BKE_object_boundbox_get(ob_eval);
+
+    float rotmat[3][3];
+    float scale[3];
+    BKE_object_scale_to_vec3(basen->object, scale);
+    ED_view3d_placement_plane_boundbox_calc(
+        C, mval, boundbox, PLACE_DIRECTION_NEG, scale, basen->object->loc, rotmat);
+
+    BLI_assert(basen->object->rotmode == ROT_MODE_XYZ);
+    mat3_to_eul(basen->object->rot, rotmat);
+    DEG_id_tag_update(&basen->object->id, ID_RECALC_TRANSFORM);
+  }
+
   return OPERATOR_FINISHED;
 }
 
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index 011efac9c0e..d8bb4ef9c77 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -1032,6 +1032,7 @@ static void view3d_interactive_add_calc_plane(bContext *C,
 
 void ED_view3d_placement_plane_calc(bContext *C,
                                     const int mval[2],
+                                    const int plane_axis,
                                     float r_co_src[3],
                                     float r_mat_orient[3][3])
 {
@@ -1039,9 +1040,11 @@ void ED_view3d_placement_plane_calc(bContext *C,
   ARegion *region = CTX_wm_region(C);
   View3D *v3d = CTX_wm_view3d(C);
 
+  /* TODO what if there is no snap gizmo? */
   wmGizmo *snap_gizmo = idp_snap_gizmo_from_region(region);
   const float mval_fl[] = {mval[0], mval[1]};
 
+  /* TODO Options here should be input parameters. */
   view3d_interactive_add_calc_plane(C,
                                     scene,
                                     v3d,
@@ -1051,12 +1054,60 @@ void ED_view3d_placement_plane_calc(bContext *C,
                                     PLACE_SNAP_TO_GEOMETRY,
                                     PLACE_DEPTH_SURFACE,
                                     PLACE_ORIENT_SURFACE,
-                                    2,
+                                    plane_axis,
                                     false,
                                     r_co_src,
                                     r_mat_orient);
 }
 
+static void placement_plane_adjust_to_boundbox(const BoundBox *boundbox,
+                                               const enum ePlaceDirection direction,
+                                               const float scale[3],
+                                               const int plane_axis,
+                                               const float plane_mat_orient[3][3],
+                                               float r_co_src[3])
+{
+  BLI_assert(ELEM(direction, PLACE_DIRECTION_NEG, PLACE_DIRECTION_POS));
+
+  const bool is_negative_up = scale[plane_axis] < 0;
+  /* Calculate the offset for all axes. */
+  float offset_vec[3] = {0};
+  {
+    /* Move the offset to put the return coordinate to the center of the bounding box. */
+    BKE_boundbox_calc_center_aabb(boundbox, offset_vec);
+
+    /* Push offset at the plane axis so the bounding box surface is where the snapping point is. */
+    float size[3];
+    BKE_boundbox_calc_size_aabb(boundbox, size);
+    offset_vec[plane_axis] -= size[plane_axis] * (is_negative_up ? -1 : 1);
+
+    /* Scale offset with the object scale. */
+    mul_v3_v3(offset_vec, scale);
+    if (direction == PLACE_DIRECTION_NEG) {
+      mul_v3_fl(offset_vec, -1);
+    }
+  }
+
+  /* Rotate the offset vector to the plane rotation. */
+  mul_v3_m3v3(offset_vec, plane_mat_orient, offset_vec);
+  /* Finally, add the rotated offset to the returned position. */
+  add_v3_v3(r_co_src, offset_vec);
+}
+
+void ED_view3d_placement_plane_boundbox_calc(bContext *C,
+                                             const int mval[2],
+                                             const BoundBox *boundbox,
+                                             const enum ePlaceDirection direction,
+                                             const float scale[3],
+                                             float r_co_src[3],
+                                             float r_mat_orient[3][3])
+{
+  const int plane_axis = 2;
+  ED_view3d_placement_plane_calc(C, mval, plane_axis, r_co_src, r_mat_orient);
+  placement_plane_adjust_to_boundbox(
+      boundbox, direction, scale, plane_axis, r_mat_orient, r_co_src);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */



More information about the Bf-blender-cvs mailing list