Commit: e0a8f9b78e7a3e5d8dcd3b490989401d461936ed
Author: Campbell Barton
Date: Thu Mar 17 18:07:07 2022 +1100
Branches: master
https://developer.blender.org/rBe0a8f9b78e7a3e5d8dcd3b490989401d461936ed
Fix unintended de-selection when selecting the object center
Selecting an object that was already active & selected would de-select
it when the cursor was over the objects center.
This was caused by [0] that added a check which assumed more than one
hits from GPU_select meant there were multiple objects to select from.
This is not necessarily the case since bones, camera tracks or the
objects own center can add additional hits.
Resolve by keeping track of the best hit with & without the
active-selected object, only using the non-active-selected if it's found.
[0] 1550573360241ef5be0839d2652e9e092f510b63
===================================================================
M source/blender/editors/space_view3d/view3d_select.c
===================================================================
diff --git a/source/blender/editors/space_view3d/view3d_select.c
b/source/blender/editors/space_view3d/view3d_select.c
index f635bcf52b8..98cf222af17 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -2052,7 +2052,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
if (do_nearest) {
uint min = 0xFFFFFFFF;
- int selcol = 0, notcol = 0;
+ int selcol = 0;
if (has_bones) {
/* we skip non-bone hits */
@@ -2065,18 +2065,51 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
}
}
else {
- /* only exclude active object when it is selected... */
+ int select_id_exclude = 0;
+ /* Only exclude active object when it is selected. */
if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) &&
hits > 1) {
- notcol = BASACT(view_layer)->object->runtime.select_id;
+ select_id_exclude = BASACT(view_layer)->object->runtime.select_id;
}
+ /* Find the best active & non-active hits.
+ * NOTE(@campbellbarton): Checking if `hits > 1` isn't a reliable way to
know
+ * if there are multiple objects selected since it's possible the same
object
+ * generates multiple hits, either from:
+ * - Multiple sub-components (bones & camera tracks).
+ * - Multiple selectable elements such as the object center and the
geometry.
+ *
+ * For this reason, keep track of the best hit as well as the best hit
that
+ * excludes the selected & active object, using this value when it's
valid. */
+
+ uint min_not_active = min;
+ int hit_index = -1, hit_index_not_active = -1;
+
for (a = 0; a < hits; a++) {
- if (min > buffer[a].depth && notcol != (buffer[a].id & 0xFFFF)) {
+ /* Any object. */
+ if (min > buffer[a].depth) {
min = buffer[a].depth;
- selcol = buffer[a].id & 0xFFFF;
- sub_selection_id = (buffer[a].id & 0xFFFF0000) >> 16;
+ hit_index = a;
+ }
+ /* Any object other than the active-selected. */
+ if (select_id_exclude != 0) {
+ if (min_not_active > buffer[a].depth && select_id_exclude !=
(buffer[a].id & 0xFFFF)) {
+ min_not_active = buffer[a].depth;
+ hit_index_not_active = a;
+ }
}
}
+
+ /* When the active was selected, first try to use the index
+ * for the best non-active hit that was found. */
+ if (hit_index_not_active != -1) {
+ hit_index = hit_index_not_active;
+ }
+
+ if (hit_index != -1) {
+ selcol = buffer[hit_index].id & 0xFFFF;
+ sub_selection_id = (buffer[hit_index].id & 0xFFFF0000) >> 16;
+ /* No need to set `min` to `buffer[hit_index].depth`, it's not used
from now on. */
+ }
}
base = FIRSTBASE(view_layer);
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs