Move BVH active visualization flag reset after early return check in MuJoCo collision driver.

This avoids unnecessarily resetting the bvh_active flags when the collision driver returns early due to disabled constraints, disabled contacts, or having fewer than two bodies/flexes.

PiperOrigin-RevId: 959531283
Change-Id: I85caf054b06e3be1018d710f9ab762627fc3356a
This commit is contained in:
Alessio Quaglino
2026-08-05 02:41:02 -07:00
committed by Copybara-Service
parent f9a00bd5b5
commit 1362a8bded
9 changed files with 20 additions and 13 deletions
+3 -3
View File
@@ -9321,10 +9321,10 @@ is effectively a miscellaneous subsection.
.. _visual-global-bvactive: .. _visual-global-bvactive:
:at:`bvactive`: :at-val:`[false, true], "true"` :at:`bvactive`: :at-val:`[false, true], "false"`
This attribute specifies whether collision and raycasting code should mark elements of Bounding Volume Hierarchies This attribute specifies whether collision and raycasting code should mark elements of Bounding Volume Hierarchies
as intersecting, for the purpose of visualization. Setting this attribute to "false" can speed up simulation for as intersecting, for the purpose of visualization. Setting this attribute to "true" can slow down simulation for
models with high-resolution meshes. models with high-resolution meshes, due to the O(N) cost of clearing visualization flags at each step.
.. _visual-quality: .. _visual-quality:
+3
View File
@@ -47,6 +47,9 @@ Engine
of the effective-metric Cholesky factor, which no longer exists; ``mjData.efm_L`` now holds dense 3x3 blocks, of the effective-metric Cholesky factor, which no longer exists; ``mjData.efm_L`` now holds dense 3x3 blocks,
9 numbers per covered vertex. ``mjData.efm_active`` no longer takes the value 2: nothing selects a solve path on 9 numbers per covered vertex. ``mjData.efm_active`` no longer takes the value 2: nothing selects a solve path on
preconditioner exactness, so it is now a plain 0/1 flag. preconditioner exactness, so it is now a plain 0/1 flag.
- Changed the default value of :ref:`bvactive<visual-global-bvactive>` from "true" to "false". This avoids
unnecessarily clearing bounding volume hierarchy visualization flags at every simulation step, which can be a
bottleneck for models with large meshes.
Models Models
^^^^^^ ^^^^^^
+5 -5
View File
@@ -599,17 +599,17 @@ void mj_collision(const mjModel* m, mjData* d) {
resetArena(d); resetArena(d);
mj_clearEfc(d); mj_clearEfc(d);
// reset the visualization flags
if (m->vis.global.bvactive) {
memset(d->bvh_active, 0, m->nbvh);
}
// return if disabled // return if disabled
if (mjDISABLED(mjDSBL_CONSTRAINT) || mjDISABLED(mjDSBL_CONTACT) || nbodyflex < 2) { if (mjDISABLED(mjDSBL_CONSTRAINT) || mjDISABLED(mjDSBL_CONTACT) || nbodyflex < 2) {
TM_END1(mjTIMER_POS_COLLISION); TM_END1(mjTIMER_POS_COLLISION);
return; return;
} }
// reset the visualization flags
if (m->vis.global.bvactive) {
memset(d->bvh_active, 0, m->nbvh);
}
mj_markStack(d); mj_markStack(d);
// broadphase collision detector // broadphase collision detector
+1 -1
View File
@@ -144,7 +144,7 @@ void mj_defaultVisual(mjVisual* vis) {
vis->global.offheight = 480; vis->global.offheight = 480;
vis->global.realtime = 1.0; vis->global.realtime = 1.0;
vis->global.ellipsoidinertia = 0; vis->global.ellipsoidinertia = 0;
vis->global.bvactive = 1; vis->global.bvactive = 0;
// rendering quality // rendering quality
vis->quality.shadowsize = 4096; vis->quality.shadowsize = 4096;
+1 -1
View File
@@ -1193,7 +1193,7 @@
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:attribute name="ellipsoidinertia" type="kw_bool" default="false"/> <xs:attribute name="ellipsoidinertia" type="kw_bool" default="false"/>
<xs:attribute name="bvactive" type="kw_bool" default="true"/> <xs:attribute name="bvactive" type="kw_bool" default="false"/>
</xs:complexType> </xs:complexType>
<xs:complexType name="quality"> <xs:complexType name="quality">
+1 -1
View File
@@ -122,7 +122,7 @@ static const mjXDefaultEntry kDefaults_mjVisual_global[] = {
{"offheight", (int)offsetof(mjVisual, global.offheight), 2, 1, 1, 0, {480.0}}, {"offheight", (int)offsetof(mjVisual, global.offheight), 2, 1, 1, 0, {480.0}},
{"realtime", (int)offsetof(mjVisual, global.realtime), 1, 1, 1, 0, {1.0}}, {"realtime", (int)offsetof(mjVisual, global.realtime), 1, 1, 1, 0, {1.0}},
{"ellipsoidinertia", (int)offsetof(mjVisual, global.ellipsoidinertia), 2, 1, 1, 0, {0}}, {"ellipsoidinertia", (int)offsetof(mjVisual, global.ellipsoidinertia), 2, 1, 1, 0, {0}},
{"bvactive", (int)offsetof(mjVisual, global.bvactive), 2, 1, 1, 0, {1}}, {"bvactive", (int)offsetof(mjVisual, global.bvactive), 2, 1, 1, 0, {0}},
}; };
static const mjXDefaultEntry kDefaults_mjVisual_headlight[] = { static const mjXDefaultEntry kDefaults_mjVisual_headlight[] = {
+1 -1
View File
@@ -687,7 +687,7 @@ element global : mjVisual (field=global) {
offheight : int = 480 offheight : int = 480
realtime : float = 1 (positive) realtime : float = 1 (positive)
ellipsoidinertia : bool = false ellipsoidinertia : bool = false
bvactive : bool = true bvactive : bool = false
} }
element quality : mjVisual (field=quality) { element quality : mjVisual (field=quality) {
+1 -1
View File
@@ -14,7 +14,7 @@
<map force="0.1" zfar="30"/> <map force="0.1" zfar="30"/>
<rgba haze="0.15 0.25 0.35 1"/> <rgba haze="0.15 0.25 0.35 1"/>
<quality shadowsize="4096"/> <quality shadowsize="4096"/>
<global offwidth="800" offheight="800"/> <global offwidth="800" offheight="800" bvactive="true"/>
</visual> </visual>
<worldbody> <worldbody>
+4
View File
@@ -26,6 +26,10 @@
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/> <material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
</asset> </asset>
<visual>
<global bvactive="true"/>
</visual>
<default> <default>
<site rgba=".5 .5 .5 .5"/> <site rgba=".5 .5 .5 .5"/>
<joint armature="1" damping="10"/> <joint armature="1" damping="10"/>