[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 ¢er, 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