[Bf-blender-cvs] [a9d716fa0fe] tmp-worbench-rewrite2-optimizations: Optimization: Draw: Avoid runtime.bb allocation for DupliObjects

Miguel Pozo noreply at git.blender.org
Fri Jan 20 20:24:16 CET 2023


Commit: a9d716fa0fe3f0d250de3438e0ac8af22514178a
Author: Miguel Pozo
Date:   Wed Jan 18 15:17:47 2023 +0100
Branches: tmp-worbench-rewrite2-optimizations
https://developer.blender.org/rBa9d716fa0fe3f0d250de3438e0ac8af22514178a

Optimization: Draw: Avoid runtime.bb allocation for DupliObjects

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

M	source/blender/draw/intern/draw_manager_data.cc
M	source/blender/draw/intern/draw_resource.hh

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

diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc
index 5b4e0792577..125029b79e1 100644
--- a/source/blender/draw/intern/draw_manager_data.cc
+++ b/source/blender/draw/intern/draw_manager_data.cc
@@ -16,6 +16,7 @@
 #include "BKE_global.h"
 #include "BKE_image.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_wrapper.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_pbvh.h"
@@ -695,7 +696,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
   drw_call_calc_orco(ob, ob_infos->orcotexfac);
   /* Random float value. */
   uint random = (DST.dupli_source) ?
-                     DST.dupli_source->random_id :
+                    DST.dupli_source->random_id :
                      /* TODO(fclem): this is rather costly to do at runtime. Maybe we can
                       * put it in ob->runtime and make depsgraph ensure it is up to date. */
                      BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
@@ -719,26 +720,41 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
 
 static void drw_call_culling_init(DRWCullingState *cull, Object *ob)
 {
-  const BoundBox *bbox;
-  if (ob != nullptr && (bbox = BKE_object_boundbox_get(ob))) {
-    float corner[3];
-    /* Get BoundSphere center and radius from the BoundBox. */
-    mid_v3_v3v3(cull->bsphere.center, bbox->vec[0], bbox->vec[6]);
-    mul_v3_m4v3(corner, ob->object_to_world, bbox->vec[0]);
-    mul_m4_v3(ob->object_to_world, cull->bsphere.center);
-    cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner);
+  /* Bypass test */
+  cull->bsphere.radius = -1.0f;
+  /* Reset user data */
+  cull->user_data = nullptr;
+
+  if (ob != nullptr) {
+    if (ob->type == OB_MESH) {
+      /* Optimization: Retrieve the mesh cached min max directly.
+       * Avoids allocating a BoundBox on every sample for each DupliObject instance.
+       * TODO(Miguel Pozo): Remove once T92963 or T96968 are done */
+      float3 min, max;
+      INIT_MINMAX(min, max);
+      BKE_mesh_wrapper_minmax(static_cast<Mesh *>(ob->data), min, max);
+
+      /* Get BoundSphere center and radius from min/max. */
+      float3 min_world = float4x4(ob->object_to_world) * min;
+      float3 max_world = float4x4(ob->object_to_world) * max;
+
+      mid_v3_v3v3(cull->bsphere.center, min_world, max_world);
+      cull->bsphere.radius = len_v3v3(cull->bsphere.center, max_world);
+    }
+    else if (const BoundBox *bbox = BKE_object_boundbox_get(ob)) {
+      float corner[3];
+      /* Get BoundSphere center and radius from the BoundBox. */
+      mid_v3_v3v3(cull->bsphere.center, bbox->vec[0], bbox->vec[6]);
+      mul_v3_m4v3(corner, ob->object_to_world, bbox->vec[0]);
+      mul_m4_v3(ob->object_to_world, cull->bsphere.center);
+      cull->bsphere.radius = len_v3v3(cull->bsphere.center, corner);
+    }
 
     /* Bypass test for very large objects (see T67319). */
     if (UNLIKELY(cull->bsphere.radius > 1e12)) {
       cull->bsphere.radius = -1.0f;
     }
   }
-  else {
-    /* Bypass test. */
-    cull->bsphere.radius = -1.0f;
-  }
-  /* Reset user data */
-  cull->user_data = nullptr;
 }
 
 static DRWResourceHandle drw_resource_handle_new(float (*obmat)[4], Object *ob)
diff --git a/source/blender/draw/intern/draw_resource.hh b/source/blender/draw/intern/draw_resource.hh
index a2de084b900..edc023c5703 100644
--- a/source/blender/draw/intern/draw_resource.hh
+++ b/source/blender/draw/intern/draw_resource.hh
@@ -13,6 +13,7 @@
 #include "BKE_curve.h"
 #include "BKE_duplilist.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_wrapper.h"
 #include "BKE_object.h"
 #include "BKE_volume.h"
 #include "BLI_hash.h"
@@ -151,11 +152,25 @@ inline void ObjectBounds::sync()
 
 inline void ObjectBounds::sync(Object &ob)
 {
-  const BoundBox *bbox = BKE_object_boundbox_get(&ob);
-  if (bbox == nullptr) {
-    bounding_sphere.w = -1.0f; /* Disable test. */
-    return;
+  BoundBox _bbox;
+  const BoundBox *bbox = &_bbox;
+
+  if (ob.type == OB_MESH) {
+    /* Optimization: Retrieve the mesh cached min max directly.
+     * Avoids allocating a BoundBox on every sample for each DupliObject instance.
+     * TODO(Miguel Pozo): Remove once T92963 or T96968 are done */
+    float3 min, max;
+    BKE_mesh_wrapper_minmax(static_cast<Mesh *>(ob.data), min, max);
+    BKE_boundbox_init_from_minmax(&_bbox, min, max);
+  }
+  else {
+    bbox = BKE_object_boundbox_get(&ob);
+    if (bbox == nullptr) {
+      bounding_sphere.w = -1.0f; /* Disable test. */
+      return;
+    }
   }
+
   *reinterpret_cast<float3 *>(&bounding_corners[0]) = bbox->vec[0];
   *reinterpret_cast<float3 *>(&bounding_corners[1]) = bbox->vec[4];
   *reinterpret_cast<float3 *>(&bounding_corners[2]) = bbox->vec[3];
@@ -163,15 +178,6 @@ inline void ObjectBounds::sync(Object &ob)
   bounding_sphere.w = 0.0f; /* Enable test. */
 }
 
-inline void ObjectBounds::sync(const float3 &center, const float3 &size)
-{
-  *reinterpret_cast<float3 *>(&bounding_corners[0]) = center - size;
-  *reinterpret_cast<float3 *>(&bounding_corners[1]) = center + float3(+size.x, -size.y, -size.z);
-  *reinterpret_cast<float3 *>(&bounding_corners[2]) = center + float3(-size.x, +size.y, -size.z);
-  *reinterpret_cast<float3 *>(&bounding_corners[3]) = center + float3(-size.x, -size.y, +size.z);
-  bounding_sphere.w = 0.0; /* Enable test. */
-}
-
 inline std::ostream &operator<<(std::ostream &stream, const ObjectBounds &bounds)
 {
   stream << "ObjectBounds(";



More information about the Bf-blender-cvs mailing list