Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-07-07 07:57:43 +0300
committerThomas Dinges <blender@dingto.org>2022-07-15 15:51:38 +0300
commit7fb8e475d9eca93bff87f011b29ac8aa7bc0ebca (patch)
treeec525221e13e672ed468ede1f613f08425e14d91 /source/blender/blenkernel/intern
parentcc5868234444098468f94aa7106c63ec3a386f28 (diff)
Fix T99270: bones using empties as custom shapes can't be selected
Regression in [0] which didn't account for the bounds of empty objects. Add support support calculating bounds from empty draw-type to use in pose-bone culling. [0]: 3267c91b4d5caab7da8aef071a446dd2e86f86a9
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/armature.c27
-rw-r--r--source/blender/blenkernel/intern/object.cc64
2 files changed, 86 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index dfe3d9cc310..622ecde6a91 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2661,13 +2661,30 @@ BoundBox *BKE_armature_boundbox_get(Object *ob)
return ob->runtime.bb;
}
-void BKE_pchan_minmax(const Object *ob, const bPoseChannel *pchan, float r_min[3], float r_max[3])
+void BKE_pchan_minmax(const Object *ob,
+ const bPoseChannel *pchan,
+ const bool use_empty_drawtype,
+ float r_min[3],
+ float r_max[3])
{
const bArmature *arm = ob->data;
const bPoseChannel *pchan_tx = (pchan->custom && pchan->custom_tx) ? pchan->custom_tx : pchan;
- const BoundBox *bb_custom = ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) ?
- BKE_object_boundbox_get(pchan->custom) :
- NULL;
+ const BoundBox *bb_custom = NULL;
+ BoundBox bb_custom_buf;
+
+ if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) {
+ float min[3], max[3];
+ if (use_empty_drawtype && (pchan->custom->type == OB_EMPTY) &&
+ BKE_object_minmax_empty_drawtype(pchan->custom, min, max)) {
+ memset(&bb_custom_buf, 0x0, sizeof(bb_custom_buf));
+ BKE_boundbox_init_from_minmax(&bb_custom_buf, min, max);
+ bb_custom = &bb_custom_buf;
+ }
+ else {
+ bb_custom = BKE_object_boundbox_get(pchan->custom);
+ }
+ }
+
if (bb_custom) {
float mat[4][4], smat[4][4], rmat[4][4], tmp[4][4];
scale_m4_fl(smat, PCHAN_CUSTOM_BONE_LENGTH(pchan));
@@ -2704,7 +2721,7 @@ bool BKE_pose_minmax(Object *ob, float r_min[3], float r_max[3], bool use_hidden
if (pchan->bone && (!((use_hidden == false) && (PBONE_VISIBLE(arm, pchan->bone) == false)) &&
!((use_select == true) && ((pchan->bone->flag & BONE_SELECTED) == 0)))) {
- BKE_pchan_minmax(ob, pchan, r_min, r_max);
+ BKE_pchan_minmax(ob, pchan, false, r_min, r_max);
changed = true;
}
}
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 0bc092bec4f..d3301f46559 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -3990,6 +3990,70 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const Re
return true;
}
+bool BKE_object_minmax_empty_drawtype(const struct Object *ob, float r_min[3], float r_max[3])
+{
+ BLI_assert(ob->type == OB_EMPTY);
+ float3 min(0), max(0);
+
+ bool ok = false;
+ const float radius = ob->empty_drawsize;
+
+ switch (ob->empty_drawtype) {
+ case OB_ARROWS: {
+ max = float3(radius);
+ ok = true;
+ break;
+ }
+ case OB_PLAINAXES:
+ case OB_CUBE:
+ case OB_EMPTY_SPHERE: {
+ min = float3(-radius);
+ max = float3(radius);
+ ok = true;
+ break;
+ }
+ case OB_CIRCLE: {
+ max[0] = max[2] = radius;
+ min[0] = min[2] = -radius;
+ ok = true;
+ break;
+ }
+ case OB_SINGLE_ARROW: {
+ max[2] = radius;
+ ok = true;
+ break;
+ }
+ case OB_EMPTY_CONE: {
+ min = float3(-radius, 0.0f, -radius);
+ max = float3(radius, radius * 2.0f, radius);
+ ok = true;
+ break;
+ }
+ case OB_EMPTY_IMAGE: {
+ const float *ofs = ob->ima_ofs;
+ /* NOTE: this is the best approximation that can be calculated without loading the image. */
+ min[0] = ofs[0] * radius;
+ min[1] = ofs[1] * radius;
+ max[0] = radius + (ofs[0] * radius);
+ max[1] = radius + (ofs[1] * radius);
+ /* Since the image aspect can shrink the bounds towards the object origin,
+ * adjust the min/max to account for that. */
+ for (int i = 0; i < 2; i++) {
+ CLAMP_MAX(min[i], 0.0f);
+ CLAMP_MIN(max[i], 0.0f);
+ }
+ ok = true;
+ break;
+ }
+ }
+
+ if (ok) {
+ copy_v3_v3(r_min, min);
+ copy_v3_v3(r_max, max);
+ }
+ return ok;
+}
+
bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
Scene *scene,
Object *ob,