warp-lang 1.0.0b5__py3-none-macosx_10_13_universal2.whl → 1.0.0b6__py3-none-macosx_10_13_universal2.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.
- docs/conf.py +3 -4
- examples/env/env_ant.py +1 -1
- examples/env/env_cartpole.py +1 -1
- examples/env/env_humanoid.py +1 -1
- examples/example_dem.py +28 -26
- examples/example_diffray.py +37 -30
- examples/example_fluid.py +7 -3
- examples/example_jacobian_ik.py +1 -1
- examples/example_mesh_intersect.py +10 -7
- examples/example_nvdb.py +3 -3
- examples/example_render_opengl.py +19 -10
- examples/example_sim_cartpole.py +9 -5
- examples/example_sim_cloth.py +29 -25
- examples/example_sim_fk_grad.py +2 -2
- examples/example_sim_fk_grad_torch.py +3 -3
- examples/example_sim_grad_bounce.py +11 -8
- examples/example_sim_grad_cloth.py +12 -9
- examples/example_sim_granular.py +2 -2
- examples/example_sim_granular_collision_sdf.py +13 -13
- examples/example_sim_neo_hookean.py +3 -3
- examples/example_sim_particle_chain.py +2 -2
- examples/example_sim_quadruped.py +8 -5
- examples/example_sim_rigid_chain.py +8 -5
- examples/example_sim_rigid_contact.py +13 -10
- examples/example_sim_rigid_fem.py +2 -2
- examples/example_sim_rigid_gyroscopic.py +2 -2
- examples/example_sim_rigid_kinematics.py +1 -1
- examples/example_sim_trajopt.py +3 -2
- examples/fem/example_apic_fluid.py +5 -7
- examples/fem/example_diffusion_mgpu.py +18 -16
- warp/__init__.py +3 -2
- warp/bin/libwarp-clang.dylib +0 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build_dll.py +29 -9
- warp/builtins.py +206 -7
- warp/codegen.py +58 -38
- warp/config.py +3 -1
- warp/context.py +234 -128
- warp/fem/__init__.py +2 -2
- warp/fem/cache.py +2 -1
- warp/fem/field/nodal_field.py +18 -17
- warp/fem/geometry/hexmesh.py +11 -6
- warp/fem/geometry/quadmesh_2d.py +16 -12
- warp/fem/geometry/tetmesh.py +19 -8
- warp/fem/geometry/trimesh_2d.py +18 -7
- warp/fem/integrate.py +341 -196
- warp/fem/quadrature/__init__.py +1 -1
- warp/fem/quadrature/pic_quadrature.py +138 -53
- warp/fem/quadrature/quadrature.py +81 -9
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/basis_space.py +169 -51
- warp/fem/space/grid_2d_function_space.py +2 -2
- warp/fem/space/grid_3d_function_space.py +2 -2
- warp/fem/space/hexmesh_function_space.py +2 -2
- warp/fem/space/partition.py +9 -6
- warp/fem/space/quadmesh_2d_function_space.py +2 -2
- warp/fem/space/shape/cube_shape_function.py +27 -15
- warp/fem/space/shape/square_shape_function.py +29 -18
- warp/fem/space/tetmesh_function_space.py +2 -2
- warp/fem/space/topology.py +10 -0
- warp/fem/space/trimesh_2d_function_space.py +2 -2
- warp/fem/utils.py +10 -5
- warp/native/array.h +49 -8
- warp/native/builtin.h +31 -14
- warp/native/cuda_util.cpp +8 -3
- warp/native/cuda_util.h +1 -0
- warp/native/exports.h +1177 -1108
- warp/native/intersect.h +4 -4
- warp/native/intersect_adj.h +8 -8
- warp/native/mat.h +65 -6
- warp/native/mesh.h +126 -5
- warp/native/quat.h +28 -4
- warp/native/vec.h +76 -14
- warp/native/warp.cu +1 -6
- warp/render/render_opengl.py +261 -109
- warp/sim/import_mjcf.py +13 -7
- warp/sim/import_urdf.py +14 -14
- warp/sim/inertia.py +17 -18
- warp/sim/model.py +67 -67
- warp/sim/render.py +1 -1
- warp/sparse.py +6 -6
- warp/stubs.py +19 -81
- warp/tape.py +1 -1
- warp/tests/__main__.py +3 -6
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/{test_kinematics.py → disabled_kinematics.py} +10 -12
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +102 -106
- warp/tests/test_arithmetic.py +39 -40
- warp/tests/test_array.py +46 -48
- warp/tests/test_array_reduce.py +25 -19
- warp/tests/test_atomic.py +62 -26
- warp/tests/test_bool.py +16 -11
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +9 -12
- warp/tests/test_closest_point_edge_edge.py +53 -57
- warp/tests/test_codegen.py +164 -134
- warp/tests/test_compile_consts.py +13 -19
- warp/tests/test_conditional.py +30 -32
- warp/tests/test_copy.py +9 -12
- warp/tests/test_ctypes.py +90 -98
- warp/tests/test_dense.py +20 -14
- warp/tests/test_devices.py +34 -35
- warp/tests/test_dlpack.py +74 -75
- warp/tests/test_examples.py +215 -97
- warp/tests/test_fabricarray.py +15 -21
- warp/tests/test_fast_math.py +14 -11
- warp/tests/test_fem.py +280 -97
- warp/tests/test_fp16.py +19 -15
- warp/tests/test_func.py +177 -194
- warp/tests/test_generics.py +71 -77
- warp/tests/test_grad.py +83 -32
- warp/tests/test_grad_customs.py +7 -9
- warp/tests/test_hash_grid.py +6 -10
- warp/tests/test_import.py +9 -23
- warp/tests/test_indexedarray.py +19 -21
- warp/tests/test_intersect.py +15 -9
- warp/tests/test_large.py +17 -19
- warp/tests/test_launch.py +14 -17
- warp/tests/test_lerp.py +63 -63
- warp/tests/test_lvalue.py +84 -35
- warp/tests/test_marching_cubes.py +9 -13
- warp/tests/test_mat.py +388 -3004
- warp/tests/test_mat_lite.py +9 -12
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +10 -11
- warp/tests/test_matmul.py +104 -100
- warp/tests/test_matmul_lite.py +72 -98
- warp/tests/test_mesh.py +35 -32
- warp/tests/test_mesh_query_aabb.py +18 -25
- warp/tests/test_mesh_query_point.py +39 -23
- warp/tests/test_mesh_query_ray.py +9 -21
- warp/tests/test_mlp.py +8 -9
- warp/tests/test_model.py +89 -93
- warp/tests/test_modules_lite.py +15 -25
- warp/tests/test_multigpu.py +87 -114
- warp/tests/test_noise.py +10 -12
- warp/tests/test_operators.py +14 -21
- warp/tests/test_options.py +10 -11
- warp/tests/test_pinned.py +16 -18
- warp/tests/test_print.py +16 -20
- warp/tests/test_quat.py +121 -88
- warp/tests/test_rand.py +12 -13
- warp/tests/test_reload.py +27 -32
- warp/tests/test_rounding.py +7 -10
- warp/tests/test_runlength_encode.py +105 -106
- warp/tests/test_smoothstep.py +8 -9
- warp/tests/test_snippet.py +13 -22
- warp/tests/test_sparse.py +30 -29
- warp/tests/test_spatial.py +179 -174
- warp/tests/test_streams.py +100 -107
- warp/tests/test_struct.py +98 -67
- warp/tests/test_tape.py +11 -17
- warp/tests/test_torch.py +89 -86
- warp/tests/test_transient_module.py +9 -12
- warp/tests/test_types.py +328 -50
- warp/tests/test_utils.py +217 -218
- warp/tests/test_vec.py +133 -2133
- warp/tests/test_vec_lite.py +8 -11
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +391 -382
- warp/tests/test_volume_write.py +122 -135
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +291 -0
- warp/tests/{test_base.py → unittest_utils.py} +138 -25
- warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
- warp/tests/{test_debug.py → walkthough_debug.py} +2 -15
- warp/thirdparty/unittest_parallel.py +257 -54
- warp/types.py +119 -98
- warp/utils.py +14 -0
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/METADATA +2 -1
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/RECORD +183 -179
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
- warp/tests/test_all.py +0 -239
- warp/tests/test_conditional_unequal_types_kernels.py +0 -14
- warp/tests/test_coverage.py +0 -38
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
warp/sim/import_urdf.py
CHANGED
|
@@ -100,8 +100,8 @@ def parse_urdf(
|
|
|
100
100
|
size = [float(x) for x in size.split()]
|
|
101
101
|
builder.add_shape_box(
|
|
102
102
|
body=link,
|
|
103
|
-
pos=tf.p,
|
|
104
|
-
rot=tf.q,
|
|
103
|
+
pos=wp.vec3(tf.p),
|
|
104
|
+
rot=wp.quat(tf.q),
|
|
105
105
|
hx=size[0] * 0.5 * scale,
|
|
106
106
|
hy=size[1] * 0.5 * scale,
|
|
107
107
|
hz=size[2] * 0.5 * scale,
|
|
@@ -117,8 +117,8 @@ def parse_urdf(
|
|
|
117
117
|
for sphere in geo.findall("sphere"):
|
|
118
118
|
builder.add_shape_sphere(
|
|
119
119
|
body=link,
|
|
120
|
-
pos=tf.p,
|
|
121
|
-
rot=tf.q,
|
|
120
|
+
pos=wp.vec3(tf.p),
|
|
121
|
+
rot=wp.quat(tf.q),
|
|
122
122
|
radius=float(sphere.get("radius") or "1") * scale,
|
|
123
123
|
density=density,
|
|
124
124
|
ke=shape_ke,
|
|
@@ -132,8 +132,8 @@ def parse_urdf(
|
|
|
132
132
|
for cylinder in geo.findall("cylinder"):
|
|
133
133
|
builder.add_shape_capsule(
|
|
134
134
|
body=link,
|
|
135
|
-
pos=tf.p,
|
|
136
|
-
rot=tf.q,
|
|
135
|
+
pos=wp.vec3(tf.p),
|
|
136
|
+
rot=wp.quat(tf.q),
|
|
137
137
|
radius=float(cylinder.get("radius") or "1") * scale,
|
|
138
138
|
half_height=float(cylinder.get("length") or "1") * 0.5 * scale,
|
|
139
139
|
density=density,
|
|
@@ -180,12 +180,12 @@ def parse_urdf(
|
|
|
180
180
|
# multiple meshes are contained in a scene
|
|
181
181
|
for geom in m.geometry.values():
|
|
182
182
|
vertices = np.array(geom.vertices, dtype=np.float32) * scaling
|
|
183
|
-
faces = np.array(geom.faces, dtype=np.int32)
|
|
183
|
+
faces = np.array(geom.faces.flatten(), dtype=np.int32)
|
|
184
184
|
mesh = Mesh(vertices, faces)
|
|
185
185
|
builder.add_shape_mesh(
|
|
186
186
|
body=link,
|
|
187
|
-
pos=tf.p,
|
|
188
|
-
rot=tf.q,
|
|
187
|
+
pos=wp.vec3(tf.p),
|
|
188
|
+
rot=wp.quat(tf.q),
|
|
189
189
|
mesh=mesh,
|
|
190
190
|
density=density,
|
|
191
191
|
ke=shape_ke,
|
|
@@ -198,7 +198,7 @@ def parse_urdf(
|
|
|
198
198
|
else:
|
|
199
199
|
# a single mesh
|
|
200
200
|
vertices = np.array(m.vertices, dtype=np.float32) * scaling
|
|
201
|
-
faces = np.array(m.faces, dtype=np.int32)
|
|
201
|
+
faces = np.array(m.faces.flatten(), dtype=np.int32)
|
|
202
202
|
mesh = Mesh(vertices, faces)
|
|
203
203
|
builder.add_shape_mesh(
|
|
204
204
|
body=link,
|
|
@@ -252,22 +252,22 @@ def parse_urdf(
|
|
|
252
252
|
I_m[2, 0] = I_m[0, 2]
|
|
253
253
|
I_m[2, 1] = I_m[1, 2]
|
|
254
254
|
rot = wp.quat_to_matrix(inertial_frame.q)
|
|
255
|
-
I_m = rot @ I_m
|
|
255
|
+
I_m = rot @ wp.mat33(I_m)
|
|
256
256
|
m = float(inertial.find("mass").get("value") or "0")
|
|
257
257
|
builder.body_mass[link] = m
|
|
258
258
|
builder.body_inv_mass[link] = 1.0 / m
|
|
259
259
|
builder.body_com[link] = com
|
|
260
260
|
builder.body_inertia[link] = I_m
|
|
261
|
-
builder.body_inv_inertia[link] =
|
|
261
|
+
builder.body_inv_inertia[link] = wp.inverse(I_m)
|
|
262
262
|
if m == 0.0 and ensure_nonstatic_links:
|
|
263
263
|
# set the mass to something nonzero to ensure the body is dynamic
|
|
264
264
|
m = static_link_mass
|
|
265
265
|
# cube with side length 0.5
|
|
266
|
-
I_m = np.eye(3) * m / 12.0 * (0.5 * scale) ** 2 * 2.0
|
|
266
|
+
I_m = wp.mat33(np.eye(3)) * m / 12.0 * (0.5 * scale) ** 2 * 2.0
|
|
267
267
|
builder.body_mass[link] = m
|
|
268
268
|
builder.body_inv_mass[link] = 1.0 / m
|
|
269
269
|
builder.body_inertia[link] = I_m
|
|
270
|
-
builder.body_inv_inertia[link] =
|
|
270
|
+
builder.body_inv_inertia[link] = wp.inverse(I_m)
|
|
271
271
|
|
|
272
272
|
end_shape_count = len(builder.shape_geo_type)
|
|
273
273
|
|
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 =
|
|
152
|
+
I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ia, 0.0], [0.0, 0.0, Ia]])
|
|
153
153
|
|
|
154
|
-
return (m,
|
|
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 =
|
|
180
|
+
I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
|
|
181
181
|
|
|
182
|
-
return (m,
|
|
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 =
|
|
203
|
+
I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
|
|
204
204
|
|
|
205
|
-
return (m,
|
|
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 =
|
|
226
|
+
I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ia]])
|
|
227
227
|
|
|
228
|
-
return (m,
|
|
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 =
|
|
252
|
+
I = wp.mat33([[Ia, 0.0, 0.0], [0.0, Ib, 0.0], [0.0, 0.0, Ic]])
|
|
253
253
|
|
|
254
|
-
return (m,
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
313
|
+
R = wp.quat_to_matrix(q)
|
|
315
314
|
|
|
316
315
|
# Steiner's theorem
|
|
317
|
-
return R @ I @ R
|
|
316
|
+
return R @ I @ wp.transpose(R) + m * (wp.dot(p, p) * wp.mat33(np.eye(3)) - wp.outer(p, p))
|
warp/sim/model.py
CHANGED
|
@@ -113,8 +113,8 @@ class JointAxis:
|
|
|
113
113
|
def __init__(
|
|
114
114
|
self,
|
|
115
115
|
axis,
|
|
116
|
-
limit_lower=-
|
|
117
|
-
limit_upper=
|
|
116
|
+
limit_lower=-math.inf,
|
|
117
|
+
limit_upper=math.inf,
|
|
118
118
|
limit_ke=100.0,
|
|
119
119
|
limit_kd=10.0,
|
|
120
120
|
target=None,
|
|
@@ -133,7 +133,7 @@ class JointAxis:
|
|
|
133
133
|
self.target_kd = axis.target_kd
|
|
134
134
|
self.mode = axis.mode
|
|
135
135
|
else:
|
|
136
|
-
self.axis =
|
|
136
|
+
self.axis = wp.normalize(wp.vec3(axis))
|
|
137
137
|
self.limit_lower = limit_lower
|
|
138
138
|
self.limit_upper = limit_upper
|
|
139
139
|
self.limit_ke = limit_ke
|
|
@@ -159,7 +159,7 @@ class SDF:
|
|
|
159
159
|
mass (float): The total mass of the SDF
|
|
160
160
|
com (Vec3): The center of mass of the SDF
|
|
161
161
|
"""
|
|
162
|
-
def __init__(self, volume=None, I=np.eye(3
|
|
162
|
+
def __init__(self, volume=None, I=wp.mat33(np.eye(3)), mass=1.0, com=wp.vec3()):
|
|
163
163
|
self.volume = volume
|
|
164
164
|
self.I = I
|
|
165
165
|
self.mass = mass
|
|
@@ -234,9 +234,9 @@ class Mesh:
|
|
|
234
234
|
if compute_inertia:
|
|
235
235
|
self.mass, self.com, self.I, _ = compute_mesh_inertia(1.0, vertices, indices, is_solid=is_solid)
|
|
236
236
|
else:
|
|
237
|
-
self.I = np.eye(3
|
|
237
|
+
self.I = wp.mat33(np.eye(3))
|
|
238
238
|
self.mass = 1.0
|
|
239
|
-
self.com =
|
|
239
|
+
self.com = wp.vec3()
|
|
240
240
|
|
|
241
241
|
def finalize(self, device=None):
|
|
242
242
|
"""
|
|
@@ -325,7 +325,7 @@ class State:
|
|
|
325
325
|
|
|
326
326
|
def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
327
327
|
if density == 0.0 or type == GEO_PLANE: # zero density means fixed
|
|
328
|
-
return 0.0,
|
|
328
|
+
return 0.0, wp.vec3(), wp.mat33()
|
|
329
329
|
|
|
330
330
|
if type == GEO_SPHERE:
|
|
331
331
|
solid = compute_sphere_inertia(density, scale[0])
|
|
@@ -335,7 +335,7 @@ def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
|
335
335
|
hollow = compute_sphere_inertia(density, scale[0] - thickness)
|
|
336
336
|
return solid[0] - hollow[0], solid[1], solid[2] - hollow[2]
|
|
337
337
|
elif type == GEO_BOX:
|
|
338
|
-
w, h, d =
|
|
338
|
+
w, h, d = scale * 2.0
|
|
339
339
|
solid = compute_box_inertia(density, w, h, d)
|
|
340
340
|
if is_solid:
|
|
341
341
|
return solid
|
|
@@ -370,13 +370,12 @@ def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
|
370
370
|
if src.has_inertia and src.mass > 0.0 and src.is_solid == is_solid:
|
|
371
371
|
m, c, I = src.mass, src.com, src.I
|
|
372
372
|
|
|
373
|
-
|
|
374
|
-
sx, sy, sz = s
|
|
373
|
+
sx, sy, sz = scale
|
|
375
374
|
|
|
376
375
|
mass_ratio = sx * sy * sz * density
|
|
377
376
|
m_new = m * mass_ratio
|
|
378
377
|
|
|
379
|
-
c_new = c
|
|
378
|
+
c_new = wp.cw_mul(c, scale)
|
|
380
379
|
|
|
381
380
|
Ixx = I[0, 0] * (sy**2 + sz**2) / 2 * mass_ratio
|
|
382
381
|
Iyy = I[1, 1] * (sx**2 + sz**2) / 2 * mass_ratio
|
|
@@ -385,12 +384,12 @@ def compute_shape_mass(type, scale, src, density, is_solid, thickness):
|
|
|
385
384
|
Ixz = I[0, 2] * sx * sz * mass_ratio
|
|
386
385
|
Iyz = I[1, 2] * sy * sz * mass_ratio
|
|
387
386
|
|
|
388
|
-
I_new =
|
|
387
|
+
I_new = wp.mat33([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])
|
|
389
388
|
|
|
390
389
|
return m_new, c_new, I_new
|
|
391
390
|
elif type == GEO_MESH:
|
|
392
391
|
# fall back to computing inertia from mesh geometry
|
|
393
|
-
vertices = np.array(src.vertices) * np.array(scale
|
|
392
|
+
vertices = np.array(src.vertices) * np.array(scale)
|
|
394
393
|
m, c, I, vol = compute_mesh_inertia(density, vertices, src.indices, is_solid, thickness)
|
|
395
394
|
return m, c, I
|
|
396
395
|
raise ValueError("Unsupported shape type: {}".format(type))
|
|
@@ -1131,8 +1130,8 @@ class ModelBuilder:
|
|
|
1131
1130
|
self.joint_coord_count = 0
|
|
1132
1131
|
self.joint_axis_total_count = 0
|
|
1133
1132
|
|
|
1134
|
-
self.up_vector =
|
|
1135
|
-
self.up_axis = np.argmax(np.abs(up_vector))
|
|
1133
|
+
self.up_vector = wp.vec3(up_vector)
|
|
1134
|
+
self.up_axis = wp.vec3(np.argmax(np.abs(up_vector)))
|
|
1136
1135
|
self.gravity = gravity
|
|
1137
1136
|
# indicates whether a ground plane has been created
|
|
1138
1137
|
self._ground_created = False
|
|
@@ -1366,8 +1365,8 @@ class ModelBuilder:
|
|
|
1366
1365
|
self,
|
|
1367
1366
|
origin: Transform = wp.transform(),
|
|
1368
1367
|
armature: float = 0.0,
|
|
1369
|
-
com: Vec3 =
|
|
1370
|
-
I_m: Mat33 =
|
|
1368
|
+
com: Vec3 = wp.vec3(),
|
|
1369
|
+
I_m: Mat33 = wp.mat33(),
|
|
1371
1370
|
m: float = 0.0,
|
|
1372
1371
|
name: str = None,
|
|
1373
1372
|
) -> int:
|
|
@@ -1392,7 +1391,7 @@ class ModelBuilder:
|
|
|
1392
1391
|
body_id = len(self.body_mass)
|
|
1393
1392
|
|
|
1394
1393
|
# body data
|
|
1395
|
-
inertia = I_m + np.eye(3) * armature
|
|
1394
|
+
inertia = I_m + wp.mat33(np.eye(3)) * armature
|
|
1396
1395
|
self.body_inertia.append(inertia)
|
|
1397
1396
|
self.body_mass.append(m)
|
|
1398
1397
|
self.body_com.append(com)
|
|
@@ -1402,8 +1401,8 @@ class ModelBuilder:
|
|
|
1402
1401
|
else:
|
|
1403
1402
|
self.body_inv_mass.append(0.0)
|
|
1404
1403
|
|
|
1405
|
-
if
|
|
1406
|
-
self.body_inv_inertia.append(
|
|
1404
|
+
if any(x for x in inertia):
|
|
1405
|
+
self.body_inv_inertia.append(wp.inverse(inertia))
|
|
1407
1406
|
else:
|
|
1408
1407
|
self.body_inv_inertia.append(inertia)
|
|
1409
1408
|
|
|
@@ -1459,8 +1458,8 @@ class ModelBuilder:
|
|
|
1459
1458
|
else:
|
|
1460
1459
|
self.joint_parents[child].append(parent)
|
|
1461
1460
|
self.joint_child.append(child)
|
|
1462
|
-
self.joint_X_p.append(
|
|
1463
|
-
self.joint_X_c.append(
|
|
1461
|
+
self.joint_X_p.append(wp.transform(parent_xform))
|
|
1462
|
+
self.joint_X_c.append(wp.transform(child_xform))
|
|
1464
1463
|
self.joint_name.append(name or f"joint {self.joint_count}")
|
|
1465
1464
|
self.joint_axis_start.append(len(self.joint_axis))
|
|
1466
1465
|
self.joint_axis_dim.append((len(linear_axes), len(angular_axes)))
|
|
@@ -2331,7 +2330,7 @@ class ModelBuilder:
|
|
|
2331
2330
|
angle = np.arcsin(np.linalg.norm(c))
|
|
2332
2331
|
axis = c / np.linalg.norm(c)
|
|
2333
2332
|
rot = wp.quat_from_axis_angle(axis, angle)
|
|
2334
|
-
scale = (width, length, 0.0)
|
|
2333
|
+
scale = wp.vec3(width, length, 0.0)
|
|
2335
2334
|
|
|
2336
2335
|
return self._add_shape(
|
|
2337
2336
|
body,
|
|
@@ -2390,10 +2389,10 @@ class ModelBuilder:
|
|
|
2390
2389
|
|
|
2391
2390
|
return self._add_shape(
|
|
2392
2391
|
body,
|
|
2393
|
-
pos,
|
|
2394
|
-
rot,
|
|
2392
|
+
wp.vec3(pos),
|
|
2393
|
+
wp.quat(rot),
|
|
2395
2394
|
GEO_SPHERE,
|
|
2396
|
-
(radius, 0.0, 0.0
|
|
2395
|
+
wp.vec3(radius, 0.0, 0.0),
|
|
2397
2396
|
None,
|
|
2398
2397
|
density,
|
|
2399
2398
|
ke,
|
|
@@ -2450,10 +2449,10 @@ class ModelBuilder:
|
|
|
2450
2449
|
|
|
2451
2450
|
return self._add_shape(
|
|
2452
2451
|
body,
|
|
2453
|
-
pos,
|
|
2454
|
-
rot,
|
|
2452
|
+
wp.vec3(pos),
|
|
2453
|
+
wp.quat(rot),
|
|
2455
2454
|
GEO_BOX,
|
|
2456
|
-
(hx, hy, hz
|
|
2455
|
+
wp.vec3(hx, hy, hz),
|
|
2457
2456
|
None,
|
|
2458
2457
|
density,
|
|
2459
2458
|
ke,
|
|
@@ -2508,19 +2507,19 @@ class ModelBuilder:
|
|
|
2508
2507
|
|
|
2509
2508
|
"""
|
|
2510
2509
|
|
|
2511
|
-
q = rot
|
|
2510
|
+
q = wp.quat(rot)
|
|
2512
2511
|
sqh = math.sqrt(0.5)
|
|
2513
2512
|
if up_axis == 0:
|
|
2514
|
-
q = wp.mul(
|
|
2513
|
+
q = wp.mul(q, wp.quat(0.0, 0.0, -sqh, sqh))
|
|
2515
2514
|
elif up_axis == 2:
|
|
2516
|
-
q = wp.mul(
|
|
2515
|
+
q = wp.mul(q, wp.quat(sqh, 0.0, 0.0, sqh))
|
|
2517
2516
|
|
|
2518
2517
|
return self._add_shape(
|
|
2519
2518
|
body,
|
|
2520
|
-
pos,
|
|
2521
|
-
q,
|
|
2519
|
+
wp.vec3(pos),
|
|
2520
|
+
wp.quat(q),
|
|
2522
2521
|
GEO_CAPSULE,
|
|
2523
|
-
(radius, half_height, 0.0
|
|
2522
|
+
wp.vec3(radius, half_height, 0.0),
|
|
2524
2523
|
None,
|
|
2525
2524
|
density,
|
|
2526
2525
|
ke,
|
|
@@ -2584,10 +2583,10 @@ class ModelBuilder:
|
|
|
2584
2583
|
|
|
2585
2584
|
return self._add_shape(
|
|
2586
2585
|
body,
|
|
2587
|
-
pos,
|
|
2588
|
-
q,
|
|
2586
|
+
wp.vec3(pos),
|
|
2587
|
+
wp.quat(q),
|
|
2589
2588
|
GEO_CYLINDER,
|
|
2590
|
-
(radius, half_height, 0.0
|
|
2589
|
+
wp.vec3(radius, half_height, 0.0),
|
|
2591
2590
|
None,
|
|
2592
2591
|
density,
|
|
2593
2592
|
ke,
|
|
@@ -2651,10 +2650,10 @@ class ModelBuilder:
|
|
|
2651
2650
|
|
|
2652
2651
|
return self._add_shape(
|
|
2653
2652
|
body,
|
|
2654
|
-
pos,
|
|
2655
|
-
q,
|
|
2653
|
+
wp.vec3(pos),
|
|
2654
|
+
wp.quat(q),
|
|
2656
2655
|
GEO_CONE,
|
|
2657
|
-
(radius, half_height, 0.0
|
|
2656
|
+
wp.vec3(radius, half_height, 0.0),
|
|
2658
2657
|
None,
|
|
2659
2658
|
density,
|
|
2660
2659
|
ke,
|
|
@@ -2670,10 +2669,10 @@ class ModelBuilder:
|
|
|
2670
2669
|
def add_shape_mesh(
|
|
2671
2670
|
self,
|
|
2672
2671
|
body: int,
|
|
2673
|
-
pos: Vec3 = (0.0, 0.0, 0.0),
|
|
2674
|
-
rot: Quat = (0.0, 0.0, 0.0, 1.0),
|
|
2672
|
+
pos: Vec3 = wp.vec3(0.0, 0.0, 0.0),
|
|
2673
|
+
rot: Quat = wp.quat(0.0, 0.0, 0.0, 1.0),
|
|
2675
2674
|
mesh: Mesh = None,
|
|
2676
|
-
scale: Vec3 = (1.0, 1.0, 1.0),
|
|
2675
|
+
scale: Vec3 = wp.vec3(1.0, 1.0, 1.0),
|
|
2677
2676
|
density: float = default_shape_density,
|
|
2678
2677
|
ke: float = default_shape_ke,
|
|
2679
2678
|
kd: float = default_shape_kd,
|
|
@@ -2712,7 +2711,7 @@ class ModelBuilder:
|
|
|
2712
2711
|
pos,
|
|
2713
2712
|
rot,
|
|
2714
2713
|
GEO_MESH,
|
|
2715
|
-
(scale[0], scale[1], scale[2]
|
|
2714
|
+
wp.vec3(scale[0], scale[1], scale[2]),
|
|
2716
2715
|
mesh,
|
|
2717
2716
|
density,
|
|
2718
2717
|
ke,
|
|
@@ -2765,10 +2764,10 @@ class ModelBuilder:
|
|
|
2765
2764
|
"""
|
|
2766
2765
|
return self._add_shape(
|
|
2767
2766
|
body,
|
|
2768
|
-
pos,
|
|
2769
|
-
rot,
|
|
2767
|
+
wp.vec3(pos),
|
|
2768
|
+
wp.quat(rot),
|
|
2770
2769
|
GEO_SDF,
|
|
2771
|
-
(scale[0], scale[1], scale[2]
|
|
2770
|
+
wp.vec3(scale[0], scale[1], scale[2]),
|
|
2772
2771
|
sdf,
|
|
2773
2772
|
density,
|
|
2774
2773
|
ke,
|
|
@@ -2859,7 +2858,7 @@ class ModelBuilder:
|
|
|
2859
2858
|
|
|
2860
2859
|
(m, c, I) = compute_shape_mass(type, scale, src, density, is_solid, thickness)
|
|
2861
2860
|
|
|
2862
|
-
self._update_body_mass(body, m, I,
|
|
2861
|
+
self._update_body_mass(body, m, I, pos + c, rot)
|
|
2863
2862
|
return shape
|
|
2864
2863
|
|
|
2865
2864
|
# particles
|
|
@@ -2954,9 +2953,9 @@ class ModelBuilder:
|
|
|
2954
2953
|
|
|
2955
2954
|
"""
|
|
2956
2955
|
# compute basis for 2D rest pose
|
|
2957
|
-
p =
|
|
2958
|
-
q =
|
|
2959
|
-
r =
|
|
2956
|
+
p = self.particle_q[i]
|
|
2957
|
+
q = self.particle_q[j]
|
|
2958
|
+
r = self.particle_q[k]
|
|
2960
2959
|
|
|
2961
2960
|
qp = q - p
|
|
2962
2961
|
rp = r - p
|
|
@@ -3153,13 +3152,13 @@ class ModelBuilder:
|
|
|
3153
3152
|
"""
|
|
3154
3153
|
# compute rest angle
|
|
3155
3154
|
if rest is None:
|
|
3156
|
-
x1 =
|
|
3157
|
-
x2 =
|
|
3158
|
-
x3 =
|
|
3159
|
-
x4 =
|
|
3155
|
+
x1 = self.particle_q[i]
|
|
3156
|
+
x2 = self.particle_q[j]
|
|
3157
|
+
x3 = self.particle_q[k]
|
|
3158
|
+
x4 = self.particle_q[l]
|
|
3160
3159
|
|
|
3161
|
-
n1 = wp.normalize(
|
|
3162
|
-
n2 = wp.normalize(
|
|
3160
|
+
n1 = wp.normalize(wp.cross(x3 - x1, x4 - x1))
|
|
3161
|
+
n2 = wp.normalize(wp.cross(x4 - x2, x3 - x2))
|
|
3163
3162
|
e = wp.normalize(x4 - x3)
|
|
3164
3163
|
|
|
3165
3164
|
d = np.clip(np.dot(n2, n1), -1.0, 1.0)
|
|
@@ -3299,8 +3298,8 @@ class ModelBuilder:
|
|
|
3299
3298
|
|
|
3300
3299
|
for y in range(0, dim_y + 1):
|
|
3301
3300
|
for x in range(0, dim_x + 1):
|
|
3302
|
-
g =
|
|
3303
|
-
p =
|
|
3301
|
+
g = wp.vec3(x * cell_x, y * cell_y, 0.0)
|
|
3302
|
+
p = wp.quat_rotate(rot, g) + pos
|
|
3304
3303
|
m = mass
|
|
3305
3304
|
|
|
3306
3305
|
if x == 0 and fix_left:
|
|
@@ -3425,7 +3424,7 @@ class ModelBuilder:
|
|
|
3425
3424
|
|
|
3426
3425
|
# particles
|
|
3427
3426
|
for v in vertices:
|
|
3428
|
-
p =
|
|
3427
|
+
p = wp.quat_rotate(rot, v * scale) + pos
|
|
3429
3428
|
|
|
3430
3429
|
self.add_particle(p, vel, 0.0)
|
|
3431
3430
|
|
|
@@ -3498,13 +3497,14 @@ class ModelBuilder:
|
|
|
3498
3497
|
radius_mean: float = default_particle_radius,
|
|
3499
3498
|
radius_std: float = 0.0,
|
|
3500
3499
|
):
|
|
3500
|
+
rng = np.random.default_rng()
|
|
3501
3501
|
for z in range(dim_z):
|
|
3502
3502
|
for y in range(dim_y):
|
|
3503
3503
|
for x in range(dim_x):
|
|
3504
|
-
v =
|
|
3504
|
+
v = wp.vec3(x * cell_x, y * cell_y, z * cell_z)
|
|
3505
3505
|
m = mass
|
|
3506
3506
|
|
|
3507
|
-
p =
|
|
3507
|
+
p = wp.quat_rotate(rot, v) + pos + wp.vec3(rng.random(3) * jitter)
|
|
3508
3508
|
|
|
3509
3509
|
if radius_std > 0.0:
|
|
3510
3510
|
r = radius_mean + np.random.randn() * radius_std
|
|
@@ -3570,7 +3570,7 @@ class ModelBuilder:
|
|
|
3570
3570
|
for z in range(dim_z + 1):
|
|
3571
3571
|
for y in range(dim_y + 1):
|
|
3572
3572
|
for x in range(dim_x + 1):
|
|
3573
|
-
v =
|
|
3573
|
+
v = wp.vec3(x * cell_x, y * cell_y, z * cell_z)
|
|
3574
3574
|
m = mass
|
|
3575
3575
|
|
|
3576
3576
|
if fix_left and x == 0:
|
|
@@ -3585,7 +3585,7 @@ class ModelBuilder:
|
|
|
3585
3585
|
if fix_bottom and y == 0:
|
|
3586
3586
|
m = 0.0
|
|
3587
3587
|
|
|
3588
|
-
p =
|
|
3588
|
+
p = wp.quat_rotate(rot, v) + pos
|
|
3589
3589
|
|
|
3590
3590
|
self.add_particle(p, vel, m)
|
|
3591
3591
|
|
|
@@ -3752,8 +3752,8 @@ class ModelBuilder:
|
|
|
3752
3752
|
else:
|
|
3753
3753
|
self.body_inv_mass[i] = 0.0
|
|
3754
3754
|
|
|
3755
|
-
if
|
|
3756
|
-
self.body_inv_inertia[i] =
|
|
3755
|
+
if any(x for x in new_inertia):
|
|
3756
|
+
self.body_inv_inertia[i] = wp.inverse(new_inertia)
|
|
3757
3757
|
else:
|
|
3758
3758
|
self.body_inv_inertia[i] = new_inertia
|
|
3759
3759
|
|
warp/sim/render.py
CHANGED
|
@@ -268,7 +268,7 @@ def CreateSimRenderer(renderer):
|
|
|
268
268
|
q = wp.quat(tf[3:])
|
|
269
269
|
# compute rotation between axis and y
|
|
270
270
|
axis = axis / np.linalg.norm(axis)
|
|
271
|
-
q = q * wp.quat_between_vectors(wp.vec3(
|
|
271
|
+
q = q * wp.quat_between_vectors(wp.vec3(axis), y_axis)
|
|
272
272
|
name = f"joint_{i}_{a}"
|
|
273
273
|
self.add_shape_instance(name, shape, body, p, q, scale, color1=color, color2=color)
|
|
274
274
|
self.instance_count += 1
|
warp/sparse.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Any, Generic, Optional, Tuple, TypeVar, Union
|
|
2
2
|
|
|
3
3
|
import warp as wp
|
|
4
4
|
import warp.types
|
|
5
|
-
from warp.types import Matrix, Vector, Rows, Cols, Scalar, Array
|
|
6
5
|
import warp.utils
|
|
6
|
+
from warp.types import Array, Cols, Matrix, Rows, Scalar, Vector
|
|
7
7
|
|
|
8
8
|
# typing hints
|
|
9
9
|
|
|
@@ -54,7 +54,7 @@ class BsrMatrix(Generic[_BlockType]):
|
|
|
54
54
|
|
|
55
55
|
@property
|
|
56
56
|
def shape(self) -> Tuple[int, int]:
|
|
57
|
-
"""Shape of the matrix, i.e. number of rows/columns of blocks times number of rows/
|
|
57
|
+
"""Shape of the matrix, i.e. number of rows/columns of blocks times number of rows/columns per block"""
|
|
58
58
|
block_shape = self.block_shape
|
|
59
59
|
return (self.nrow * block_shape[0], self.ncol * block_shape[1])
|
|
60
60
|
|
|
@@ -193,7 +193,7 @@ def bsr_set_from_triplets(
|
|
|
193
193
|
elif values.ndim == 3:
|
|
194
194
|
if values.shape[1:] != dest.block_shape:
|
|
195
195
|
raise ValueError(
|
|
196
|
-
f"Last two dimensions in values array ({values.shape[1:]})
|
|
196
|
+
f"Last two dimensions in values array ({values.shape[1:]}) should correspond to matrix block shape {(dest.block_shape)})"
|
|
197
197
|
)
|
|
198
198
|
|
|
199
199
|
if warp.types.type_scalar_type(values.dtype) != dest.scalar_type:
|
|
@@ -266,7 +266,7 @@ def bsr_assign(dest: BsrMatrix[BlockType[Rows, Cols, Scalar]], src: BsrMatrix[Bl
|
|
|
266
266
|
|
|
267
267
|
|
|
268
268
|
def bsr_copy(A: BsrMatrix, scalar_type: Optional[Scalar] = None):
|
|
269
|
-
"""Returns a copy of matrix ``A``, possibly
|
|
269
|
+
"""Returns a copy of matrix ``A``, possibly changing its scalar type.
|
|
270
270
|
|
|
271
271
|
Args:
|
|
272
272
|
scalar_type: If provided, the returned matrix will use this scalar type instead of the one from `A`.
|
|
@@ -992,7 +992,7 @@ def bsr_mm(
|
|
|
992
992
|
# Get back total counts on host
|
|
993
993
|
if device.is_cuda:
|
|
994
994
|
wp.copy(dest=work_arrays._pinned_count_buffer, src=work_arrays._mm_row_counts, src_offset=z.nrow, count=1)
|
|
995
|
-
wp.synchronize_stream(wp.get_stream())
|
|
995
|
+
wp.synchronize_stream(wp.get_stream(device))
|
|
996
996
|
mm_nnz = int(work_arrays._pinned_count_buffer.numpy()[0])
|
|
997
997
|
else:
|
|
998
998
|
mm_nnz = int(work_arrays._mm_row_counts.numpy()[z.nrow])
|