warp-lang 0.9.0__py3-none-win_amd64.whl → 0.11.0__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of warp-lang might be problematic. Click here for more details.

Files changed (315) hide show
  1. warp/__init__.py +15 -7
  2. warp/__init__.pyi +1 -0
  3. warp/bin/warp-clang.dll +0 -0
  4. warp/bin/warp.dll +0 -0
  5. warp/build.py +22 -443
  6. warp/build_dll.py +384 -0
  7. warp/builtins.py +998 -488
  8. warp/codegen.py +1307 -739
  9. warp/config.py +5 -3
  10. warp/constants.py +6 -0
  11. warp/context.py +1291 -548
  12. warp/dlpack.py +31 -31
  13. warp/fabric.py +326 -0
  14. warp/fem/__init__.py +27 -0
  15. warp/fem/cache.py +389 -0
  16. warp/fem/dirichlet.py +181 -0
  17. warp/fem/domain.py +263 -0
  18. warp/fem/field/__init__.py +101 -0
  19. warp/fem/field/field.py +149 -0
  20. warp/fem/field/nodal_field.py +299 -0
  21. warp/fem/field/restriction.py +21 -0
  22. warp/fem/field/test.py +181 -0
  23. warp/fem/field/trial.py +183 -0
  24. warp/fem/geometry/__init__.py +19 -0
  25. warp/fem/geometry/closest_point.py +70 -0
  26. warp/fem/geometry/deformed_geometry.py +271 -0
  27. warp/fem/geometry/element.py +744 -0
  28. warp/fem/geometry/geometry.py +186 -0
  29. warp/fem/geometry/grid_2d.py +373 -0
  30. warp/fem/geometry/grid_3d.py +435 -0
  31. warp/fem/geometry/hexmesh.py +953 -0
  32. warp/fem/geometry/partition.py +376 -0
  33. warp/fem/geometry/quadmesh_2d.py +532 -0
  34. warp/fem/geometry/tetmesh.py +840 -0
  35. warp/fem/geometry/trimesh_2d.py +577 -0
  36. warp/fem/integrate.py +1616 -0
  37. warp/fem/operator.py +191 -0
  38. warp/fem/polynomial.py +213 -0
  39. warp/fem/quadrature/__init__.py +2 -0
  40. warp/fem/quadrature/pic_quadrature.py +245 -0
  41. warp/fem/quadrature/quadrature.py +294 -0
  42. warp/fem/space/__init__.py +292 -0
  43. warp/fem/space/basis_space.py +489 -0
  44. warp/fem/space/collocated_function_space.py +105 -0
  45. warp/fem/space/dof_mapper.py +236 -0
  46. warp/fem/space/function_space.py +145 -0
  47. warp/fem/space/grid_2d_function_space.py +267 -0
  48. warp/fem/space/grid_3d_function_space.py +306 -0
  49. warp/fem/space/hexmesh_function_space.py +352 -0
  50. warp/fem/space/partition.py +350 -0
  51. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  52. warp/fem/space/restriction.py +160 -0
  53. warp/fem/space/shape/__init__.py +15 -0
  54. warp/fem/space/shape/cube_shape_function.py +738 -0
  55. warp/fem/space/shape/shape_function.py +103 -0
  56. warp/fem/space/shape/square_shape_function.py +611 -0
  57. warp/fem/space/shape/tet_shape_function.py +567 -0
  58. warp/fem/space/shape/triangle_shape_function.py +429 -0
  59. warp/fem/space/tetmesh_function_space.py +292 -0
  60. warp/fem/space/topology.py +295 -0
  61. warp/fem/space/trimesh_2d_function_space.py +221 -0
  62. warp/fem/types.py +77 -0
  63. warp/fem/utils.py +495 -0
  64. warp/native/array.h +164 -55
  65. warp/native/builtin.h +150 -174
  66. warp/native/bvh.cpp +75 -328
  67. warp/native/bvh.cu +406 -23
  68. warp/native/bvh.h +37 -45
  69. warp/native/clang/clang.cpp +136 -24
  70. warp/native/crt.cpp +1 -76
  71. warp/native/crt.h +111 -104
  72. warp/native/cuda_crt.h +1049 -0
  73. warp/native/cuda_util.cpp +15 -3
  74. warp/native/cuda_util.h +3 -1
  75. warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
  76. warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
  77. warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
  78. warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
  79. warp/native/cutlass/tools/library/scripts/library.py +799 -0
  80. warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
  81. warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
  82. warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
  83. warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
  84. warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
  85. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
  86. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
  87. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
  88. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
  89. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
  90. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
  91. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
  92. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
  93. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
  94. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
  95. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
  96. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
  97. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
  98. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
  99. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
  100. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
  101. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
  102. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
  103. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
  104. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
  105. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
  106. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
  107. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
  108. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
  109. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
  110. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
  111. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
  112. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
  113. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
  114. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
  115. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
  116. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
  117. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  118. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  119. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
  120. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
  121. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
  122. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  123. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  124. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
  125. warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
  126. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
  127. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
  128. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
  129. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
  130. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
  131. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
  132. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
  133. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
  134. warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
  135. warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
  136. warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
  137. warp/native/cutlass/tools/library/scripts/rt.py +796 -0
  138. warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
  139. warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
  140. warp/native/cutlass_gemm.cu +5 -3
  141. warp/native/exports.h +1240 -949
  142. warp/native/fabric.h +228 -0
  143. warp/native/hashgrid.cpp +4 -4
  144. warp/native/hashgrid.h +22 -2
  145. warp/native/initializer_array.h +2 -2
  146. warp/native/intersect.h +22 -7
  147. warp/native/intersect_adj.h +8 -8
  148. warp/native/intersect_tri.h +13 -16
  149. warp/native/marching.cu +157 -161
  150. warp/native/mat.h +119 -19
  151. warp/native/matnn.h +2 -2
  152. warp/native/mesh.cpp +108 -83
  153. warp/native/mesh.cu +243 -6
  154. warp/native/mesh.h +1547 -458
  155. warp/native/nanovdb/NanoVDB.h +1 -1
  156. warp/native/noise.h +272 -329
  157. warp/native/quat.h +51 -8
  158. warp/native/rand.h +45 -35
  159. warp/native/range.h +6 -2
  160. warp/native/reduce.cpp +157 -0
  161. warp/native/reduce.cu +348 -0
  162. warp/native/runlength_encode.cpp +62 -0
  163. warp/native/runlength_encode.cu +46 -0
  164. warp/native/scan.cu +11 -13
  165. warp/native/scan.h +1 -0
  166. warp/native/solid_angle.h +442 -0
  167. warp/native/sort.cpp +13 -0
  168. warp/native/sort.cu +9 -1
  169. warp/native/sparse.cpp +338 -0
  170. warp/native/sparse.cu +545 -0
  171. warp/native/spatial.h +2 -2
  172. warp/native/temp_buffer.h +30 -0
  173. warp/native/vec.h +126 -24
  174. warp/native/volume.h +120 -0
  175. warp/native/warp.cpp +658 -53
  176. warp/native/warp.cu +660 -68
  177. warp/native/warp.h +112 -12
  178. warp/optim/__init__.py +1 -0
  179. warp/optim/linear.py +922 -0
  180. warp/optim/sgd.py +92 -0
  181. warp/render/render_opengl.py +392 -152
  182. warp/render/render_usd.py +11 -11
  183. warp/sim/__init__.py +2 -2
  184. warp/sim/articulation.py +385 -185
  185. warp/sim/collide.py +21 -8
  186. warp/sim/import_mjcf.py +297 -106
  187. warp/sim/import_urdf.py +389 -210
  188. warp/sim/import_usd.py +198 -97
  189. warp/sim/inertia.py +17 -18
  190. warp/sim/integrator_euler.py +14 -8
  191. warp/sim/integrator_xpbd.py +161 -19
  192. warp/sim/model.py +795 -291
  193. warp/sim/optimizer.py +2 -6
  194. warp/sim/render.py +65 -3
  195. warp/sim/utils.py +3 -0
  196. warp/sparse.py +1227 -0
  197. warp/stubs.py +665 -223
  198. warp/tape.py +66 -15
  199. warp/tests/__main__.py +3 -6
  200. warp/tests/assets/curlnoise_golden.npy +0 -0
  201. warp/tests/assets/pnoise_golden.npy +0 -0
  202. warp/tests/assets/torus.usda +105 -105
  203. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  204. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  205. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  206. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  207. warp/tests/aux_test_unresolved_func.py +14 -0
  208. warp/tests/aux_test_unresolved_symbol.py +14 -0
  209. warp/tests/disabled_kinematics.py +239 -0
  210. warp/tests/run_coverage_serial.py +31 -0
  211. warp/tests/test_adam.py +103 -106
  212. warp/tests/test_arithmetic.py +128 -74
  213. warp/tests/test_array.py +1497 -211
  214. warp/tests/test_array_reduce.py +150 -0
  215. warp/tests/test_atomic.py +64 -28
  216. warp/tests/test_bool.py +99 -0
  217. warp/tests/test_builtins_resolution.py +1292 -0
  218. warp/tests/test_bvh.py +75 -43
  219. warp/tests/test_closest_point_edge_edge.py +54 -57
  220. warp/tests/test_codegen.py +233 -128
  221. warp/tests/test_compile_consts.py +28 -20
  222. warp/tests/test_conditional.py +108 -24
  223. warp/tests/test_copy.py +10 -12
  224. warp/tests/test_ctypes.py +112 -88
  225. warp/tests/test_dense.py +21 -14
  226. warp/tests/test_devices.py +98 -0
  227. warp/tests/test_dlpack.py +136 -108
  228. warp/tests/test_examples.py +277 -0
  229. warp/tests/test_fabricarray.py +955 -0
  230. warp/tests/test_fast_math.py +15 -11
  231. warp/tests/test_fem.py +1271 -0
  232. warp/tests/test_fp16.py +53 -19
  233. warp/tests/test_func.py +187 -74
  234. warp/tests/test_generics.py +194 -49
  235. warp/tests/test_grad.py +180 -116
  236. warp/tests/test_grad_customs.py +176 -0
  237. warp/tests/test_hash_grid.py +52 -37
  238. warp/tests/test_import.py +10 -23
  239. warp/tests/test_indexedarray.py +577 -24
  240. warp/tests/test_intersect.py +18 -9
  241. warp/tests/test_large.py +141 -0
  242. warp/tests/test_launch.py +251 -15
  243. warp/tests/test_lerp.py +64 -65
  244. warp/tests/test_linear_solvers.py +154 -0
  245. warp/tests/test_lvalue.py +493 -0
  246. warp/tests/test_marching_cubes.py +12 -13
  247. warp/tests/test_mat.py +508 -2778
  248. warp/tests/test_mat_lite.py +115 -0
  249. warp/tests/test_mat_scalar_ops.py +2889 -0
  250. warp/tests/test_math.py +103 -9
  251. warp/tests/test_matmul.py +305 -69
  252. warp/tests/test_matmul_lite.py +410 -0
  253. warp/tests/test_mesh.py +71 -14
  254. warp/tests/test_mesh_query_aabb.py +41 -25
  255. warp/tests/test_mesh_query_point.py +325 -34
  256. warp/tests/test_mesh_query_ray.py +39 -22
  257. warp/tests/test_mlp.py +30 -22
  258. warp/tests/test_model.py +92 -89
  259. warp/tests/test_modules_lite.py +39 -0
  260. warp/tests/test_multigpu.py +88 -114
  261. warp/tests/test_noise.py +12 -11
  262. warp/tests/test_operators.py +16 -20
  263. warp/tests/test_options.py +11 -11
  264. warp/tests/test_pinned.py +17 -18
  265. warp/tests/test_print.py +32 -11
  266. warp/tests/test_quat.py +275 -129
  267. warp/tests/test_rand.py +18 -16
  268. warp/tests/test_reload.py +38 -34
  269. warp/tests/test_rounding.py +50 -43
  270. warp/tests/test_runlength_encode.py +190 -0
  271. warp/tests/test_smoothstep.py +9 -11
  272. warp/tests/test_snippet.py +143 -0
  273. warp/tests/test_sparse.py +460 -0
  274. warp/tests/test_spatial.py +276 -243
  275. warp/tests/test_streams.py +110 -85
  276. warp/tests/test_struct.py +331 -85
  277. warp/tests/test_tape.py +39 -21
  278. warp/tests/test_torch.py +118 -89
  279. warp/tests/test_transient_module.py +12 -13
  280. warp/tests/test_types.py +614 -0
  281. warp/tests/test_utils.py +494 -0
  282. warp/tests/test_vec.py +354 -1987
  283. warp/tests/test_vec_lite.py +73 -0
  284. warp/tests/test_vec_scalar_ops.py +2099 -0
  285. warp/tests/test_volume.py +457 -293
  286. warp/tests/test_volume_write.py +124 -134
  287. warp/tests/unittest_serial.py +35 -0
  288. warp/tests/unittest_suites.py +341 -0
  289. warp/tests/unittest_utils.py +568 -0
  290. warp/tests/unused_test_misc.py +71 -0
  291. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  292. warp/thirdparty/appdirs.py +36 -45
  293. warp/thirdparty/unittest_parallel.py +549 -0
  294. warp/torch.py +72 -30
  295. warp/types.py +1744 -713
  296. warp/utils.py +360 -350
  297. warp_lang-0.11.0.dist-info/LICENSE.md +36 -0
  298. warp_lang-0.11.0.dist-info/METADATA +238 -0
  299. warp_lang-0.11.0.dist-info/RECORD +332 -0
  300. {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
  301. warp/bin/warp-clang.exp +0 -0
  302. warp/bin/warp-clang.lib +0 -0
  303. warp/bin/warp.exp +0 -0
  304. warp/bin/warp.lib +0 -0
  305. warp/tests/test_all.py +0 -215
  306. warp/tests/test_array_scan.py +0 -60
  307. warp/tests/test_base.py +0 -208
  308. warp/tests/test_unresolved_func.py +0 -7
  309. warp/tests/test_unresolved_symbol.py +0 -7
  310. warp_lang-0.9.0.dist-info/METADATA +0 -20
  311. warp_lang-0.9.0.dist-info/RECORD +0 -177
  312. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  313. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  314. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  315. {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
warp/sim/import_usd.py CHANGED
@@ -10,95 +10,80 @@ import numpy as np
10
10
  import re
11
11
 
12
12
  import warp as wp
13
- from . import ModelBuilder
14
13
 
15
14
 
16
15
  def parse_usd(
17
- filename,
18
- builder: ModelBuilder,
16
+ source,
17
+ builder,
19
18
  default_density=1.0e3,
20
19
  only_load_enabled_rigid_bodies=False,
21
20
  only_load_enabled_joints=True,
22
21
  default_ke=1e5,
23
22
  default_kd=250.0,
24
23
  default_kf=500.0,
25
- default_mu=0.0,
24
+ default_mu=0.6,
26
25
  default_restitution=0.0,
27
26
  default_thickness=0.0,
28
27
  joint_limit_ke=100.0,
29
28
  joint_limit_kd=10.0,
29
+ invert_rotations=False,
30
30
  verbose=False,
31
31
  ignore_paths=[],
32
- export_usda=False,
33
32
  ):
33
+ """
34
+ Parses a Universal Scene Description (USD) stage containing UsdPhysics schema definitions for rigid-body articulations and adds the bodies, shapes and joints to the given ModelBuilder.
35
+
36
+ The USD description has to be either a path (file name or URL), or an existing USD stage instance that implements the `UsdStage <https://openusd.org/dev/api/class_usd_stage.html>`_ interface.
37
+
38
+ Args:
39
+ source (str | pxr.UsdStage): The file path to the USD file, or an existing USD stage instance.
40
+ builder (ModelBuilder): The :class:`ModelBuilder` to add the bodies and joints to.
41
+ default_density (float): The default density to use for bodies without a density attribute.
42
+ only_load_enabled_rigid_bodies (bool): If True, only rigid bodies which do not have `physics:rigidBodyEnabled` set to False are loaded.
43
+ only_load_enabled_joints (bool): If True, only joints which do not have `physics:jointEnabled` set to False are loaded.
44
+ default_ke (float): The default contact stiffness to use, only considered by SemiImplicitIntegrator.
45
+ default_kd (float): The default contact damping to use, only considered by SemiImplicitIntegrator.
46
+ default_kf (float): The default friction stiffness to use, only considered by SemiImplicitIntegrator.
47
+ default_mu (float): The default friction coefficient to use if a shape has not friction coefficient defined.
48
+ default_restitution (float): The default coefficient of restitution to use if a shape has not coefficient of restitution defined.
49
+ default_thickness (float): The thickness to add to the shape geometry.
50
+ joint_limit_ke (float): The default stiffness to use for joint limits, only considered by SemiImplicitIntegrator.
51
+ joint_limit_kd (float): The default damping to use for joint limits, only considered by SemiImplicitIntegrator.
52
+ invert_rotations (bool): If True, inverts any rotations defined in the shape transforms.
53
+ verbose (bool): If True, print additional information about the parsed USD file.
54
+ ignore_paths (List[str]): A list of regular expressions matching prim paths to ignore.
55
+
56
+ Returns:
57
+ dict: Dictionary with the following entries:
58
+
59
+ .. list-table::
60
+ :widths: 25 75
61
+
62
+ * - "fps"
63
+ - USD stage frames per second
64
+ * - "duration"
65
+ - Difference between end time code and start time code of the USD stage
66
+ * - "up_axis"
67
+ - Upper-case string of the stage's up axis ("X", "Y", or "Z")
68
+ * - "path_shape_map"
69
+ - Mapping from prim path (str) of the UsdGeom to the respective shape index in :class:`ModelBuilder`
70
+ * - "path_body_map"
71
+ - Mapping from prim path (str) of a rigid body prim (e.g. that implements the PhysicsRigidBodyAPI) to the respective body index in :class:`ModelBuilder`
72
+ * - "path_shape_scale"
73
+ - Mapping from prim path (str) of the UsdGeom to its respective 3D world scale
74
+ * - "mass_unit"
75
+ - The stage's Kilograms Per Unit (KGPU) definition (1.0 by default)
76
+ * - "linear_unit"
77
+ - The stage's Meters Per Unit (MPU) definition (1.0 by default)
78
+
79
+
80
+ Note:
81
+ This importer is experimental and only supports a subset of the USD Physics schema. Please report any issues you encounter.
82
+ """
34
83
  try:
35
84
  from pxr import Usd, UsdGeom, UsdPhysics
36
85
  except ImportError:
37
- raise ImportError("Failed to import pxr. Please install USD.")
38
-
39
- if filename.startswith("http://") or filename.startswith("https://"):
40
- # download file
41
- import requests, os, datetime
42
-
43
- response = requests.get(filename, allow_redirects=True)
44
- if response.status_code != 200:
45
- raise RuntimeError(f"Failed to download USD file. Status code: {response.status_code}")
46
- file = response.content
47
- dot = os.path.extsep
48
- base = os.path.basename(filename)
49
- url_folder = os.path.dirname(filename)
50
- base_name = dot.join(base.split(dot)[:-1])
51
- timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
52
- folder_name = os.path.join(".usd_cache", f"{base_name}_{timestamp}")
53
- os.makedirs(folder_name, exist_ok=True)
54
- target_filename = os.path.join(folder_name, base)
55
- with open(target_filename, "wb") as f:
56
- f.write(file)
57
-
58
- stage = Usd.Stage.Open(target_filename, Usd.Stage.LoadNone)
59
- stage_str = stage.GetRootLayer().ExportToString()
60
- print(f"Downloaded USD file to {target_filename}.")
61
- if export_usda:
62
- usda_filename = os.path.join(folder_name, base_name + ".usda")
63
- with open(usda_filename, "w") as f:
64
- f.write(stage_str)
65
- print(f"Exported USDA file to {usda_filename}.")
66
-
67
- # parse referenced USD files like `references = @./franka_collisions.usd@`
68
- downloaded = set()
69
- for match in re.finditer(r"references.=.@(.*?)@", stage_str):
70
- refname = match.group(1)
71
- if refname.startswith("./"):
72
- refname = refname[2:]
73
- if refname in downloaded:
74
- continue
75
- try:
76
- response = requests.get(f"{url_folder}/{refname}", allow_redirects=True)
77
- if response.status_code != 200:
78
- print(f"Failed to download reference {refname}. Status code: {response.status_code}")
79
- continue
80
- file = response.content
81
- refdir = os.path.dirname(refname)
82
- if refdir:
83
- os.makedirs(os.path.join(folder_name, refdir), exist_ok=True)
84
- ref_filename = os.path.join(folder_name, refname)
85
- with open(ref_filename, "wb") as f:
86
- f.write(file)
87
- downloaded.add(refname)
88
- print(f"Downloaded USD reference {refname} to {ref_filename}.")
89
- if export_usda:
90
- ref_stage = Usd.Stage.Open(ref_filename, Usd.Stage.LoadNone)
91
- ref_stage_str = ref_stage.GetRootLayer().ExportToString()
92
- base = os.path.basename(ref_filename)
93
- base_name = dot.join(base.split(dot)[:-1])
94
- usda_filename = os.path.join(folder_name, base_name + ".usda")
95
- with open(usda_filename, "w") as f:
96
- f.write(ref_stage_str)
97
- print(f"Exported USDA file to {usda_filename}.")
98
- except:
99
- print(f"Failed to download {refname}.")
100
-
101
- filename = target_filename
86
+ raise ImportError("Failed to import pxr. Please install USD (e.g. via `pip install usd-core`).")
102
87
 
103
88
  def get_attribute(prim, name):
104
89
  if "*" in name:
@@ -127,7 +112,10 @@ def parse_usd(
127
112
  if not attr or not attr.HasAuthoredValue():
128
113
  return default
129
114
  val = attr.Get()
130
- quat = wp.quat(*val.imaginary, val.real)
115
+ if invert_rotations:
116
+ quat = wp.quat(*val.imaginary, -val.real)
117
+ else:
118
+ quat = wp.quat(*val.imaginary, val.real)
131
119
  l = wp.length(quat)
132
120
  if np.isfinite(l) and l > 0.0:
133
121
  return quat
@@ -153,20 +141,31 @@ def parse_usd(
153
141
  axis["XYZ".index(s.upper())] = 1.0
154
142
  return axis
155
143
 
156
- stage = Usd.Stage.Open(filename, Usd.Stage.LoadAll)
157
- if UsdPhysics.StageHasAuthoredKilogramsPerUnit(stage):
158
- mass_unit = UsdPhysics.GetStageKilogramsPerUnit(stage)
144
+ if isinstance(source, str):
145
+ stage = Usd.Stage.Open(source, Usd.Stage.LoadAll)
159
146
  else:
160
- mass_unit = 1.0
161
- if UsdGeom.StageHasAuthoredMetersPerUnit(stage):
162
- linear_unit = UsdGeom.GetStageMetersPerUnit(stage)
163
- else:
164
- linear_unit = 1.0
147
+ stage = source
148
+
149
+ mass_unit = 1.0
150
+ try:
151
+ if UsdPhysics.StageHasAuthoredKilogramsPerUnit(stage):
152
+ mass_unit = UsdPhysics.GetStageKilogramsPerUnit(stage)
153
+ except:
154
+ pass
155
+ linear_unit = 1.0
156
+ try:
157
+ if UsdGeom.StageHasAuthoredMetersPerUnit(stage):
158
+ linear_unit = UsdGeom.GetStageMetersPerUnit(stage)
159
+ except:
160
+ pass
165
161
 
166
162
  def parse_xform(prim):
167
163
  xform = UsdGeom.Xform(prim)
168
164
  mat = np.array(xform.GetLocalTransformation(), dtype=np.float32)
169
- rot = wp.quat_from_matrix(wp.mat33(mat[:3, :3].flatten()))
165
+ if invert_rotations:
166
+ rot = wp.quat_from_matrix(wp.mat33(mat[:3, :3].T.flatten()))
167
+ else:
168
+ rot = wp.quat_from_matrix(wp.mat33(mat[:3, :3].flatten()))
170
169
  pos = mat[3, :3] * linear_unit
171
170
  scale = np.ones(3, dtype=np.float32)
172
171
  for op in xform.GetOrderedXformOps():
@@ -247,12 +246,18 @@ def parse_usd(
247
246
  else:
248
247
  joint_data["linear_axes"].append(axis)
249
248
 
250
- upaxis = str2axis(UsdGeom.GetStageUpAxis(stage))
249
+ axis_str = "Y"
250
+ try:
251
+ axis_str = UsdGeom.GetStageUpAxis(stage)
252
+ except:
253
+ pass
254
+ upaxis = str2axis(axis_str)
251
255
 
252
256
  shape_types = {"Cube", "Sphere", "Mesh", "Capsule", "Plane", "Cylinder", "Cone"}
253
257
 
254
258
  path_body_map = {}
255
259
  path_shape_map = {}
260
+ path_shape_scale = {}
256
261
  # maps prim path name to its world transform
257
262
  path_world_poses = {}
258
263
  # transform from body frame to where the actual joint child frame is
@@ -347,21 +352,27 @@ def parse_usd(
347
352
  materials[path] = material
348
353
 
349
354
  elif type_name == "PhysicsScene":
350
- scene = UsdPhysics.Scene(prim)
351
- g_vec = scene.GetGravityDirectionAttr()
352
- g_mag = scene.GetGravityMagnitudeAttr()
353
- if g_mag.HasAuthoredValue() and np.isfinite(g_mag.Get()):
354
- builder.gravity = g_mag.Get() * linear_unit
355
- if g_vec.HasAuthoredValue() and np.linalg.norm(g_vec.Get()) > 0.0:
356
- builder.up_vector = np.array(g_vec.Get(), dtype=np.float32) # TODO flip sign?
357
- else:
358
- builder.up_vector = upaxis
355
+ try:
356
+ scene = UsdPhysics.Scene(prim)
357
+ g_vec = scene.GetGravityDirectionAttr()
358
+ g_mag = scene.GetGravityMagnitudeAttr()
359
+ if g_mag.HasAuthoredValue() and np.isfinite(g_mag.Get()):
360
+ builder.gravity = -np.abs(g_mag.Get() * linear_unit)
361
+ if g_vec.HasAuthoredValue() and np.linalg.norm(g_vec.Get()) > 0.0:
362
+ builder.up_vector = np.array(g_vec.Get(), dtype=np.float32)
363
+ if np.any(builder.up_vector < 0.0):
364
+ builder.up_vector = -builder.up_vector
365
+ else:
366
+ builder.up_vector = upaxis
367
+ except:
368
+ pass
359
369
 
360
370
  def parse_prim(prim, incoming_xform, incoming_scale, parent_body: int = -1):
361
371
  nonlocal builder
362
372
  nonlocal joint_data
363
373
  nonlocal path_body_map
364
374
  nonlocal path_shape_map
375
+ nonlocal path_shape_scale
365
376
  nonlocal path_world_poses
366
377
  nonlocal prim_joint_xforms
367
378
  nonlocal path_collision_filters
@@ -374,13 +385,14 @@ def parse_usd(
374
385
  return
375
386
 
376
387
  type_name = str(prim.GetTypeName())
377
- if (
378
- type_name.endswith("Joint")
379
- or type_name.endswith("Light")
380
- or type_name.endswith("Scene")
381
- or type_name.endswith("Material")
382
- ):
388
+ if type_name.endswith("Joint") or type_name.endswith("Light") or type_name.endswith("Material"):
383
389
  return
390
+ if verbose:
391
+ print(f"parse_prim {prim.GetPath()} ({type_name})")
392
+ if type_name == "PhysicsScene":
393
+ # in case the PhysicsScene has bodies as children...
394
+ for child in prim.GetChildren():
395
+ parse_prim(child, incoming_xform, incoming_scale, parent_body)
384
396
 
385
397
  schemas = set(prim.GetAppliedSchemas())
386
398
  children_refs = prim.GetChildren()
@@ -696,6 +708,7 @@ def parse_usd(
696
708
 
697
709
  path_body_map[path] = body_id
698
710
  path_shape_map[path] = shape_id
711
+ path_shape_scale[path] = scale
699
712
 
700
713
  if prim.HasRelationship("physics:filteredPairs"):
701
714
  other_paths = prim.GetRelationship("physics:filteredPairs").GetTargets()
@@ -761,5 +774,93 @@ def parse_usd(
761
774
  return {
762
775
  "fps": stage.GetFramesPerSecond(),
763
776
  "duration": stage.GetEndTimeCode() - stage.GetStartTimeCode(),
764
- "up_axis": UsdGeom.GetStageUpAxis(stage).lower(),
777
+ "up_axis": UsdGeom.GetStageUpAxis(stage).upper(),
778
+ "path_shape_map": path_shape_map,
779
+ "path_body_map": path_body_map,
780
+ "path_shape_scale": path_shape_scale,
781
+ "mass_unit": mass_unit,
782
+ "linear_unit": linear_unit,
765
783
  }
784
+
785
+
786
+ def resolve_usd_from_url(url: str, target_folder_name: str = None, export_usda: bool = False):
787
+ """
788
+ Downloads a USD file from a URL and resolves all references to other USD files to be downloaded to the given target folder.
789
+
790
+ Args:
791
+ url (str): URL to the USD file.
792
+ target_folder_name (str): Target folder name. If None, a timestamped folder will be created in the current directory.
793
+ export_usda (bool): If True, converts each downloaded USD file to USDA and saves the additional USDA file in the target folder with the same base name as the original USD file.
794
+
795
+ Returns:
796
+ str: File path to the downloaded USD file.
797
+ """
798
+ import requests
799
+ import datetime
800
+ import os
801
+
802
+ try:
803
+ from pxr import Usd
804
+ except ImportError:
805
+ raise ImportError("Failed to import pxr. Please install USD (e.g. via `pip install usd-core`).")
806
+
807
+ response = requests.get(url, allow_redirects=True)
808
+ if response.status_code != 200:
809
+ raise RuntimeError(f"Failed to download USD file. Status code: {response.status_code}")
810
+ file = response.content
811
+ dot = os.path.extsep
812
+ base = os.path.basename(url)
813
+ url_folder = os.path.dirname(url)
814
+ base_name = dot.join(base.split(dot)[:-1])
815
+ if target_folder_name is None:
816
+ timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
817
+ target_folder_name = os.path.join(".usd_cache", f"{base_name}_{timestamp}")
818
+ os.makedirs(target_folder_name, exist_ok=True)
819
+ target_filename = os.path.join(target_folder_name, base)
820
+ with open(target_filename, "wb") as f:
821
+ f.write(file)
822
+
823
+ stage = Usd.Stage.Open(target_filename, Usd.Stage.LoadNone)
824
+ stage_str = stage.GetRootLayer().ExportToString()
825
+ print(f"Downloaded USD file to {target_filename}.")
826
+ if export_usda:
827
+ usda_filename = os.path.join(target_folder_name, base_name + ".usda")
828
+ with open(usda_filename, "w") as f:
829
+ f.write(stage_str)
830
+ print(f"Exported USDA file to {usda_filename}.")
831
+
832
+ # parse referenced USD files like `references = @./franka_collisions.usd@`
833
+ downloaded = set()
834
+ for match in re.finditer(r"references.=.@(.*?)@", stage_str):
835
+ refname = match.group(1)
836
+ if refname.startswith("./"):
837
+ refname = refname[2:]
838
+ if refname in downloaded:
839
+ continue
840
+ try:
841
+ response = requests.get(f"{url_folder}/{refname}", allow_redirects=True)
842
+ if response.status_code != 200:
843
+ print(f"Failed to download reference {refname}. Status code: {response.status_code}")
844
+ continue
845
+ file = response.content
846
+ refdir = os.path.dirname(refname)
847
+ if refdir:
848
+ os.makedirs(os.path.join(target_folder_name, refdir), exist_ok=True)
849
+ ref_filename = os.path.join(target_folder_name, refname)
850
+ if not os.path.exists(ref_filename):
851
+ with open(ref_filename, "wb") as f:
852
+ f.write(file)
853
+ downloaded.add(refname)
854
+ print(f"Downloaded USD reference {refname} to {ref_filename}.")
855
+ if export_usda:
856
+ ref_stage = Usd.Stage.Open(ref_filename, Usd.Stage.LoadNone)
857
+ ref_stage_str = ref_stage.GetRootLayer().ExportToString()
858
+ base = os.path.basename(ref_filename)
859
+ base_name = dot.join(base.split(dot)[:-1])
860
+ usda_filename = os.path.join(target_folder_name, base_name + ".usda")
861
+ with open(usda_filename, "w") as f:
862
+ f.write(ref_stage_str)
863
+ print(f"Exported USDA file to {usda_filename}.")
864
+ except Exception:
865
+ print(f"Failed to download {refname}.")
866
+ return target_filename
warp/sim/inertia.py CHANGED
@@ -149,9 +149,9 @@ def compute_sphere_inertia(density: float, r: float) -> tuple:
149
149
  m = density * v
150
150
  Ia = 2.0 / 5.0 * m * r * r
151
151
 
152
- I = np.array([[Ia, 0.0, 0.0], [0.0, Ia, 0.0], [0.0, 0.0, Ia]])
152
+ I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ia, 0.0], [0.0, 0.0, Ia]])
153
153
 
154
- return (m, np.zeros(3), I)
154
+ return (m, wp.vec3(), I)
155
155
 
156
156
 
157
157
  def compute_capsule_inertia(density: float, r: float, h: float) -> tuple:
@@ -177,9 +177,9 @@ def compute_capsule_inertia(density: float, r: float, h: float) -> tuple:
177
177
  Ia = mc * (0.25 * r * r + (1.0 / 12.0) * h * h) + ms * (0.4 * r * r + 0.375 * r * h + 0.25 * h * h)
178
178
  Ib = (mc * 0.5 + ms * 0.4) * r * r
179
179
 
180
- I = np.array([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
180
+ I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
181
181
 
182
- return (m, np.zeros(3), I)
182
+ return (m, wp.vec3(), I)
183
183
 
184
184
 
185
185
  def compute_cylinder_inertia(density: float, r: float, h: float) -> tuple:
@@ -200,9 +200,9 @@ def compute_cylinder_inertia(density: float, r: float, h: float) -> tuple:
200
200
  Ia = 1 / 12 * m * (3 * r * r + h * h)
201
201
  Ib = 1 / 2 * m * r * r
202
202
 
203
- I = np.array([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
203
+ I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
204
204
 
205
- return (m, np.zeros(3), I)
205
+ return (m, wp.vec3(), I)
206
206
 
207
207
 
208
208
  def compute_cone_inertia(density: float, r: float, h: float) -> tuple:
@@ -223,9 +223,9 @@ def compute_cone_inertia(density: float, r: float, h: float) -> tuple:
223
223
  Ia = 1 / 20 * m * (3 * r * r + 2 * h * h)
224
224
  Ib = 3 / 10 * m * r * r
225
225
 
226
- I = np.array([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
226
+ I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
227
227
 
228
- return (m, np.zeros(3), I)
228
+ return (m, wp.vec3(), I)
229
229
 
230
230
 
231
231
  def compute_box_inertia(density: float, w: float, h: float, d: float) -> tuple:
@@ -249,17 +249,16 @@ def compute_box_inertia(density: float, w: float, h: float, d: float) -> tuple:
249
249
  Ib = 1.0 / 12.0 * m * (w * w + d * d)
250
250
  Ic = 1.0 / 12.0 * m * (w * w + h * h)
251
251
 
252
- I = np.array([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ic]])
252
+ I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ic]])
253
253
 
254
- return (m, np.zeros(3), I)
254
+ return (m, wp.vec3(), I)
255
255
 
256
256
 
257
257
  def compute_mesh_inertia(
258
258
  density: float, vertices: list, indices: list, is_solid: bool = True, thickness: Union[List[float], float] = 0.001
259
259
  ) -> tuple:
260
260
  """Computes mass, center of mass, 3x3 inertia matrix, and volume for a mesh."""
261
- com = np.mean(vertices, 0)
262
- com_warp = wp.vec3(com[0], com[1], com[2])
261
+ com = wp.vec3(np.mean(vertices, 0))
263
262
 
264
263
  num_tris = len(indices) // 3
265
264
 
@@ -279,7 +278,7 @@ def compute_mesh_inertia(
279
278
  kernel=compute_solid_mesh_inertia,
280
279
  dim=num_tris,
281
280
  inputs=[
282
- com_warp,
281
+ com,
283
282
  weight,
284
283
  wp.array(indices, dtype=int),
285
284
  wp.array(vertices, dtype=wp.vec3),
@@ -294,7 +293,7 @@ def compute_mesh_inertia(
294
293
  kernel=compute_hollow_mesh_inertia,
295
294
  dim=num_tris,
296
295
  inputs=[
297
- com_warp,
296
+ com,
298
297
  weight,
299
298
  wp.array(indices, dtype=int),
300
299
  wp.array(vertices, dtype=wp.vec3),
@@ -304,14 +303,14 @@ def compute_mesh_inertia(
304
303
  )
305
304
 
306
305
  # Extract mass and inertia and save to class attributes.
307
- mass = mass_warp.numpy()[0] * density
308
- I = I_warp.numpy()[0] * density
306
+ mass = float(mass_warp.numpy()[0] * density)
307
+ I = wp.mat33(*(I_warp.numpy()[0] * density))
309
308
  volume = vol_warp.numpy()[0]
310
309
  return mass, com, I, volume
311
310
 
312
311
 
313
312
  def transform_inertia(m, I, p, q):
314
- R = np.array(wp.quat_to_matrix(q)).reshape(3, 3)
313
+ R = wp.quat_to_matrix(q)
315
314
 
316
315
  # Steiner's theorem
317
- return R @ I @ R.T + m * (np.dot(p, p) * np.eye(3) - np.outer(p, p))
316
+ return R @ I @ wp.transpose(R) + m * (wp.dot(p, p) * wp.mat33(np.eye(3)) - wp.outer(p, p))
@@ -12,11 +12,10 @@ models + state forward in time.
12
12
 
13
13
  import warp as wp
14
14
 
15
- from .model import PARTICLE_FLAG_ACTIVE, ModelShapeMaterials, ModelShapeGeometry
16
-
15
+ from .collide import triangle_closest_point_barycentric
16
+ from .model import PARTICLE_FLAG_ACTIVE, ModelShapeGeometry, ModelShapeMaterials
17
17
  from .optimizer import Optimizer
18
18
  from .particles import eval_particle_forces
19
- from .collide import triangle_closest_point_barycentric
20
19
  from .utils import quat_decompose, quat_twist
21
20
 
22
21
 
@@ -29,6 +28,7 @@ def integrate_particles(
29
28
  particle_flags: wp.array(dtype=wp.uint32),
30
29
  gravity: wp.vec3,
31
30
  dt: float,
31
+ v_max: float,
32
32
  x_new: wp.array(dtype=wp.vec3),
33
33
  v_new: wp.array(dtype=wp.vec3),
34
34
  ):
@@ -44,6 +44,10 @@ def integrate_particles(
44
44
 
45
45
  # simple semi-implicit Euler. v1 = v0 + a dt, x1 = x0 + v1 dt
46
46
  v1 = v0 + (f0 * inv_mass + gravity * wp.step(0.0 - inv_mass)) * dt
47
+ # enforce velocity limit to prevent instability
48
+ v1_mag = wp.length(v1)
49
+ if v1_mag > v_max:
50
+ v1 *= v_max / v1_mag
47
51
  x1 = x0 + v1 * dt
48
52
 
49
53
  x_new[tid] = x1
@@ -837,10 +841,10 @@ def eval_particle_ground_contacts(
837
841
  def eval_particle_contacts(
838
842
  particle_x: wp.array(dtype=wp.vec3),
839
843
  particle_v: wp.array(dtype=wp.vec3),
840
- particle_radius: wp.array(dtype=float),
841
- particle_flags: wp.array(dtype=wp.uint32),
842
844
  body_q: wp.array(dtype=wp.transform),
843
845
  body_qd: wp.array(dtype=wp.spatial_vector),
846
+ particle_radius: wp.array(dtype=float),
847
+ particle_flags: wp.array(dtype=wp.uint32),
844
848
  body_com: wp.array(dtype=wp.vec3),
845
849
  shape_body: wp.array(dtype=int),
846
850
  shape_materials: ModelShapeMaterials,
@@ -1664,10 +1668,10 @@ def compute_forces(model, state, particle_f, body_f, requires_grad):
1664
1668
  inputs=[
1665
1669
  state.particle_q,
1666
1670
  state.particle_qd,
1667
- model.particle_radius,
1668
- model.particle_flags,
1669
1671
  state.body_q,
1670
1672
  state.body_qd,
1673
+ model.particle_radius,
1674
+ model.particle_flags,
1671
1675
  model.body_com,
1672
1676
  model.shape_body,
1673
1677
  model.shape_materials,
@@ -1825,6 +1829,7 @@ class SemiImplicitIntegrator:
1825
1829
  model.particle_flags,
1826
1830
  model.gravity,
1827
1831
  dt,
1832
+ model.particle_max_velocity,
1828
1833
  ],
1829
1834
  outputs=[state_out.particle_q, state_out.particle_qd],
1830
1835
  device=model.device,
@@ -1913,6 +1918,7 @@ def init_state(model, state_in, state_out, dt):
1913
1918
  model.particle_flags,
1914
1919
  model.gravity,
1915
1920
  dt,
1921
+ model.particle_max_velocity,
1916
1922
  ],
1917
1923
  outputs=[state_out.particle_q, state_out.particle_qd],
1918
1924
  device=model.device,
@@ -1956,7 +1962,7 @@ class VariationalImplicitIntegrator:
1956
1962
  compute_forces(model, state_out, self.particle_f, None)
1957
1963
  compute_residual(model, state_in, state_out, self.particle_f, dfdx, dt)
1958
1964
 
1959
- # initialize oututput state using the input velocity to create 'predicted state'
1965
+ # initialize output state using the input velocity to create 'predicted state'
1960
1966
  init_state(model, state_in, state_out, dt)
1961
1967
 
1962
1968
  # our optimization variable