@@ -193,6 +193,15 @@ def capsule(p: wp.vec3, size: wp.vec3) -> float:
193193 return wp .length (diff ) - r
194194
195195
196+ @wp .func
197+ def cylinder (p : wp .vec3 , size : wp .vec3 ) -> float :
198+ r = size [0 ]
199+ h = size [1 ]
200+ dx = wp .length (wp .vec2 (p [0 ], p [1 ])) - r
201+ dy = wp .abs (p [2 ]) - h
202+ return wp .min (wp .max (dx , dy ), 0.0 ) + wp .length (wp .vec2 (wp .max (dx , 0.0 ), wp .max (dy , 0.0 )))
203+
204+
196205@wp .func
197206def grad_sphere (p : wp .vec3 ) -> wp .vec3 :
198207 c = wp .length (p )
@@ -252,6 +261,40 @@ def grad_capsule(p: wp.vec3, size: wp.vec3) -> wp.vec3:
252261 return wp .vec3 (0.0 )
253262
254263
264+ @wp .func
265+ def grad_cylinder (p : wp .vec3 , size : wp .vec3 ) -> wp .vec3 :
266+ r = size [0 ]
267+ h = size [1 ]
268+
269+ radial_dist = wp .length (wp .vec2 (p [0 ], p [1 ]))
270+ if radial_dist > MJ_MINVAL :
271+ u = wp .vec3 (p [0 ] / radial_dist , p [1 ] / radial_dist , 0.0 )
272+ else :
273+ u = wp .vec3 (0.0 )
274+
275+ w = wp .vec3 (0.0 , 0.0 , wp .sign (p [2 ]))
276+
277+ dx = radial_dist - r
278+ dy = wp .abs (p [2 ]) - h
279+
280+ if dx > 0.0 and dy > 0.0 :
281+ v = wp .vec2 (dx , dy )
282+ len_v = wp .length (v )
283+ if len_v > MJ_MINVAL :
284+ return u * (dx / len_v ) + w * (dy / len_v )
285+ else :
286+ return wp .vec3 (0.0 )
287+ elif dx > 0.0 :
288+ return u
289+ elif dy > 0.0 :
290+ return w
291+ else :
292+ if dx > dy :
293+ return u
294+ else :
295+ return w
296+
297+
255298@wp .func
256299def user_sdf (p : wp .vec3 , attr : vec_pluginattr , sdf_type : int ) -> float :
257300 """User-defined SDF function.
@@ -418,6 +461,8 @@ def sdf(type: int, p: wp.vec3, attr: vec_pluginattr, sdf_type: int, volume_data:
418461 return sphere (p , attr_vec3 )
419462 elif type == GeomType .CAPSULE :
420463 return capsule (p , attr_vec3 )
464+ elif type == GeomType .CYLINDER :
465+ return cylinder (p , attr_vec3 )
421466 elif type == GeomType .BOX :
422467 return box (p , attr_vec3 )
423468 elif type == GeomType .ELLIPSOID :
@@ -478,6 +523,8 @@ def sdf_grad(
478523 return grad_sphere (p )
479524 elif type == GeomType .CAPSULE :
480525 return grad_capsule (p , attr_vec3 )
526+ elif type == GeomType .CYLINDER :
527+ return grad_cylinder (p , attr_vec3 )
481528 elif type == GeomType .BOX :
482529 return grad_box (p , attr_vec3 )
483530 elif type == GeomType .ELLIPSOID :
0 commit comments