Cloth: share self and object collision BVH trees when possible.

Both cloth object collision and self collision use a BVH tree
representing the current cloth shape. The only difference between
them is the epsilon threshold value.

If these values are the same, it is possible to use the same tree
for both uses, thus easily reducing the overhead in the case when
both collision modes are used by the same cloth object.

Differential Revision: https://developer.blender.org/D16914
This commit is contained in:
Alexander Gavrilov 2022-12-28 23:39:36 +02:00
parent 5cc793912e
commit a3ac91da27
3 changed files with 16 additions and 5 deletions

View File

@ -72,7 +72,7 @@ typedef struct Cloth {
unsigned char pad2;
short pad3;
struct BVHTree *bvhtree; /* collision tree for this cloth object */
struct BVHTree *bvhselftree; /* collision tree for this cloth object */
struct BVHTree *bvhselftree; /* collision tree for this cloth object (may be same as bvhtree) */
struct MVertTri *tri;
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
struct EdgeSet *edgeset; /* used for selfcollisions */

View File

@ -461,7 +461,7 @@ void cloth_free_modifier(ClothModifierData *clmd)
BLI_bvhtree_free(cloth->bvhtree);
}
if (cloth->bvhselftree) {
if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) {
BLI_bvhtree_free(cloth->bvhselftree);
}
@ -538,7 +538,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd)
BLI_bvhtree_free(cloth->bvhtree);
}
if (cloth->bvhselftree) {
if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) {
BLI_bvhtree_free(cloth->bvhselftree);
}
@ -820,7 +820,14 @@ static bool cloth_from_object(
}
clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon);
clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon);
if (compare_ff(clmd->coll_parms->selfepsilon, clmd->coll_parms->epsilon, 1e-6f)) {
/* Share the BVH tree if the epsilon is the same. */
clmd->clothObject->bvhselftree = clmd->clothObject->bvhtree;
}
else {
clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon);
}
return true;
}

View File

@ -1559,6 +1559,7 @@ int cloth_bvh_collision(
BVHTreeOverlap **overlap_obj = NULL;
uint coll_count_self = 0;
BVHTreeOverlap *overlap_self = NULL;
bool bvh_updated = false;
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh == NULL) {
return 0;
@ -1569,6 +1570,7 @@ int cloth_bvh_collision(
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
bvhtree_update_from_cloth(clmd, false, false);
bvh_updated = true;
/* Enable self collision if this is a hair sim */
const bool is_hair = (clmd->hairdata != NULL);
@ -1605,7 +1607,9 @@ int cloth_bvh_collision(
}
if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) {
bvhtree_update_from_cloth(clmd, false, true);
if (cloth->bvhselftree != cloth->bvhtree || !bvh_updated) {
bvhtree_update_from_cloth(clmd, false, true);
}
overlap_self = BLI_bvhtree_overlap_self(
cloth->bvhselftree, &coll_count_self, cloth_bvh_self_overlap_cb, clmd);