@@ -271,13 +271,14 @@ def _obb_filter(
271271 return True
272272
273273
274- def _broadphase_filter (opt_broadphase_filter : int , ngeom_aabb : int , ngeom_rbound : int , ngeom_margin : int ):
274+ def _broadphase_filter (opt_broadphase_filter : int , ngeom_aabb : int , ngeom_rbound : int , ngeom_margin : int , ngeom_gap : int ):
275275 @wp .func
276276 def func (
277277 # Model:
278278 geom_aabb : wp .array3d [wp .vec3 ],
279279 geom_rbound : wp .array2d [float ],
280280 geom_margin : wp .array2d [float ],
281+ geom_gap : wp .array2d [float ],
281282 # Data in:
282283 geom_xpos_in : wp .array2d [wp .vec3 ],
283284 geom_xmat_in : wp .array2d [wp .mat33 ],
@@ -299,21 +300,25 @@ def func(
299300 rbound1 , rbound2 = geom_rbound [rbound_id , geom1 ], geom_rbound [rbound_id , geom2 ] # kernel_analyzer: ignore
300301 margin_id = worldid % ngeom_margin if wp .static (ngeom_margin > 1 ) else 0
301302 margin1 , margin2 = geom_margin [margin_id , geom1 ], geom_margin [margin_id , geom2 ] # kernel_analyzer: ignore
303+ gap_id = worldid % ngeom_gap if wp .static (ngeom_gap > 1 ) else 0
304+ gap1 , gap2 = geom_gap [gap_id , geom1 ], geom_gap [gap_id , geom2 ] # kernel_analyzer: ignore
305+ effective_margin1 = margin1 + gap1
306+ effective_margin2 = margin2 + gap2
302307 xpos1 , xpos2 = geom_xpos_in [worldid , geom1 ], geom_xpos_in [worldid , geom2 ]
303308 xmat1 , xmat2 = geom_xmat_in [worldid , geom1 ], geom_xmat_in [worldid , geom2 ]
304309
305310 if rbound1 == 0.0 or rbound2 == 0.0 :
306311 if wp .static (opt_broadphase_filter & BroadphaseFilter .PLANE ):
307- return _plane_filter (rbound1 , rbound2 , margin1 , margin2 , xpos1 , xpos2 , xmat1 , xmat2 )
312+ return _plane_filter (rbound1 , rbound2 , effective_margin1 , effective_margin2 , xpos1 , xpos2 , xmat1 , xmat2 )
308313 else :
309314 if wp .static (opt_broadphase_filter & BroadphaseFilter .SPHERE ):
310- if not _sphere_filter (rbound1 , rbound2 , margin1 , margin2 , xpos1 , xpos2 ):
315+ if not _sphere_filter (rbound1 , rbound2 , effective_margin1 , effective_margin2 , xpos1 , xpos2 ):
311316 return False
312317 if wp .static (opt_broadphase_filter & BroadphaseFilter .AABB ):
313- if not _aabb_filter (center1 , center2 , size1 , size2 , margin1 , margin2 , xpos1 , xpos2 , xmat1 , xmat2 ):
318+ if not _aabb_filter (center1 , center2 , size1 , size2 , effective_margin1 , effective_margin2 , xpos1 , xpos2 , xmat1 , xmat2 ):
314319 return False
315320 if wp .static (opt_broadphase_filter & BroadphaseFilter .OBB ):
316- if not _obb_filter (center1 , center2 , size1 , size2 , margin1 , margin2 , xpos1 , xpos2 , xmat1 , xmat2 ):
321+ if not _obb_filter (center1 , center2 , size1 , size2 , effective_margin1 , effective_margin2 , xpos1 , xpos2 , xmat1 , xmat2 ):
317322 return False
318323
319324 return True
@@ -378,6 +383,7 @@ def sap_project(
378383 ngeom : int ,
379384 geom_rbound : wp .array2d [float ],
380385 geom_margin : wp .array2d [float ],
386+ geom_gap : wp .array2d [float ],
381387 # Data in:
382388 geom_xpos_in : wp .array2d [wp .vec3 ],
383389 nworld_in : int ,
@@ -398,7 +404,7 @@ def sap_project(
398404 # geom is a plane
399405 rbound = MJ_MAXVAL
400406
401- radius = rbound + geom_margin [worldid % geom_margin .shape [0 ], geomid ]
407+ radius = rbound + geom_margin [worldid % geom_margin .shape [0 ], geomid ] + geom_gap [ worldid % geom_gap . shape [ 0 ], geomid ]
402408 center = wp .dot (direction_in , xpos )
403409
404410 sort_index_out [worldid , geomid ] = geomid
@@ -444,7 +450,7 @@ def _sap_range(
444450
445451
446452@cache_kernel
447- def _sap_broadphase (opt_broadphase_filter : int , ngeom_aabb : int , ngeom_rbound : int , ngeom_margin : int ):
453+ def _sap_broadphase (opt_broadphase_filter : int , ngeom_aabb : int , ngeom_rbound : int , ngeom_margin : int , ngeom_gap : int ):
448454 @wp .kernel (module = "unique" , enable_backward = False )
449455 def kernel (
450456 # Model:
@@ -453,6 +459,7 @@ def kernel(
453459 geom_aabb : wp .array3d [wp .vec3 ],
454460 geom_rbound : wp .array2d [float ],
455461 geom_margin : wp .array2d [float ],
462+ geom_gap : wp .array2d [float ],
456463 nxn_pairid : wp .array [wp .vec2i ],
457464 # Data in:
458465 geom_xpos_in : wp .array2d [wp .vec3 ],
@@ -503,8 +510,8 @@ def kernel(
503510 continue
504511
505512 if (
506- wp .static (_broadphase_filter (opt_broadphase_filter , ngeom_aabb , ngeom_rbound , ngeom_margin ))(
507- geom_aabb , geom_rbound , geom_margin , geom_xpos_in , geom_xmat_in , geom1 , geom2 , worldid
513+ wp .static (_broadphase_filter (opt_broadphase_filter , ngeom_aabb , ngeom_rbound , ngeom_margin , ngeom_gap ))(
514+ geom_aabb , geom_rbound , geom_margin , geom_gap , geom_xpos_in , geom_xmat_in , geom1 , geom2 , worldid
508515 )
509516 or pairid [1 ] >= 0
510517 ):
@@ -588,7 +595,7 @@ def sap_broadphase(m: Model, d: Data, ctx: CollisionContext):
588595 wp .launch (
589596 kernel = _sap_project (m .opt .broadphase ),
590597 dim = (d .nworld , m .ngeom ),
591- inputs = [m .ngeom , m .geom_rbound , m .geom_margin , d .geom_xpos , d .nworld , direction ],
598+ inputs = [m .ngeom , m .geom_rbound , m .geom_margin , m . geom_gap , d .geom_xpos , d .nworld , direction ],
592599 outputs = [
593600 projection_lower .reshape ((- 1 , m .ngeom )),
594601 projection_upper ,
@@ -624,14 +631,17 @@ def sap_broadphase(m: Model, d: Data, ctx: CollisionContext):
624631 # assumes each geom has 5 other geoms (batched over all worlds)
625632 nsweep = 5 * nworldgeom
626633 wp .launch (
627- kernel = _sap_broadphase (m .opt .broadphase_filter , m .geom_aabb .shape [0 ], m .geom_rbound .shape [0 ], m .geom_margin .shape [0 ]),
634+ kernel = _sap_broadphase (
635+ m .opt .broadphase_filter , m .geom_aabb .shape [0 ], m .geom_rbound .shape [0 ], m .geom_margin .shape [0 ], m .geom_gap .shape [0 ]
636+ ),
628637 dim = nsweep ,
629638 inputs = [
630639 m .ngeom ,
631640 m .geom_type ,
632641 m .geom_aabb ,
633642 m .geom_rbound ,
634643 m .geom_margin ,
644+ m .geom_gap ,
635645 m .nxn_pairid ,
636646 d .geom_xpos ,
637647 d .geom_xmat ,
@@ -646,14 +656,15 @@ def sap_broadphase(m: Model, d: Data, ctx: CollisionContext):
646656
647657
648658@cache_kernel
649- def _nxn_broadphase (opt_broadphase_filter : int , ngeom_aabb : int , ngeom_rbound : int , ngeom_margin : int ):
659+ def _nxn_broadphase (opt_broadphase_filter : int , ngeom_aabb : int , ngeom_rbound : int , ngeom_margin : int , ngeom_gap : int ):
650660 @wp .kernel (module = "unique" , enable_backward = False )
651661 def kernel (
652662 # Model:
653663 geom_type : wp .array [int ],
654664 geom_aabb : wp .array3d [wp .vec3 ],
655665 geom_rbound : wp .array2d [float ],
656666 geom_margin : wp .array2d [float ],
667+ geom_gap : wp .array2d [float ],
657668 nxn_geom_pair : wp .array [wp .vec2i ],
658669 nxn_pairid : wp .array [wp .vec2i ],
659670 # Data in:
@@ -674,8 +685,8 @@ def kernel(
674685 geom2 = geom [1 ]
675686
676687 if (
677- wp .static (_broadphase_filter (opt_broadphase_filter , ngeom_aabb , ngeom_rbound , ngeom_margin ))(
678- geom_aabb , geom_rbound , geom_margin , geom_xpos_in , geom_xmat_in , geom1 , geom2 , worldid
688+ wp .static (_broadphase_filter (opt_broadphase_filter , ngeom_aabb , ngeom_rbound , ngeom_margin , ngeom_gap ))(
689+ geom_aabb , geom_rbound , geom_margin , geom_gap , geom_xpos_in , geom_xmat_in , geom1 , geom2 , worldid
679690 )
680691 or nxn_pairid [elementid ][1 ] >= 0
681692 ):
@@ -711,13 +722,16 @@ def nxn_broadphase(m: Model, d: Data, ctx: CollisionContext):
711722 `contype`/`conaffinity`, parent-child relationships, and explicit `<exclude>` tags.
712723 """
713724 wp .launch (
714- _nxn_broadphase (m .opt .broadphase_filter , m .geom_aabb .shape [0 ], m .geom_rbound .shape [0 ], m .geom_margin .shape [0 ]),
725+ _nxn_broadphase (
726+ m .opt .broadphase_filter , m .geom_aabb .shape [0 ], m .geom_rbound .shape [0 ], m .geom_margin .shape [0 ], m .geom_gap .shape [0 ]
727+ ),
715728 dim = (d .nworld , m .nxn_geom_pair_filtered .shape [0 ]),
716729 inputs = [
717730 m .geom_type ,
718731 m .geom_aabb ,
719732 m .geom_rbound ,
720733 m .geom_margin ,
734+ m .geom_gap ,
721735 m .nxn_geom_pair_filtered ,
722736 m .nxn_pairid_filtered ,
723737 d .geom_xpos ,
0 commit comments