warp-lang 1.7.2rc1__py3-none-manylinux_2_34_aarch64.whl → 1.8.0__py3-none-manylinux_2_34_aarch64.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.
- warp/__init__.py +3 -1
- warp/__init__.pyi +3489 -1
- warp/autograd.py +45 -122
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +241 -252
- warp/build_dll.py +125 -26
- warp/builtins.py +1907 -384
- warp/codegen.py +257 -101
- warp/config.py +12 -1
- warp/constants.py +1 -1
- warp/context.py +657 -223
- warp/dlpack.py +1 -1
- warp/examples/benchmarks/benchmark_cloth.py +2 -2
- warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
- warp/examples/core/example_sample_mesh.py +1 -1
- warp/examples/core/example_spin_lock.py +93 -0
- warp/examples/core/example_work_queue.py +118 -0
- warp/examples/fem/example_adaptive_grid.py +5 -5
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_burgers.py +1 -1
- warp/examples/fem/example_convection_diffusion.py +9 -6
- warp/examples/fem/example_darcy_ls_optimization.py +489 -0
- warp/examples/fem/example_deformed_geometry.py +1 -1
- warp/examples/fem/example_diffusion.py +2 -2
- warp/examples/fem/example_diffusion_3d.py +1 -1
- warp/examples/fem/example_distortion_energy.py +1 -1
- warp/examples/fem/example_elastic_shape_optimization.py +387 -0
- warp/examples/fem/example_magnetostatics.py +5 -3
- warp/examples/fem/example_mixed_elasticity.py +5 -3
- warp/examples/fem/example_navier_stokes.py +11 -9
- warp/examples/fem/example_nonconforming_contact.py +5 -3
- warp/examples/fem/example_streamlines.py +8 -3
- warp/examples/fem/utils.py +9 -8
- warp/examples/interop/example_jax_ffi_callback.py +2 -2
- warp/examples/optim/example_drone.py +1 -1
- warp/examples/sim/example_cloth.py +1 -1
- warp/examples/sim/example_cloth_self_contact.py +48 -54
- warp/examples/tile/example_tile_block_cholesky.py +502 -0
- warp/examples/tile/example_tile_cholesky.py +2 -1
- warp/examples/tile/example_tile_convolution.py +1 -1
- warp/examples/tile/example_tile_filtering.py +1 -1
- warp/examples/tile/example_tile_matmul.py +1 -1
- warp/examples/tile/example_tile_mlp.py +2 -0
- warp/fabric.py +7 -7
- warp/fem/__init__.py +5 -0
- warp/fem/adaptivity.py +1 -1
- warp/fem/cache.py +152 -63
- warp/fem/dirichlet.py +2 -2
- warp/fem/domain.py +136 -6
- warp/fem/field/field.py +141 -99
- warp/fem/field/nodal_field.py +85 -39
- warp/fem/field/virtual.py +97 -52
- warp/fem/geometry/adaptive_nanogrid.py +91 -86
- warp/fem/geometry/closest_point.py +13 -0
- warp/fem/geometry/deformed_geometry.py +102 -40
- warp/fem/geometry/element.py +56 -2
- warp/fem/geometry/geometry.py +323 -22
- warp/fem/geometry/grid_2d.py +157 -62
- warp/fem/geometry/grid_3d.py +116 -20
- warp/fem/geometry/hexmesh.py +86 -20
- warp/fem/geometry/nanogrid.py +166 -86
- warp/fem/geometry/partition.py +59 -25
- warp/fem/geometry/quadmesh.py +86 -135
- warp/fem/geometry/tetmesh.py +47 -119
- warp/fem/geometry/trimesh.py +77 -270
- warp/fem/integrate.py +107 -52
- warp/fem/linalg.py +25 -58
- warp/fem/operator.py +124 -27
- warp/fem/quadrature/pic_quadrature.py +36 -14
- warp/fem/quadrature/quadrature.py +40 -16
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/basis_function_space.py +66 -46
- warp/fem/space/basis_space.py +17 -4
- warp/fem/space/dof_mapper.py +1 -1
- warp/fem/space/function_space.py +2 -2
- warp/fem/space/grid_2d_function_space.py +4 -1
- warp/fem/space/hexmesh_function_space.py +4 -2
- warp/fem/space/nanogrid_function_space.py +3 -1
- warp/fem/space/partition.py +11 -2
- warp/fem/space/quadmesh_function_space.py +4 -1
- warp/fem/space/restriction.py +5 -2
- warp/fem/space/shape/__init__.py +10 -8
- warp/fem/space/tetmesh_function_space.py +4 -1
- warp/fem/space/topology.py +52 -21
- warp/fem/space/trimesh_function_space.py +4 -1
- warp/fem/utils.py +53 -8
- warp/jax.py +1 -2
- warp/jax_experimental/ffi.py +12 -17
- warp/jax_experimental/xla_ffi.py +37 -24
- warp/math.py +171 -1
- warp/native/array.h +99 -0
- warp/native/builtin.h +174 -31
- warp/native/coloring.cpp +1 -1
- warp/native/exports.h +118 -63
- warp/native/intersect.h +3 -3
- warp/native/mat.h +5 -10
- warp/native/mathdx.cpp +11 -5
- warp/native/matnn.h +1 -123
- warp/native/quat.h +28 -4
- warp/native/sparse.cpp +121 -258
- warp/native/sparse.cu +181 -274
- warp/native/spatial.h +305 -17
- warp/native/tile.h +583 -72
- warp/native/tile_radix_sort.h +1108 -0
- warp/native/tile_reduce.h +237 -2
- warp/native/tile_scan.h +240 -0
- warp/native/tuple.h +189 -0
- warp/native/vec.h +6 -16
- warp/native/warp.cpp +36 -4
- warp/native/warp.cu +574 -51
- warp/native/warp.h +47 -74
- warp/optim/linear.py +5 -1
- warp/paddle.py +7 -8
- warp/py.typed +0 -0
- warp/render/render_opengl.py +58 -29
- warp/render/render_usd.py +124 -61
- warp/sim/__init__.py +9 -0
- warp/sim/collide.py +252 -78
- warp/sim/graph_coloring.py +8 -1
- warp/sim/import_mjcf.py +4 -3
- warp/sim/import_usd.py +11 -7
- warp/sim/integrator.py +5 -2
- warp/sim/integrator_euler.py +1 -1
- warp/sim/integrator_featherstone.py +1 -1
- warp/sim/integrator_vbd.py +751 -320
- warp/sim/integrator_xpbd.py +1 -1
- warp/sim/model.py +265 -260
- warp/sim/utils.py +10 -7
- warp/sparse.py +303 -166
- warp/tape.py +52 -51
- warp/tests/cuda/test_conditional_captures.py +1046 -0
- warp/tests/cuda/test_streams.py +1 -1
- warp/tests/geometry/test_volume.py +2 -2
- warp/tests/interop/test_dlpack.py +9 -9
- warp/tests/interop/test_jax.py +0 -1
- warp/tests/run_coverage_serial.py +1 -1
- warp/tests/sim/disabled_kinematics.py +2 -2
- warp/tests/sim/{test_vbd.py → test_cloth.py} +296 -113
- warp/tests/sim/test_collision.py +159 -51
- warp/tests/sim/test_coloring.py +15 -1
- warp/tests/test_array.py +254 -2
- warp/tests/test_array_reduce.py +2 -2
- warp/tests/test_atomic_cas.py +299 -0
- warp/tests/test_codegen.py +142 -19
- warp/tests/test_conditional.py +47 -1
- warp/tests/test_ctypes.py +0 -20
- warp/tests/test_devices.py +8 -0
- warp/tests/test_fabricarray.py +4 -2
- warp/tests/test_fem.py +58 -25
- warp/tests/test_func.py +42 -1
- warp/tests/test_grad.py +1 -1
- warp/tests/test_lerp.py +1 -3
- warp/tests/test_map.py +481 -0
- warp/tests/test_mat.py +1 -24
- warp/tests/test_quat.py +6 -15
- warp/tests/test_rounding.py +10 -38
- warp/tests/test_runlength_encode.py +7 -7
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +51 -2
- warp/tests/test_spatial.py +507 -1
- warp/tests/test_struct.py +2 -2
- warp/tests/test_tuple.py +265 -0
- warp/tests/test_types.py +2 -2
- warp/tests/test_utils.py +24 -18
- warp/tests/tile/test_tile.py +420 -1
- warp/tests/tile/test_tile_mathdx.py +518 -14
- warp/tests/tile/test_tile_reduce.py +213 -0
- warp/tests/tile/test_tile_shared_memory.py +130 -1
- warp/tests/tile/test_tile_sort.py +117 -0
- warp/tests/unittest_suites.py +4 -6
- warp/types.py +462 -308
- warp/utils.py +647 -86
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/METADATA +20 -6
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/RECORD +178 -166
- warp/stubs.py +0 -3381
- warp/tests/sim/test_xpbd.py +0 -399
- warp/tests/test_mlp.py +0 -282
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/top_level.txt +0 -0
warp/sim/collide.py
CHANGED
|
@@ -232,11 +232,11 @@ def box_sdf_grad(upper: wp.vec3, p: wp.vec3):
|
|
|
232
232
|
sz = wp.sign(p[2])
|
|
233
233
|
|
|
234
234
|
# x projection
|
|
235
|
-
if qx > qy and qx > qz or qy == 0.0 and qz == 0.0:
|
|
235
|
+
if (qx > qy and qx > qz) or (qy == 0.0 and qz == 0.0):
|
|
236
236
|
return wp.vec3(sx, 0.0, 0.0)
|
|
237
237
|
|
|
238
238
|
# y projection
|
|
239
|
-
if qy > qx and qy > qz or qx == 0.0 and qz == 0.0:
|
|
239
|
+
if (qy > qx and qy > qz) or (qx == 0.0 and qz == 0.0):
|
|
240
240
|
return wp.vec3(0.0, sy, 0.0)
|
|
241
241
|
|
|
242
242
|
# z projection
|
|
@@ -341,9 +341,9 @@ def closest_point_box(upper: wp.vec3, point: wp.vec3):
|
|
|
341
341
|
sy = wp.abs(wp.abs(point[1]) - upper[1])
|
|
342
342
|
sz = wp.abs(wp.abs(point[2]) - upper[2])
|
|
343
343
|
# return closest point on closest side, handle corner cases
|
|
344
|
-
if sx < sy and sx < sz or sy == 0.0 and sz == 0.0:
|
|
344
|
+
if (sx < sy and sx < sz) or (sy == 0.0 and sz == 0.0):
|
|
345
345
|
x = wp.sign(point[0]) * upper[0]
|
|
346
|
-
elif sy < sx and sy < sz or sx == 0.0 and sz == 0.0:
|
|
346
|
+
elif (sy < sx and sy < sz) or (sx == 0.0 and sz == 0.0):
|
|
347
347
|
y = wp.sign(point[1]) * upper[1]
|
|
348
348
|
else:
|
|
349
349
|
z = wp.sign(point[2]) * upper[2]
|
|
@@ -1516,11 +1516,8 @@ def handle_contact_pairs(
|
|
|
1516
1516
|
diff = p_a_world - p_b_world
|
|
1517
1517
|
|
|
1518
1518
|
# if the plane is infinite or the point is within the plane we fix the normal to prevent intersections
|
|
1519
|
-
if (
|
|
1520
|
-
geo_scale_b[0]
|
|
1521
|
-
and geo_scale_b[1] == 0.0
|
|
1522
|
-
or wp.abs(query_b[0]) < geo_scale_b[0]
|
|
1523
|
-
and wp.abs(query_b[2]) < geo_scale_b[1]
|
|
1519
|
+
if (geo_scale_b[0] == 0.0 and geo_scale_b[1] == 0.0) or (
|
|
1520
|
+
wp.abs(query_b[0]) < geo_scale_b[0] and wp.abs(query_b[2]) < geo_scale_b[1]
|
|
1524
1521
|
):
|
|
1525
1522
|
normal = wp.transform_vector(X_ws_b, wp.vec3(0.0, 1.0, 0.0))
|
|
1526
1523
|
distance = wp.dot(diff, normal)
|
|
@@ -1618,7 +1615,7 @@ def collide(
|
|
|
1618
1615
|
device=model.device,
|
|
1619
1616
|
)
|
|
1620
1617
|
|
|
1621
|
-
if model.shape_contact_pair_count or model.ground and model.shape_ground_contact_pair_count:
|
|
1618
|
+
if model.shape_contact_pair_count or (model.ground and model.shape_ground_contact_pair_count):
|
|
1622
1619
|
# clear old count
|
|
1623
1620
|
model.rigid_contact_count.zero_()
|
|
1624
1621
|
|
|
@@ -1683,7 +1680,7 @@ def collide(
|
|
|
1683
1680
|
record_tape=False,
|
|
1684
1681
|
)
|
|
1685
1682
|
|
|
1686
|
-
if model.shape_contact_pair_count or model.ground and model.shape_ground_contact_pair_count:
|
|
1683
|
+
if model.shape_contact_pair_count or (model.ground and model.shape_ground_contact_pair_count):
|
|
1687
1684
|
if requires_grad:
|
|
1688
1685
|
model.rigid_contact_point0 = wp.empty_like(model.rigid_contact_point0)
|
|
1689
1686
|
model.rigid_contact_point1 = wp.empty_like(model.rigid_contact_point1)
|
|
@@ -1850,7 +1847,7 @@ def vertex_triangle_collision_detection_kernel(
|
|
|
1850
1847
|
"""
|
|
1851
1848
|
This function applies discrete collision detection between vertices and triangles. It uses pre-allocated spaces to
|
|
1852
1849
|
record the collision data. This collision detector works both ways, i.e., it records vertices' colliding triangles to
|
|
1853
|
-
vertex_colliding_triangles
|
|
1850
|
+
`vertex_colliding_triangles`, and records each triangles colliding vertices to `triangle_colliding_vertices`.
|
|
1854
1851
|
|
|
1855
1852
|
This function assumes that all the vertices are on triangles, and can be indexed from the pos argument.
|
|
1856
1853
|
|
|
@@ -1870,7 +1867,8 @@ def vertex_triangle_collision_detection_kernel(
|
|
|
1870
1867
|
vertex_colliding_triangles_offsets (array): where each vertex' collision buffer starts
|
|
1871
1868
|
vertex_colliding_triangles_buffer_sizes (array): size of each vertex' collision buffer, will be modified if resizing is needed
|
|
1872
1869
|
vertex_colliding_triangles_min_dist (array): each vertex' min distance to all (non-neighbor) triangles
|
|
1873
|
-
triangle_colliding_vertices (array): positions of all the triangles' collision vertices
|
|
1870
|
+
triangle_colliding_vertices (array): positions of all the triangles' collision vertices, every two elements
|
|
1871
|
+
records the vertex index and a triangle index it collides to
|
|
1874
1872
|
triangle_colliding_vertices_count (array): number of triangles each vertex collides
|
|
1875
1873
|
triangle_colliding_vertices_offsets (array): where each triangle's collision buffer starts
|
|
1876
1874
|
triangle_colliding_vertices_buffer_sizes (array): size of each triangle's collision buffer, will be modified if resizing is needed
|
|
@@ -1880,6 +1878,8 @@ def vertex_triangle_collision_detection_kernel(
|
|
|
1880
1878
|
|
|
1881
1879
|
v_index = wp.tid()
|
|
1882
1880
|
v = pos[v_index]
|
|
1881
|
+
vertex_buffer_offset = vertex_colliding_triangles_offsets[v_index]
|
|
1882
|
+
vertex_buffer_size = vertex_colliding_triangles_offsets[v_index + 1] - vertex_buffer_offset
|
|
1883
1883
|
|
|
1884
1884
|
lower = wp.vec3(v[0] - query_radius, v[1] - query_radius, v[2] - query_radius)
|
|
1885
1885
|
upper = wp.vec3(v[0] + query_radius, v[1] + query_radius, v[2] + query_radius)
|
|
@@ -1905,13 +1905,11 @@ def vertex_triangle_collision_detection_kernel(
|
|
|
1905
1905
|
dist = wp.length(closest_p - v)
|
|
1906
1906
|
|
|
1907
1907
|
if dist < query_radius:
|
|
1908
|
-
vertex_buffer_offset = vertex_colliding_triangles_offsets[v_index]
|
|
1909
|
-
vertex_buffer_size = vertex_colliding_triangles_offsets[v_index + 1] - vertex_buffer_offset
|
|
1910
|
-
|
|
1911
1908
|
# record v-f collision to vertex
|
|
1912
1909
|
min_dis_to_tris = wp.min(min_dis_to_tris, dist)
|
|
1913
1910
|
if vertex_num_collisions < vertex_buffer_size:
|
|
1914
|
-
vertex_colliding_triangles[vertex_buffer_offset + vertex_num_collisions] =
|
|
1911
|
+
vertex_colliding_triangles[2 * (vertex_buffer_offset + vertex_num_collisions)] = v_index
|
|
1912
|
+
vertex_colliding_triangles[2 * (vertex_buffer_offset + vertex_num_collisions) + 1] = tri_index
|
|
1915
1913
|
else:
|
|
1916
1914
|
resize_flags[VERTEX_COLLISION_BUFFER_OVERFLOW_INDEX] = 1
|
|
1917
1915
|
|
|
@@ -1932,6 +1930,94 @@ def vertex_triangle_collision_detection_kernel(
|
|
|
1932
1930
|
vertex_colliding_triangles_min_dist[v_index] = min_dis_to_tris
|
|
1933
1931
|
|
|
1934
1932
|
|
|
1933
|
+
@wp.kernel
|
|
1934
|
+
def vertex_triangle_collision_detection_no_triangle_buffers_kernel(
|
|
1935
|
+
query_radius: float,
|
|
1936
|
+
bvh_id: wp.uint64,
|
|
1937
|
+
pos: wp.array(dtype=wp.vec3),
|
|
1938
|
+
tri_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1939
|
+
vertex_colliding_triangles_offsets: wp.array(dtype=wp.int32),
|
|
1940
|
+
vertex_colliding_triangles_buffer_sizes: wp.array(dtype=wp.int32),
|
|
1941
|
+
# outputs
|
|
1942
|
+
vertex_colliding_triangles: wp.array(dtype=wp.int32),
|
|
1943
|
+
vertex_colliding_triangles_count: wp.array(dtype=wp.int32),
|
|
1944
|
+
vertex_colliding_triangles_min_dist: wp.array(dtype=float),
|
|
1945
|
+
triangle_colliding_vertices_min_dist: wp.array(dtype=float),
|
|
1946
|
+
resize_flags: wp.array(dtype=wp.int32),
|
|
1947
|
+
):
|
|
1948
|
+
"""
|
|
1949
|
+
This function applies discrete collision detection between vertices and triangles. It uses pre-allocated spaces to
|
|
1950
|
+
record the collision data. Unlike `vertex_triangle_collision_detection_kernel`, this collision detection kernel
|
|
1951
|
+
works only in one way, i.e., it only records vertices' colliding triangles to `vertex_colliding_triangles`.
|
|
1952
|
+
|
|
1953
|
+
This function assumes that all the vertices are on triangles, and can be indexed from the pos argument.
|
|
1954
|
+
|
|
1955
|
+
Note:
|
|
1956
|
+
|
|
1957
|
+
The collision date buffer is pre-allocated and cannot be changed during collision detection, therefore, the space
|
|
1958
|
+
may not be enough. If the space is not enough to record all the collision information, the function will set a
|
|
1959
|
+
certain element in resized_flag to be true. The user can reallocate the buffer based on vertex_colliding_triangles_count
|
|
1960
|
+
and vertex_colliding_triangles_count.
|
|
1961
|
+
|
|
1962
|
+
Attributes:
|
|
1963
|
+
bvh_id (int): the bvh id you want to collide with
|
|
1964
|
+
query_radius (float): the contact radius. vertex-triangle pairs whose distance are less than this will get detected
|
|
1965
|
+
pos (array): positions of all the vertices that make up triangles
|
|
1966
|
+
vertex_colliding_triangles (array): flattened buffer of vertices' collision triangles, every two elements records
|
|
1967
|
+
the vertex index and a triangle index it collides to
|
|
1968
|
+
vertex_colliding_triangles_count (array): number of triangles each vertex collides
|
|
1969
|
+
vertex_colliding_triangles_offsets (array): where each vertex' collision buffer starts
|
|
1970
|
+
vertex_colliding_triangles_buffer_sizes (array): size of each vertex' collision buffer, will be modified if resizing is needed
|
|
1971
|
+
vertex_colliding_triangles_min_dist (array): each vertex' min distance to all (non-neighbor) triangles
|
|
1972
|
+
triangle_colliding_vertices_min_dist (array): each triangle's min distance to all (non-self) vertices
|
|
1973
|
+
resized_flag (array): size == 3, (vertex_buffer_resize_required, triangle_buffer_resize_required, edge_buffer_resize_required)
|
|
1974
|
+
"""
|
|
1975
|
+
|
|
1976
|
+
v_index = wp.tid()
|
|
1977
|
+
v = pos[v_index]
|
|
1978
|
+
vertex_buffer_offset = vertex_colliding_triangles_offsets[v_index]
|
|
1979
|
+
vertex_buffer_size = vertex_colliding_triangles_offsets[v_index + 1] - vertex_buffer_offset
|
|
1980
|
+
|
|
1981
|
+
lower = wp.vec3(v[0] - query_radius, v[1] - query_radius, v[2] - query_radius)
|
|
1982
|
+
upper = wp.vec3(v[0] + query_radius, v[1] + query_radius, v[2] + query_radius)
|
|
1983
|
+
|
|
1984
|
+
query = wp.bvh_query_aabb(bvh_id, lower, upper)
|
|
1985
|
+
|
|
1986
|
+
tri_index = wp.int32(0)
|
|
1987
|
+
vertex_num_collisions = wp.int32(0)
|
|
1988
|
+
min_dis_to_tris = query_radius
|
|
1989
|
+
while wp.bvh_query_next(query, tri_index):
|
|
1990
|
+
t1 = tri_indices[tri_index, 0]
|
|
1991
|
+
t2 = tri_indices[tri_index, 1]
|
|
1992
|
+
t3 = tri_indices[tri_index, 2]
|
|
1993
|
+
if vertex_adjacent_to_triangle(v_index, t1, t2, t3):
|
|
1994
|
+
continue
|
|
1995
|
+
|
|
1996
|
+
u1 = pos[t1]
|
|
1997
|
+
u2 = pos[t2]
|
|
1998
|
+
u3 = pos[t3]
|
|
1999
|
+
|
|
2000
|
+
closest_p, bary, feature_type = triangle_closest_point(u1, u2, u3, v)
|
|
2001
|
+
|
|
2002
|
+
dist = wp.length(closest_p - v)
|
|
2003
|
+
|
|
2004
|
+
if dist < query_radius:
|
|
2005
|
+
# record v-f collision to vertex
|
|
2006
|
+
min_dis_to_tris = wp.min(min_dis_to_tris, dist)
|
|
2007
|
+
if vertex_num_collisions < vertex_buffer_size:
|
|
2008
|
+
vertex_colliding_triangles[2 * (vertex_buffer_offset + vertex_num_collisions)] = v_index
|
|
2009
|
+
vertex_colliding_triangles[2 * (vertex_buffer_offset + vertex_num_collisions) + 1] = tri_index
|
|
2010
|
+
else:
|
|
2011
|
+
resize_flags[VERTEX_COLLISION_BUFFER_OVERFLOW_INDEX] = 1
|
|
2012
|
+
|
|
2013
|
+
vertex_num_collisions = vertex_num_collisions + 1
|
|
2014
|
+
|
|
2015
|
+
wp.atomic_min(triangle_colliding_vertices_min_dist, tri_index, dist)
|
|
2016
|
+
|
|
2017
|
+
vertex_colliding_triangles_count[v_index] = vertex_num_collisions
|
|
2018
|
+
vertex_colliding_triangles_min_dist[v_index] = min_dis_to_tris
|
|
2019
|
+
|
|
2020
|
+
|
|
1935
2021
|
@wp.kernel
|
|
1936
2022
|
def edge_colliding_edges_detection_kernel(
|
|
1937
2023
|
query_radius: float,
|
|
@@ -2001,7 +2087,8 @@ def edge_colliding_edges_detection_kernel(
|
|
|
2001
2087
|
# record e-e collision to e0, and leave e1; e1 will detect this collision from its own thread
|
|
2002
2088
|
min_dis_to_edges = wp.min(min_dis_to_edges, dist)
|
|
2003
2089
|
if edge_num_collisions < edge_buffer_size:
|
|
2004
|
-
edge_colliding_edges[edge_buffer_offset + edge_num_collisions] =
|
|
2090
|
+
edge_colliding_edges[2 * (edge_buffer_offset + edge_num_collisions)] = e_index
|
|
2091
|
+
edge_colliding_edges[2 * (edge_buffer_offset + edge_num_collisions) + 1] = colliding_edge_index
|
|
2005
2092
|
else:
|
|
2006
2093
|
resize_flags[EDGE_COLLISION_BUFFER_OVERFLOW_INDEX] = 1
|
|
2007
2094
|
|
|
@@ -2068,6 +2155,9 @@ def triangle_triangle_collision_detection_kernel(
|
|
|
2068
2155
|
|
|
2069
2156
|
@wp.struct
|
|
2070
2157
|
class TriMeshCollisionInfo:
|
|
2158
|
+
vertex_indices: wp.array(dtype=wp.int32)
|
|
2159
|
+
# size: 2 x sum(vertex_colliding_triangles_buffer_sizes)
|
|
2160
|
+
# every two elements records the vertex index and a triangle index it collides to
|
|
2071
2161
|
vertex_colliding_triangles: wp.array(dtype=wp.int32)
|
|
2072
2162
|
vertex_colliding_triangles_offsets: wp.array(dtype=wp.int32)
|
|
2073
2163
|
vertex_colliding_triangles_buffer_sizes: wp.array(dtype=wp.int32)
|
|
@@ -2080,6 +2170,8 @@ class TriMeshCollisionInfo:
|
|
|
2080
2170
|
triangle_colliding_vertices_count: wp.array(dtype=wp.int32)
|
|
2081
2171
|
triangle_colliding_vertices_min_dist: wp.array(dtype=float)
|
|
2082
2172
|
|
|
2173
|
+
# size: 2 x sum(edge_colliding_edges_buffer_sizes)
|
|
2174
|
+
# every two elements records the edge index and an edge index it collides to
|
|
2083
2175
|
edge_colliding_edges: wp.array(dtype=wp.int32)
|
|
2084
2176
|
edge_colliding_edges_offsets: wp.array(dtype=wp.int32)
|
|
2085
2177
|
edge_colliding_edges_buffer_sizes: wp.array(dtype=wp.int32)
|
|
@@ -2095,7 +2187,13 @@ def get_vertex_colliding_triangles_count(col_info: TriMeshCollisionInfo, v: int)
|
|
|
2095
2187
|
@wp.func
|
|
2096
2188
|
def get_vertex_colliding_triangles(col_info: TriMeshCollisionInfo, v: int, i_collision: int):
|
|
2097
2189
|
offset = col_info.vertex_colliding_triangles_offsets[v]
|
|
2098
|
-
return col_info.vertex_colliding_triangles[offset + i_collision]
|
|
2190
|
+
return col_info.vertex_colliding_triangles[2 * (offset + i_collision) + 1]
|
|
2191
|
+
|
|
2192
|
+
|
|
2193
|
+
@wp.func
|
|
2194
|
+
def get_vertex_collision_buffer_vertex_index(col_info: TriMeshCollisionInfo, v: int, i_collision: int):
|
|
2195
|
+
offset = col_info.vertex_colliding_triangles_offsets[v]
|
|
2196
|
+
return col_info.vertex_colliding_triangles[2 * (offset + i_collision)]
|
|
2099
2197
|
|
|
2100
2198
|
|
|
2101
2199
|
@wp.func
|
|
@@ -2119,13 +2217,20 @@ def get_edge_colliding_edges_count(col_info: TriMeshCollisionInfo, e: int):
|
|
|
2119
2217
|
@wp.func
|
|
2120
2218
|
def get_edge_colliding_edges(col_info: TriMeshCollisionInfo, e: int, i_collision: int):
|
|
2121
2219
|
offset = col_info.edge_colliding_edges_offsets[e]
|
|
2122
|
-
return col_info.edge_colliding_edges[offset + i_collision]
|
|
2220
|
+
return col_info.edge_colliding_edges[2 * (offset + i_collision) + 1]
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
@wp.func
|
|
2224
|
+
def get_edge_collision_buffer_edge_index(col_info: TriMeshCollisionInfo, e: int, i_collision: int):
|
|
2225
|
+
offset = col_info.edge_colliding_edges_offsets[e]
|
|
2226
|
+
return col_info.edge_colliding_edges[2 * (offset + i_collision)]
|
|
2123
2227
|
|
|
2124
2228
|
|
|
2125
2229
|
class TriMeshCollisionDetector:
|
|
2126
2230
|
def __init__(
|
|
2127
2231
|
self,
|
|
2128
2232
|
model: Model,
|
|
2233
|
+
record_triangle_contacting_vertices=False,
|
|
2129
2234
|
vertex_positions=None,
|
|
2130
2235
|
vertex_collision_buffer_pre_alloc=8,
|
|
2131
2236
|
vertex_collision_buffer_max_alloc=256,
|
|
@@ -2138,6 +2243,7 @@ class TriMeshCollisionDetector:
|
|
|
2138
2243
|
edge_edge_parallel_epsilon=1e-5,
|
|
2139
2244
|
):
|
|
2140
2245
|
self.model = model
|
|
2246
|
+
self.record_triangle_contacting_vertices = record_triangle_contacting_vertices
|
|
2141
2247
|
self.vertex_positions = model.particle_q if vertex_positions is None else vertex_positions
|
|
2142
2248
|
self.device = model.device
|
|
2143
2249
|
self.vertex_collision_buffer_pre_alloc = vertex_collision_buffer_pre_alloc
|
|
@@ -2166,7 +2272,9 @@ class TriMeshCollisionDetector:
|
|
|
2166
2272
|
|
|
2167
2273
|
# vertex collision buffers
|
|
2168
2274
|
self.vertex_colliding_triangles = wp.zeros(
|
|
2169
|
-
shape=(model.particle_count * self.vertex_collision_buffer_pre_alloc,),
|
|
2275
|
+
shape=(2 * model.particle_count * self.vertex_collision_buffer_pre_alloc,),
|
|
2276
|
+
dtype=wp.int32,
|
|
2277
|
+
device=self.device,
|
|
2170
2278
|
)
|
|
2171
2279
|
self.vertex_colliding_triangles_count = wp.array(
|
|
2172
2280
|
shape=(model.particle_count,), dtype=wp.int32, device=self.device
|
|
@@ -2187,26 +2295,39 @@ class TriMeshCollisionDetector:
|
|
|
2187
2295
|
self.vertex_colliding_triangles_buffer_sizes, self.vertex_colliding_triangles_offsets
|
|
2188
2296
|
)
|
|
2189
2297
|
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2298
|
+
if record_triangle_contacting_vertices:
|
|
2299
|
+
# triangle collision buffers
|
|
2300
|
+
self.triangle_colliding_vertices = wp.zeros(
|
|
2301
|
+
shape=(model.tri_count * self.triangle_collision_buffer_pre_alloc,), dtype=wp.int32, device=self.device
|
|
2302
|
+
)
|
|
2303
|
+
self.triangle_colliding_vertices_count = wp.zeros(
|
|
2304
|
+
shape=(model.tri_count,), dtype=wp.int32, device=self.device
|
|
2305
|
+
)
|
|
2306
|
+
self.triangle_colliding_vertices_buffer_sizes = wp.full(
|
|
2307
|
+
shape=(model.tri_count,),
|
|
2308
|
+
value=self.triangle_collision_buffer_pre_alloc,
|
|
2309
|
+
dtype=wp.int32,
|
|
2310
|
+
device=self.device,
|
|
2311
|
+
)
|
|
2199
2312
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2313
|
+
self.triangle_colliding_vertices_offsets = wp.array(
|
|
2314
|
+
shape=(model.tri_count + 1,), dtype=wp.int32, device=self.device
|
|
2315
|
+
)
|
|
2316
|
+
self.compute_collision_buffer_offsets(
|
|
2317
|
+
self.triangle_colliding_vertices_buffer_sizes, self.triangle_colliding_vertices_offsets
|
|
2318
|
+
)
|
|
2319
|
+
else:
|
|
2320
|
+
self.triangle_colliding_vertices = None
|
|
2321
|
+
self.triangle_colliding_vertices_count = None
|
|
2322
|
+
self.triangle_colliding_vertices_buffer_sizes = None
|
|
2323
|
+
self.triangle_colliding_vertices_offsets = None
|
|
2324
|
+
|
|
2325
|
+
# this is need regardless of whether we record triangle contacting vertices
|
|
2326
|
+
self.triangle_colliding_vertices_min_dist = wp.array(shape=(model.tri_count,), dtype=float, device=self.device)
|
|
2206
2327
|
|
|
2207
2328
|
# edge collision buffers
|
|
2208
2329
|
self.edge_colliding_edges = wp.zeros(
|
|
2209
|
-
shape=(model.edge_count * self.edge_collision_buffer_pre_alloc,), dtype=wp.int32, device=self.device
|
|
2330
|
+
shape=(2 * model.edge_count * self.edge_collision_buffer_pre_alloc,), dtype=wp.int32, device=self.device
|
|
2210
2331
|
)
|
|
2211
2332
|
self.edge_colliding_edges_count = wp.zeros(shape=(model.edge_count,), dtype=wp.int32, device=self.device)
|
|
2212
2333
|
self.edge_colliding_edges_buffer_sizes = wp.full(
|
|
@@ -2248,10 +2369,12 @@ class TriMeshCollisionDetector:
|
|
|
2248
2369
|
collision_info.vertex_colliding_triangles_count = self.vertex_colliding_triangles_count
|
|
2249
2370
|
collision_info.vertex_colliding_triangles_min_dist = self.vertex_colliding_triangles_min_dist
|
|
2250
2371
|
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2372
|
+
if self.record_triangle_contacting_vertices:
|
|
2373
|
+
collision_info.triangle_colliding_vertices = self.triangle_colliding_vertices
|
|
2374
|
+
collision_info.triangle_colliding_vertices_offsets = self.triangle_colliding_vertices_offsets
|
|
2375
|
+
collision_info.triangle_colliding_vertices_buffer_sizes = self.triangle_colliding_vertices_buffer_sizes
|
|
2376
|
+
collision_info.triangle_colliding_vertices_count = self.triangle_colliding_vertices_count
|
|
2377
|
+
|
|
2255
2378
|
collision_info.triangle_colliding_vertices_min_dist = self.triangle_colliding_vertices_min_dist
|
|
2256
2379
|
|
|
2257
2380
|
collision_info.edge_colliding_edges = self.edge_colliding_edges
|
|
@@ -2272,6 +2395,31 @@ class TriMeshCollisionDetector:
|
|
|
2272
2395
|
|
|
2273
2396
|
offsets.assign(offsets_np)
|
|
2274
2397
|
|
|
2398
|
+
def rebuild(self, new_pos=None):
|
|
2399
|
+
if new_pos is not None:
|
|
2400
|
+
self.vertex_positions = new_pos
|
|
2401
|
+
|
|
2402
|
+
wp.launch(
|
|
2403
|
+
kernel=compute_tri_aabbs,
|
|
2404
|
+
inputs=[
|
|
2405
|
+
self.vertex_positions,
|
|
2406
|
+
self.model.tri_indices,
|
|
2407
|
+
],
|
|
2408
|
+
outputs=[self.lower_bounds_tris, self.upper_bounds_tris],
|
|
2409
|
+
dim=self.model.tri_count,
|
|
2410
|
+
device=self.model.device,
|
|
2411
|
+
)
|
|
2412
|
+
self.bvh_tris = wp.Bvh(self.lower_bounds_tris, self.upper_bounds_tris)
|
|
2413
|
+
|
|
2414
|
+
wp.launch(
|
|
2415
|
+
kernel=compute_edge_aabbs,
|
|
2416
|
+
inputs=[self.vertex_positions, self.model.edge_indices],
|
|
2417
|
+
outputs=[self.lower_bounds_edges, self.upper_bounds_edges],
|
|
2418
|
+
dim=self.model.edge_count,
|
|
2419
|
+
device=self.model.device,
|
|
2420
|
+
)
|
|
2421
|
+
self.bvh_edges = wp.Bvh(self.lower_bounds_edges, self.upper_bounds_edges)
|
|
2422
|
+
|
|
2275
2423
|
def refit(self, new_pos=None):
|
|
2276
2424
|
if new_pos is not None:
|
|
2277
2425
|
self.vertex_positions = new_pos
|
|
@@ -2298,46 +2446,72 @@ class TriMeshCollisionDetector:
|
|
|
2298
2446
|
self.bvh_edges.refit()
|
|
2299
2447
|
|
|
2300
2448
|
def vertex_triangle_collision_detection(self, query_radius):
|
|
2301
|
-
|
|
2302
|
-
kernel=init_triangle_collision_data_kernel,
|
|
2303
|
-
inputs=[
|
|
2304
|
-
query_radius,
|
|
2305
|
-
],
|
|
2306
|
-
outputs=[
|
|
2307
|
-
self.triangle_colliding_vertices_count,
|
|
2308
|
-
self.triangle_colliding_vertices_min_dist,
|
|
2309
|
-
self.resize_flags,
|
|
2310
|
-
],
|
|
2311
|
-
dim=self.model.tri_count,
|
|
2312
|
-
device=self.model.device,
|
|
2313
|
-
)
|
|
2449
|
+
self.vertex_colliding_triangles.fill_(-1)
|
|
2314
2450
|
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2451
|
+
if self.record_triangle_contacting_vertices:
|
|
2452
|
+
wp.launch(
|
|
2453
|
+
kernel=init_triangle_collision_data_kernel,
|
|
2454
|
+
inputs=[
|
|
2455
|
+
query_radius,
|
|
2456
|
+
],
|
|
2457
|
+
outputs=[
|
|
2458
|
+
self.triangle_colliding_vertices_count,
|
|
2459
|
+
self.triangle_colliding_vertices_min_dist,
|
|
2460
|
+
self.resize_flags,
|
|
2461
|
+
],
|
|
2462
|
+
dim=self.model.tri_count,
|
|
2463
|
+
device=self.model.device,
|
|
2464
|
+
)
|
|
2465
|
+
|
|
2466
|
+
wp.launch(
|
|
2467
|
+
kernel=vertex_triangle_collision_detection_kernel,
|
|
2468
|
+
inputs=[
|
|
2469
|
+
query_radius,
|
|
2470
|
+
self.bvh_tris.id,
|
|
2471
|
+
self.vertex_positions,
|
|
2472
|
+
self.model.tri_indices,
|
|
2473
|
+
self.vertex_colliding_triangles_offsets,
|
|
2474
|
+
self.vertex_colliding_triangles_buffer_sizes,
|
|
2475
|
+
self.triangle_colliding_vertices_offsets,
|
|
2476
|
+
self.triangle_colliding_vertices_buffer_sizes,
|
|
2477
|
+
],
|
|
2478
|
+
outputs=[
|
|
2479
|
+
self.vertex_colliding_triangles,
|
|
2480
|
+
self.vertex_colliding_triangles_count,
|
|
2481
|
+
self.vertex_colliding_triangles_min_dist,
|
|
2482
|
+
self.triangle_colliding_vertices,
|
|
2483
|
+
self.triangle_colliding_vertices_count,
|
|
2484
|
+
self.triangle_colliding_vertices_min_dist,
|
|
2485
|
+
self.resize_flags,
|
|
2486
|
+
],
|
|
2487
|
+
dim=self.model.particle_count,
|
|
2488
|
+
device=self.model.device,
|
|
2489
|
+
)
|
|
2490
|
+
else:
|
|
2491
|
+
self.triangle_colliding_vertices_min_dist.fill_(query_radius)
|
|
2492
|
+
wp.launch(
|
|
2493
|
+
kernel=vertex_triangle_collision_detection_no_triangle_buffers_kernel,
|
|
2494
|
+
inputs=[
|
|
2495
|
+
query_radius,
|
|
2496
|
+
self.bvh_tris.id,
|
|
2497
|
+
self.vertex_positions,
|
|
2498
|
+
self.model.tri_indices,
|
|
2499
|
+
self.vertex_colliding_triangles_offsets,
|
|
2500
|
+
self.vertex_colliding_triangles_buffer_sizes,
|
|
2501
|
+
],
|
|
2502
|
+
outputs=[
|
|
2503
|
+
self.vertex_colliding_triangles,
|
|
2504
|
+
self.vertex_colliding_triangles_count,
|
|
2505
|
+
self.vertex_colliding_triangles_min_dist,
|
|
2506
|
+
self.triangle_colliding_vertices_min_dist,
|
|
2507
|
+
self.resize_flags,
|
|
2508
|
+
],
|
|
2509
|
+
dim=self.model.particle_count,
|
|
2510
|
+
device=self.model.device,
|
|
2511
|
+
)
|
|
2339
2512
|
|
|
2340
2513
|
def edge_edge_collision_detection(self, query_radius):
|
|
2514
|
+
self.edge_colliding_edges.fill_(-1)
|
|
2341
2515
|
wp.launch(
|
|
2342
2516
|
kernel=edge_colliding_edges_detection_kernel,
|
|
2343
2517
|
inputs=[
|
warp/sim/graph_coloring.py
CHANGED
|
@@ -178,6 +178,13 @@ def color_trimesh(
|
|
|
178
178
|
algorithm: the parameter passed to `color_graph`, see `color_graph`'s document
|
|
179
179
|
|
|
180
180
|
"""
|
|
181
|
+
if num_nodes == 0:
|
|
182
|
+
return []
|
|
183
|
+
|
|
184
|
+
if trimesh_edge_indices.shape[0] == 0:
|
|
185
|
+
# no edge, all the particle can have same color
|
|
186
|
+
return [np.arange(0, num_nodes, dtype=int)]
|
|
187
|
+
|
|
181
188
|
if include_bending_energy:
|
|
182
189
|
graph_edge_indices = construct_trimesh_graph_edges(trimesh_edge_indices, return_wp_array=True)
|
|
183
190
|
else:
|
|
@@ -218,7 +225,7 @@ def color_graph(
|
|
|
218
225
|
Ordered Greedy: Ton-That, Q. M., Kry, P. G., & Andrews, S. (2023). Parallel block Neo-Hookean XPBD using graph clustering. Computers & Graphics, 110, 1-10.
|
|
219
226
|
"""
|
|
220
227
|
if num_nodes == 0:
|
|
221
|
-
return
|
|
228
|
+
return []
|
|
222
229
|
|
|
223
230
|
particle_colors = wp.empty(shape=(num_nodes), dtype=wp.int32, device="cpu")
|
|
224
231
|
|
warp/sim/import_mjcf.py
CHANGED
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
import math
|
|
17
19
|
import os
|
|
18
20
|
import re
|
|
19
21
|
import xml.etree.ElementTree as ET
|
|
20
|
-
from typing import Union
|
|
21
22
|
|
|
22
23
|
import numpy as np
|
|
23
24
|
|
|
@@ -30,7 +31,7 @@ def parse_mjcf(
|
|
|
30
31
|
builder,
|
|
31
32
|
xform=None,
|
|
32
33
|
floating=False,
|
|
33
|
-
base_joint:
|
|
34
|
+
base_joint: dict | str | None = None,
|
|
34
35
|
density=1000.0,
|
|
35
36
|
stiffness=100.0,
|
|
36
37
|
damping=10.0,
|
|
@@ -447,7 +448,7 @@ def parse_mjcf(
|
|
|
447
448
|
|
|
448
449
|
return shapes
|
|
449
450
|
|
|
450
|
-
def parse_body(body, parent, incoming_defaults: dict, childclass: str = None):
|
|
451
|
+
def parse_body(body, parent, incoming_defaults: dict, childclass: str | None = None):
|
|
451
452
|
body_class = body.get("class")
|
|
452
453
|
if body_class is None:
|
|
453
454
|
body_class = childclass
|
warp/sim/import_usd.py
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
import re
|
|
17
19
|
|
|
18
20
|
import numpy as np
|
|
@@ -810,17 +812,19 @@ def parse_usd(
|
|
|
810
812
|
}
|
|
811
813
|
|
|
812
814
|
|
|
813
|
-
def resolve_usd_from_url(url: str, target_folder_name: str = None, export_usda: bool = False):
|
|
814
|
-
"""
|
|
815
|
-
Downloads a USD file from a URL and resolves all references to other USD files to be downloaded to the given target folder.
|
|
815
|
+
def resolve_usd_from_url(url: str, target_folder_name: str | None = None, export_usda: bool = False) -> str:
|
|
816
|
+
"""Download a USD file from a URL and resolves all references to other USD files to be downloaded to the given target folder.
|
|
816
817
|
|
|
817
818
|
Args:
|
|
818
|
-
url
|
|
819
|
-
target_folder_name
|
|
820
|
-
|
|
819
|
+
url: URL to the USD file.
|
|
820
|
+
target_folder_name: Target folder name. If ``None``, a time-stamped
|
|
821
|
+
folder will be created in the current directory.
|
|
822
|
+
export_usda: If ``True``, converts each downloaded USD file to USDA and
|
|
823
|
+
saves the additional USDA file in the target folder with the same
|
|
824
|
+
base name as the original USD file.
|
|
821
825
|
|
|
822
826
|
Returns:
|
|
823
|
-
|
|
827
|
+
File path to the downloaded USD file.
|
|
824
828
|
"""
|
|
825
829
|
import datetime
|
|
826
830
|
import os
|
warp/sim/integrator.py
CHANGED
|
@@ -32,11 +32,14 @@ def integrate_particles(
|
|
|
32
32
|
v_new: wp.array(dtype=wp.vec3),
|
|
33
33
|
):
|
|
34
34
|
tid = wp.tid()
|
|
35
|
+
x0 = x[tid]
|
|
36
|
+
v0 = v[tid]
|
|
37
|
+
|
|
35
38
|
if (particle_flags[tid] & PARTICLE_FLAG_ACTIVE) == 0:
|
|
39
|
+
x_new[tid] = x0
|
|
40
|
+
v_new[tid] = wp.vec3(0.0)
|
|
36
41
|
return
|
|
37
42
|
|
|
38
|
-
x0 = x[tid]
|
|
39
|
-
v0 = v[tid]
|
|
40
43
|
f0 = f[tid]
|
|
41
44
|
|
|
42
45
|
inv_mass = w[tid]
|
warp/sim/integrator_euler.py
CHANGED
|
@@ -1781,7 +1781,7 @@ def eval_tetrahedral_forces(model: Model, state: State, control: Control, partic
|
|
|
1781
1781
|
|
|
1782
1782
|
def eval_body_contact_forces(model: Model, state: State, particle_f: wp.array, friction_smoothing: float = 1.0):
|
|
1783
1783
|
if model.rigid_contact_max and (
|
|
1784
|
-
model.ground and model.shape_ground_contact_pair_count or model.shape_contact_pair_count
|
|
1784
|
+
(model.ground and model.shape_ground_contact_pair_count) or model.shape_contact_pair_count
|
|
1785
1785
|
):
|
|
1786
1786
|
wp.launch(
|
|
1787
1787
|
kernel=eval_rigid_contacts,
|
|
@@ -1825,7 +1825,7 @@ class FeatherstoneIntegrator(Integrator):
|
|
|
1825
1825
|
)
|
|
1826
1826
|
|
|
1827
1827
|
if model.rigid_contact_max and (
|
|
1828
|
-
model.ground and model.shape_ground_contact_pair_count or model.shape_contact_pair_count
|
|
1828
|
+
(model.ground and model.shape_ground_contact_pair_count) or model.shape_contact_pair_count
|
|
1829
1829
|
):
|
|
1830
1830
|
wp.launch(
|
|
1831
1831
|
kernel=eval_rigid_contacts,
|