warp-lang 1.7.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 +139 -0
- warp/__init__.pyi +1 -0
- warp/autograd.py +1142 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +557 -0
- warp/build_dll.py +405 -0
- warp/builtins.py +6855 -0
- warp/codegen.py +3969 -0
- warp/config.py +158 -0
- warp/constants.py +57 -0
- warp/context.py +6812 -0
- warp/dlpack.py +462 -0
- warp/examples/__init__.py +24 -0
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -0
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nonuniform.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -0
- warp/examples/assets/nv_humanoid.xml +183 -0
- warp/examples/assets/nvidia_logo.png +0 -0
- warp/examples/assets/pixel.jpg +0 -0
- warp/examples/assets/quadruped.urdf +268 -0
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +389 -0
- warp/examples/benchmarks/benchmark_cloth.py +296 -0
- warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
- warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
- warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
- warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
- warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
- warp/examples/benchmarks/benchmark_gemm.py +164 -0
- warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
- warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
- warp/examples/benchmarks/benchmark_launches.py +301 -0
- warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
- warp/examples/browse.py +37 -0
- warp/examples/core/example_cupy.py +86 -0
- warp/examples/core/example_dem.py +241 -0
- warp/examples/core/example_fluid.py +299 -0
- warp/examples/core/example_graph_capture.py +150 -0
- warp/examples/core/example_marching_cubes.py +194 -0
- warp/examples/core/example_mesh.py +180 -0
- warp/examples/core/example_mesh_intersect.py +211 -0
- warp/examples/core/example_nvdb.py +182 -0
- warp/examples/core/example_raycast.py +111 -0
- warp/examples/core/example_raymarch.py +205 -0
- warp/examples/core/example_render_opengl.py +193 -0
- warp/examples/core/example_sample_mesh.py +300 -0
- warp/examples/core/example_sph.py +411 -0
- warp/examples/core/example_torch.py +211 -0
- warp/examples/core/example_wave.py +269 -0
- warp/examples/fem/example_adaptive_grid.py +286 -0
- warp/examples/fem/example_apic_fluid.py +423 -0
- warp/examples/fem/example_burgers.py +261 -0
- warp/examples/fem/example_convection_diffusion.py +178 -0
- warp/examples/fem/example_convection_diffusion_dg.py +204 -0
- warp/examples/fem/example_deformed_geometry.py +172 -0
- warp/examples/fem/example_diffusion.py +196 -0
- warp/examples/fem/example_diffusion_3d.py +225 -0
- warp/examples/fem/example_diffusion_mgpu.py +220 -0
- warp/examples/fem/example_distortion_energy.py +228 -0
- warp/examples/fem/example_magnetostatics.py +240 -0
- warp/examples/fem/example_mixed_elasticity.py +291 -0
- warp/examples/fem/example_navier_stokes.py +261 -0
- warp/examples/fem/example_nonconforming_contact.py +298 -0
- warp/examples/fem/example_stokes.py +213 -0
- warp/examples/fem/example_stokes_transfer.py +262 -0
- warp/examples/fem/example_streamlines.py +352 -0
- warp/examples/fem/utils.py +1000 -0
- warp/examples/interop/example_jax_callable.py +116 -0
- warp/examples/interop/example_jax_ffi_callback.py +132 -0
- warp/examples/interop/example_jax_kernel.py +205 -0
- warp/examples/optim/example_bounce.py +266 -0
- warp/examples/optim/example_cloth_throw.py +228 -0
- warp/examples/optim/example_diffray.py +561 -0
- warp/examples/optim/example_drone.py +870 -0
- warp/examples/optim/example_fluid_checkpoint.py +497 -0
- warp/examples/optim/example_inverse_kinematics.py +182 -0
- warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
- warp/examples/optim/example_softbody_properties.py +400 -0
- warp/examples/optim/example_spring_cage.py +245 -0
- warp/examples/optim/example_trajectory.py +227 -0
- warp/examples/sim/example_cartpole.py +143 -0
- warp/examples/sim/example_cloth.py +225 -0
- warp/examples/sim/example_cloth_self_contact.py +322 -0
- warp/examples/sim/example_granular.py +130 -0
- warp/examples/sim/example_granular_collision_sdf.py +202 -0
- warp/examples/sim/example_jacobian_ik.py +244 -0
- warp/examples/sim/example_particle_chain.py +124 -0
- warp/examples/sim/example_quadruped.py +203 -0
- warp/examples/sim/example_rigid_chain.py +203 -0
- warp/examples/sim/example_rigid_contact.py +195 -0
- warp/examples/sim/example_rigid_force.py +133 -0
- warp/examples/sim/example_rigid_gyroscopic.py +115 -0
- warp/examples/sim/example_rigid_soft_contact.py +140 -0
- warp/examples/sim/example_soft_body.py +196 -0
- warp/examples/tile/example_tile_cholesky.py +87 -0
- warp/examples/tile/example_tile_convolution.py +66 -0
- warp/examples/tile/example_tile_fft.py +55 -0
- warp/examples/tile/example_tile_filtering.py +113 -0
- warp/examples/tile/example_tile_matmul.py +85 -0
- warp/examples/tile/example_tile_mlp.py +383 -0
- warp/examples/tile/example_tile_nbody.py +199 -0
- warp/examples/tile/example_tile_walker.py +327 -0
- warp/fabric.py +355 -0
- warp/fem/__init__.py +106 -0
- warp/fem/adaptivity.py +508 -0
- warp/fem/cache.py +572 -0
- warp/fem/dirichlet.py +202 -0
- warp/fem/domain.py +411 -0
- warp/fem/field/__init__.py +125 -0
- warp/fem/field/field.py +619 -0
- warp/fem/field/nodal_field.py +326 -0
- warp/fem/field/restriction.py +37 -0
- warp/fem/field/virtual.py +848 -0
- warp/fem/geometry/__init__.py +32 -0
- warp/fem/geometry/adaptive_nanogrid.py +857 -0
- warp/fem/geometry/closest_point.py +84 -0
- warp/fem/geometry/deformed_geometry.py +221 -0
- warp/fem/geometry/element.py +776 -0
- warp/fem/geometry/geometry.py +362 -0
- warp/fem/geometry/grid_2d.py +392 -0
- warp/fem/geometry/grid_3d.py +452 -0
- warp/fem/geometry/hexmesh.py +911 -0
- warp/fem/geometry/nanogrid.py +571 -0
- warp/fem/geometry/partition.py +389 -0
- warp/fem/geometry/quadmesh.py +663 -0
- warp/fem/geometry/tetmesh.py +855 -0
- warp/fem/geometry/trimesh.py +806 -0
- warp/fem/integrate.py +2335 -0
- warp/fem/linalg.py +419 -0
- warp/fem/operator.py +293 -0
- warp/fem/polynomial.py +229 -0
- warp/fem/quadrature/__init__.py +17 -0
- warp/fem/quadrature/pic_quadrature.py +299 -0
- warp/fem/quadrature/quadrature.py +591 -0
- warp/fem/space/__init__.py +228 -0
- warp/fem/space/basis_function_space.py +468 -0
- warp/fem/space/basis_space.py +667 -0
- warp/fem/space/dof_mapper.py +251 -0
- warp/fem/space/function_space.py +309 -0
- warp/fem/space/grid_2d_function_space.py +177 -0
- warp/fem/space/grid_3d_function_space.py +227 -0
- warp/fem/space/hexmesh_function_space.py +257 -0
- warp/fem/space/nanogrid_function_space.py +201 -0
- warp/fem/space/partition.py +367 -0
- warp/fem/space/quadmesh_function_space.py +223 -0
- warp/fem/space/restriction.py +179 -0
- warp/fem/space/shape/__init__.py +143 -0
- warp/fem/space/shape/cube_shape_function.py +1105 -0
- warp/fem/space/shape/shape_function.py +133 -0
- warp/fem/space/shape/square_shape_function.py +926 -0
- warp/fem/space/shape/tet_shape_function.py +834 -0
- warp/fem/space/shape/triangle_shape_function.py +672 -0
- warp/fem/space/tetmesh_function_space.py +271 -0
- warp/fem/space/topology.py +424 -0
- warp/fem/space/trimesh_function_space.py +194 -0
- warp/fem/types.py +99 -0
- warp/fem/utils.py +420 -0
- warp/jax.py +187 -0
- warp/jax_experimental/__init__.py +16 -0
- warp/jax_experimental/custom_call.py +351 -0
- warp/jax_experimental/ffi.py +698 -0
- warp/jax_experimental/xla_ffi.py +602 -0
- warp/math.py +244 -0
- warp/native/array.h +1145 -0
- warp/native/builtin.h +1800 -0
- warp/native/bvh.cpp +492 -0
- warp/native/bvh.cu +791 -0
- warp/native/bvh.h +554 -0
- warp/native/clang/clang.cpp +536 -0
- warp/native/coloring.cpp +613 -0
- warp/native/crt.cpp +51 -0
- warp/native/crt.h +362 -0
- warp/native/cuda_crt.h +1058 -0
- warp/native/cuda_util.cpp +646 -0
- warp/native/cuda_util.h +307 -0
- warp/native/error.cpp +77 -0
- warp/native/error.h +36 -0
- warp/native/exports.h +1878 -0
- warp/native/fabric.h +245 -0
- warp/native/hashgrid.cpp +311 -0
- warp/native/hashgrid.cu +87 -0
- warp/native/hashgrid.h +240 -0
- warp/native/initializer_array.h +41 -0
- warp/native/intersect.h +1230 -0
- warp/native/intersect_adj.h +375 -0
- warp/native/intersect_tri.h +339 -0
- warp/native/marching.cpp +19 -0
- warp/native/marching.cu +514 -0
- warp/native/marching.h +19 -0
- warp/native/mat.h +2220 -0
- warp/native/mathdx.cpp +87 -0
- warp/native/matnn.h +343 -0
- warp/native/mesh.cpp +266 -0
- warp/native/mesh.cu +404 -0
- warp/native/mesh.h +1980 -0
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +6624 -0
- warp/native/nanovdb/PNanoVDB.h +3390 -0
- warp/native/noise.h +859 -0
- warp/native/quat.h +1371 -0
- warp/native/rand.h +342 -0
- warp/native/range.h +139 -0
- warp/native/reduce.cpp +174 -0
- warp/native/reduce.cu +364 -0
- warp/native/runlength_encode.cpp +79 -0
- warp/native/runlength_encode.cu +61 -0
- warp/native/scan.cpp +47 -0
- warp/native/scan.cu +53 -0
- warp/native/scan.h +23 -0
- warp/native/solid_angle.h +466 -0
- warp/native/sort.cpp +251 -0
- warp/native/sort.cu +277 -0
- warp/native/sort.h +33 -0
- warp/native/sparse.cpp +378 -0
- warp/native/sparse.cu +524 -0
- warp/native/spatial.h +657 -0
- warp/native/svd.h +702 -0
- warp/native/temp_buffer.h +46 -0
- warp/native/tile.h +2584 -0
- warp/native/tile_reduce.h +264 -0
- warp/native/vec.h +1426 -0
- warp/native/volume.cpp +501 -0
- warp/native/volume.cu +67 -0
- warp/native/volume.h +969 -0
- warp/native/volume_builder.cu +477 -0
- warp/native/volume_builder.h +52 -0
- warp/native/volume_impl.h +70 -0
- warp/native/warp.cpp +1082 -0
- warp/native/warp.cu +3636 -0
- warp/native/warp.h +381 -0
- warp/optim/__init__.py +17 -0
- warp/optim/adam.py +163 -0
- warp/optim/linear.py +1137 -0
- warp/optim/sgd.py +112 -0
- warp/paddle.py +407 -0
- warp/render/__init__.py +18 -0
- warp/render/render_opengl.py +3518 -0
- warp/render/render_usd.py +784 -0
- warp/render/utils.py +160 -0
- warp/sim/__init__.py +65 -0
- warp/sim/articulation.py +793 -0
- warp/sim/collide.py +2395 -0
- warp/sim/graph_coloring.py +300 -0
- warp/sim/import_mjcf.py +790 -0
- warp/sim/import_snu.py +227 -0
- warp/sim/import_urdf.py +579 -0
- warp/sim/import_usd.py +894 -0
- warp/sim/inertia.py +324 -0
- warp/sim/integrator.py +242 -0
- warp/sim/integrator_euler.py +1997 -0
- warp/sim/integrator_featherstone.py +2101 -0
- warp/sim/integrator_vbd.py +2048 -0
- warp/sim/integrator_xpbd.py +3292 -0
- warp/sim/model.py +4791 -0
- warp/sim/particles.py +121 -0
- warp/sim/render.py +427 -0
- warp/sim/utils.py +428 -0
- warp/sparse.py +2057 -0
- warp/stubs.py +3333 -0
- warp/tape.py +1203 -0
- warp/tests/__init__.py +1 -0
- warp/tests/__main__.py +4 -0
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/mlp_golden.npy +0 -0
- warp/tests/assets/pixel.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/assets/spiky.usd +0 -0
- warp/tests/assets/test_grid.nvdb +0 -0
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/assets/test_int32_grid.nvdb +0 -0
- warp/tests/assets/test_vec_grid.nvdb +0 -0
- warp/tests/assets/torus.nvdb +0 -0
- warp/tests/assets/torus.usda +105 -0
- warp/tests/aux_test_class_kernel.py +34 -0
- warp/tests/aux_test_compile_consts_dummy.py +18 -0
- warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
- warp/tests/aux_test_dependent.py +29 -0
- warp/tests/aux_test_grad_customs.py +29 -0
- warp/tests/aux_test_instancing_gc.py +26 -0
- warp/tests/aux_test_module_unload.py +23 -0
- warp/tests/aux_test_name_clash1.py +40 -0
- warp/tests/aux_test_name_clash2.py +40 -0
- warp/tests/aux_test_reference.py +9 -0
- warp/tests/aux_test_reference_reference.py +8 -0
- warp/tests/aux_test_square.py +16 -0
- warp/tests/aux_test_unresolved_func.py +22 -0
- warp/tests/aux_test_unresolved_symbol.py +22 -0
- warp/tests/cuda/__init__.py +0 -0
- warp/tests/cuda/test_async.py +676 -0
- warp/tests/cuda/test_ipc.py +124 -0
- warp/tests/cuda/test_mempool.py +233 -0
- warp/tests/cuda/test_multigpu.py +169 -0
- warp/tests/cuda/test_peer.py +139 -0
- warp/tests/cuda/test_pinned.py +84 -0
- warp/tests/cuda/test_streams.py +634 -0
- warp/tests/geometry/__init__.py +0 -0
- warp/tests/geometry/test_bvh.py +200 -0
- warp/tests/geometry/test_hash_grid.py +221 -0
- warp/tests/geometry/test_marching_cubes.py +74 -0
- warp/tests/geometry/test_mesh.py +316 -0
- warp/tests/geometry/test_mesh_query_aabb.py +399 -0
- warp/tests/geometry/test_mesh_query_point.py +932 -0
- warp/tests/geometry/test_mesh_query_ray.py +311 -0
- warp/tests/geometry/test_volume.py +1103 -0
- warp/tests/geometry/test_volume_write.py +346 -0
- warp/tests/interop/__init__.py +0 -0
- warp/tests/interop/test_dlpack.py +729 -0
- warp/tests/interop/test_jax.py +371 -0
- warp/tests/interop/test_paddle.py +800 -0
- warp/tests/interop/test_torch.py +1001 -0
- warp/tests/run_coverage_serial.py +39 -0
- warp/tests/sim/__init__.py +0 -0
- warp/tests/sim/disabled_kinematics.py +244 -0
- warp/tests/sim/flaky_test_sim_grad.py +290 -0
- warp/tests/sim/test_collision.py +604 -0
- warp/tests/sim/test_coloring.py +258 -0
- warp/tests/sim/test_model.py +224 -0
- warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
- warp/tests/sim/test_sim_kinematics.py +98 -0
- warp/tests/sim/test_vbd.py +597 -0
- warp/tests/test_adam.py +163 -0
- warp/tests/test_arithmetic.py +1096 -0
- warp/tests/test_array.py +2972 -0
- warp/tests/test_array_reduce.py +156 -0
- warp/tests/test_assert.py +250 -0
- warp/tests/test_atomic.py +153 -0
- warp/tests/test_bool.py +220 -0
- warp/tests/test_builtins_resolution.py +1298 -0
- warp/tests/test_closest_point_edge_edge.py +327 -0
- warp/tests/test_codegen.py +810 -0
- warp/tests/test_codegen_instancing.py +1495 -0
- warp/tests/test_compile_consts.py +215 -0
- warp/tests/test_conditional.py +252 -0
- warp/tests/test_context.py +42 -0
- warp/tests/test_copy.py +238 -0
- warp/tests/test_ctypes.py +638 -0
- warp/tests/test_dense.py +73 -0
- warp/tests/test_devices.py +97 -0
- warp/tests/test_examples.py +482 -0
- warp/tests/test_fabricarray.py +996 -0
- warp/tests/test_fast_math.py +74 -0
- warp/tests/test_fem.py +2003 -0
- warp/tests/test_fp16.py +136 -0
- warp/tests/test_func.py +454 -0
- warp/tests/test_future_annotations.py +98 -0
- warp/tests/test_generics.py +656 -0
- warp/tests/test_grad.py +893 -0
- warp/tests/test_grad_customs.py +339 -0
- warp/tests/test_grad_debug.py +341 -0
- warp/tests/test_implicit_init.py +411 -0
- warp/tests/test_import.py +45 -0
- warp/tests/test_indexedarray.py +1140 -0
- warp/tests/test_intersect.py +73 -0
- warp/tests/test_iter.py +76 -0
- warp/tests/test_large.py +177 -0
- warp/tests/test_launch.py +411 -0
- warp/tests/test_lerp.py +151 -0
- warp/tests/test_linear_solvers.py +193 -0
- warp/tests/test_lvalue.py +427 -0
- warp/tests/test_mat.py +2089 -0
- warp/tests/test_mat_lite.py +122 -0
- warp/tests/test_mat_scalar_ops.py +2913 -0
- warp/tests/test_math.py +178 -0
- warp/tests/test_mlp.py +282 -0
- warp/tests/test_module_hashing.py +258 -0
- warp/tests/test_modules_lite.py +44 -0
- warp/tests/test_noise.py +252 -0
- warp/tests/test_operators.py +299 -0
- warp/tests/test_options.py +129 -0
- warp/tests/test_overwrite.py +551 -0
- warp/tests/test_print.py +339 -0
- warp/tests/test_quat.py +2315 -0
- warp/tests/test_rand.py +339 -0
- warp/tests/test_reload.py +302 -0
- warp/tests/test_rounding.py +185 -0
- warp/tests/test_runlength_encode.py +196 -0
- warp/tests/test_scalar_ops.py +105 -0
- warp/tests/test_smoothstep.py +108 -0
- warp/tests/test_snippet.py +318 -0
- warp/tests/test_sparse.py +582 -0
- warp/tests/test_spatial.py +2229 -0
- warp/tests/test_special_values.py +361 -0
- warp/tests/test_static.py +592 -0
- warp/tests/test_struct.py +734 -0
- warp/tests/test_tape.py +204 -0
- warp/tests/test_transient_module.py +93 -0
- warp/tests/test_triangle_closest_point.py +145 -0
- warp/tests/test_types.py +562 -0
- warp/tests/test_utils.py +588 -0
- warp/tests/test_vec.py +1487 -0
- warp/tests/test_vec_lite.py +80 -0
- warp/tests/test_vec_scalar_ops.py +2327 -0
- warp/tests/test_verify_fp.py +100 -0
- warp/tests/tile/__init__.py +0 -0
- warp/tests/tile/test_tile.py +780 -0
- warp/tests/tile/test_tile_load.py +407 -0
- warp/tests/tile/test_tile_mathdx.py +208 -0
- warp/tests/tile/test_tile_mlp.py +402 -0
- warp/tests/tile/test_tile_reduce.py +447 -0
- warp/tests/tile/test_tile_shared_memory.py +247 -0
- warp/tests/tile/test_tile_view.py +173 -0
- warp/tests/unittest_serial.py +47 -0
- warp/tests/unittest_suites.py +427 -0
- warp/tests/unittest_utils.py +468 -0
- warp/tests/walkthrough_debug.py +93 -0
- warp/thirdparty/__init__.py +0 -0
- warp/thirdparty/appdirs.py +598 -0
- warp/thirdparty/dlpack.py +145 -0
- warp/thirdparty/unittest_parallel.py +570 -0
- warp/torch.py +391 -0
- warp/types.py +5230 -0
- warp/utils.py +1137 -0
- warp_lang-1.7.0.dist-info/METADATA +516 -0
- warp_lang-1.7.0.dist-info/RECORD +429 -0
- warp_lang-1.7.0.dist-info/WHEEL +5 -0
- warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
- warp_lang-1.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# Example NanoVDB
|
|
18
|
+
#
|
|
19
|
+
# Shows how to implement a particle simulation with collision against
|
|
20
|
+
# a NanoVDB signed-distance field. In this example the NanoVDB field
|
|
21
|
+
# is created offline in Houdini. The particle kernel uses the Warp
|
|
22
|
+
# wp.volume_sample_f() method to compute the SDF and normal at a point.
|
|
23
|
+
#
|
|
24
|
+
###########################################################################
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
|
|
28
|
+
import numpy as np
|
|
29
|
+
|
|
30
|
+
import warp as wp
|
|
31
|
+
import warp.examples
|
|
32
|
+
import warp.render
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@wp.func
|
|
36
|
+
def volume_grad(volume: wp.uint64, p: wp.vec3):
|
|
37
|
+
eps = 1.0
|
|
38
|
+
q = wp.volume_world_to_index(volume, p)
|
|
39
|
+
|
|
40
|
+
# compute gradient of the SDF using finite differences
|
|
41
|
+
dx = wp.volume_sample_f(volume, q + wp.vec3(eps, 0.0, 0.0), wp.Volume.LINEAR) - wp.volume_sample_f(
|
|
42
|
+
volume, q - wp.vec3(eps, 0.0, 0.0), wp.Volume.LINEAR
|
|
43
|
+
)
|
|
44
|
+
dy = wp.volume_sample_f(volume, q + wp.vec3(0.0, eps, 0.0), wp.Volume.LINEAR) - wp.volume_sample_f(
|
|
45
|
+
volume, q - wp.vec3(0.0, eps, 0.0), wp.Volume.LINEAR
|
|
46
|
+
)
|
|
47
|
+
dz = wp.volume_sample_f(volume, q + wp.vec3(0.0, 0.0, eps), wp.Volume.LINEAR) - wp.volume_sample_f(
|
|
48
|
+
volume, q - wp.vec3(0.0, 0.0, eps), wp.Volume.LINEAR
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return wp.normalize(wp.vec3(dx, dy, dz))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@wp.kernel
|
|
55
|
+
def simulate(
|
|
56
|
+
positions: wp.array(dtype=wp.vec3),
|
|
57
|
+
velocities: wp.array(dtype=wp.vec3),
|
|
58
|
+
volume: wp.uint64,
|
|
59
|
+
margin: float,
|
|
60
|
+
dt: float,
|
|
61
|
+
):
|
|
62
|
+
tid = wp.tid()
|
|
63
|
+
|
|
64
|
+
x = positions[tid]
|
|
65
|
+
v = velocities[tid]
|
|
66
|
+
|
|
67
|
+
v = v + wp.vec3(0.0, -9.8, 0.0) * dt - v * 0.1 * dt
|
|
68
|
+
xpred = x + v * dt
|
|
69
|
+
xpred_local = wp.volume_world_to_index(volume, xpred)
|
|
70
|
+
|
|
71
|
+
# d = wp.volume_sample_f(volume, xpred_local, wp.Volume.LINEAR)
|
|
72
|
+
n = wp.vec3()
|
|
73
|
+
d = wp.volume_sample_grad_f(volume, xpred_local, wp.Volume.LINEAR, n)
|
|
74
|
+
|
|
75
|
+
if d < margin:
|
|
76
|
+
# n = volume_grad(volume, xpred)
|
|
77
|
+
n = wp.normalize(n)
|
|
78
|
+
err = d - margin
|
|
79
|
+
|
|
80
|
+
# mesh collision
|
|
81
|
+
xpred = xpred - n * err
|
|
82
|
+
|
|
83
|
+
# ground collision
|
|
84
|
+
if xpred[1] < 0.0:
|
|
85
|
+
xpred = wp.vec3(xpred[0], 0.0, xpred[2])
|
|
86
|
+
|
|
87
|
+
# pbd update
|
|
88
|
+
v = (xpred - x) * (1.0 / dt)
|
|
89
|
+
x = xpred
|
|
90
|
+
|
|
91
|
+
positions[tid] = x
|
|
92
|
+
velocities[tid] = v
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class Example:
|
|
96
|
+
def __init__(self, stage_path="example_nvdb.usd"):
|
|
97
|
+
rng = np.random.default_rng(42)
|
|
98
|
+
self.num_particles = 10000
|
|
99
|
+
|
|
100
|
+
fps = 60
|
|
101
|
+
frame_dt = 1.0 / fps
|
|
102
|
+
self.sim_substeps = 3
|
|
103
|
+
self.sim_dt = frame_dt / self.sim_substeps
|
|
104
|
+
|
|
105
|
+
self.sim_time = 0.0
|
|
106
|
+
self.sim_timers = {}
|
|
107
|
+
|
|
108
|
+
self.sim_margin = 0.15
|
|
109
|
+
|
|
110
|
+
init_pos = 10.0 * (rng.random((self.num_particles, 3)) * 2.0 - 1.0) + np.array((0.0, 30.0, 0.0))
|
|
111
|
+
init_vel = rng.random((self.num_particles, 3))
|
|
112
|
+
|
|
113
|
+
self.positions = wp.from_numpy(init_pos.astype(np.float32), dtype=wp.vec3)
|
|
114
|
+
self.velocities = wp.from_numpy(init_vel.astype(np.float32), dtype=wp.vec3)
|
|
115
|
+
|
|
116
|
+
# load collision volume
|
|
117
|
+
with open(os.path.join(warp.examples.get_asset_directory(), "rocks.nvdb"), "rb") as file:
|
|
118
|
+
# create Volume object
|
|
119
|
+
self.volume = wp.Volume.load_from_nvdb(file)
|
|
120
|
+
|
|
121
|
+
# renderer
|
|
122
|
+
self.renderer = None
|
|
123
|
+
if stage_path:
|
|
124
|
+
self.renderer = wp.render.UsdRenderer(stage_path)
|
|
125
|
+
self.renderer.render_ground(size=100.0)
|
|
126
|
+
|
|
127
|
+
def step(self):
|
|
128
|
+
with wp.ScopedTimer("step", dict=self.sim_timers):
|
|
129
|
+
for _ in range(self.sim_substeps):
|
|
130
|
+
wp.launch(
|
|
131
|
+
kernel=simulate,
|
|
132
|
+
dim=self.num_particles,
|
|
133
|
+
inputs=[self.positions, self.velocities, self.volume.id, self.sim_margin, self.sim_dt],
|
|
134
|
+
)
|
|
135
|
+
self.sim_time += self.sim_dt
|
|
136
|
+
|
|
137
|
+
def render(self):
|
|
138
|
+
if self.renderer is None:
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
with wp.ScopedTimer("render"):
|
|
142
|
+
self.renderer.begin_frame(self.sim_time)
|
|
143
|
+
|
|
144
|
+
self.renderer.render_ref(
|
|
145
|
+
name="collision",
|
|
146
|
+
path=os.path.join(warp.examples.get_asset_directory(), "rocks.usd"),
|
|
147
|
+
pos=wp.vec3(0.0, 0.0, 0.0),
|
|
148
|
+
rot=wp.quat(0.0, 0.0, 0.0, 1.0),
|
|
149
|
+
scale=wp.vec3(1.0, 1.0, 1.0),
|
|
150
|
+
color=(0.35, 0.55, 0.9),
|
|
151
|
+
)
|
|
152
|
+
self.renderer.render_points(
|
|
153
|
+
name="points", points=self.positions.numpy(), radius=self.sim_margin, colors=(0.8, 0.3, 0.2)
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
self.renderer.end_frame()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
import argparse
|
|
161
|
+
|
|
162
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
163
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
164
|
+
parser.add_argument(
|
|
165
|
+
"--stage_path",
|
|
166
|
+
type=lambda x: None if x == "None" else str(x),
|
|
167
|
+
default="example_nvdb.usd",
|
|
168
|
+
help="Path to the output USD file.",
|
|
169
|
+
)
|
|
170
|
+
parser.add_argument("--num_frames", type=int, default=1000, help="Total number of frames.")
|
|
171
|
+
|
|
172
|
+
args = parser.parse_known_args()[0]
|
|
173
|
+
|
|
174
|
+
with wp.ScopedDevice(args.device):
|
|
175
|
+
example = Example(stage_path=args.stage_path)
|
|
176
|
+
|
|
177
|
+
for _ in range(args.num_frames):
|
|
178
|
+
example.step()
|
|
179
|
+
example.render()
|
|
180
|
+
|
|
181
|
+
if example.renderer:
|
|
182
|
+
example.renderer.save()
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
#############################################################################
|
|
17
|
+
# Example Ray Cast
|
|
18
|
+
#
|
|
19
|
+
# Shows how to use the built-in wp.Mesh data structure and wp.mesh_query_ray()
|
|
20
|
+
# function to implement a basic ray-tracer.
|
|
21
|
+
#
|
|
22
|
+
##############################################################################
|
|
23
|
+
|
|
24
|
+
import os
|
|
25
|
+
|
|
26
|
+
import numpy as np
|
|
27
|
+
from pxr import Usd, UsdGeom
|
|
28
|
+
|
|
29
|
+
import warp as wp
|
|
30
|
+
import warp.examples
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@wp.kernel
|
|
34
|
+
def draw(mesh: wp.uint64, cam_pos: wp.vec3, width: int, height: int, pixels: wp.array(dtype=wp.vec3)):
|
|
35
|
+
tid = wp.tid()
|
|
36
|
+
|
|
37
|
+
x = tid % width
|
|
38
|
+
y = tid // width
|
|
39
|
+
|
|
40
|
+
sx = 2.0 * float(x) / float(height) - 1.0
|
|
41
|
+
sy = 2.0 * float(y) / float(height) - 1.0
|
|
42
|
+
|
|
43
|
+
# compute view ray
|
|
44
|
+
ro = cam_pos
|
|
45
|
+
rd = wp.normalize(wp.vec3(sx, sy, -1.0))
|
|
46
|
+
|
|
47
|
+
color = wp.vec3(0.0, 0.0, 0.0)
|
|
48
|
+
|
|
49
|
+
query = wp.mesh_query_ray(mesh, ro, rd, 1.0e6)
|
|
50
|
+
if query.result:
|
|
51
|
+
color = query.normal * 0.5 + wp.vec3(0.5, 0.5, 0.5)
|
|
52
|
+
|
|
53
|
+
pixels[tid] = color
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Example:
|
|
57
|
+
def __init__(self, height=1024, width=1024):
|
|
58
|
+
self.height = height
|
|
59
|
+
self.width = width
|
|
60
|
+
self.cam_pos = (0.0, 1.0, 2.0)
|
|
61
|
+
|
|
62
|
+
asset_stage = Usd.Stage.Open(os.path.join(warp.examples.get_asset_directory(), "bunny.usd"))
|
|
63
|
+
mesh_geom = UsdGeom.Mesh(asset_stage.GetPrimAtPath("/root/bunny"))
|
|
64
|
+
|
|
65
|
+
points = np.array(mesh_geom.GetPointsAttr().Get())
|
|
66
|
+
indices = np.array(mesh_geom.GetFaceVertexIndicesAttr().Get())
|
|
67
|
+
|
|
68
|
+
self.pixels = wp.zeros(self.width * self.height, dtype=wp.vec3)
|
|
69
|
+
|
|
70
|
+
# create wp mesh
|
|
71
|
+
self.mesh = wp.Mesh(
|
|
72
|
+
points=wp.array(points, dtype=wp.vec3), velocities=None, indices=wp.array(indices, dtype=int)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def render(self):
|
|
76
|
+
with wp.ScopedTimer("render"):
|
|
77
|
+
wp.launch(
|
|
78
|
+
kernel=draw,
|
|
79
|
+
dim=self.width * self.height,
|
|
80
|
+
inputs=[self.mesh.id, self.cam_pos, self.width, self.height, self.pixels],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
import argparse
|
|
86
|
+
|
|
87
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
88
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
89
|
+
parser.add_argument("--width", type=int, default=1024, help="Output image width in pixels.")
|
|
90
|
+
parser.add_argument("--height", type=int, default=1024, help="Output image height in pixels.")
|
|
91
|
+
parser.add_argument(
|
|
92
|
+
"--headless",
|
|
93
|
+
action="store_true",
|
|
94
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
args = parser.parse_known_args()[0]
|
|
98
|
+
|
|
99
|
+
with wp.ScopedDevice(args.device):
|
|
100
|
+
example = Example(height=args.height, width=args.width)
|
|
101
|
+
example.render()
|
|
102
|
+
|
|
103
|
+
if not args.headless:
|
|
104
|
+
import matplotlib.pyplot as plt
|
|
105
|
+
|
|
106
|
+
plt.imshow(
|
|
107
|
+
example.pixels.numpy().reshape((example.height, example.width, 3)),
|
|
108
|
+
origin="lower",
|
|
109
|
+
interpolation="antialiased",
|
|
110
|
+
)
|
|
111
|
+
plt.show()
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# Example Ray March
|
|
18
|
+
#
|
|
19
|
+
# Shows how to implement an SDF ray marching based renderer. Please see
|
|
20
|
+
# https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
|
|
21
|
+
# for reference on different distance functions.
|
|
22
|
+
#
|
|
23
|
+
###########################################################################
|
|
24
|
+
|
|
25
|
+
import warp as wp
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@wp.func
|
|
29
|
+
def sdf_sphere(p: wp.vec3, r: float):
|
|
30
|
+
return wp.length(p) - r
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@wp.func
|
|
34
|
+
def sdf_box(upper: wp.vec3, p: wp.vec3):
|
|
35
|
+
qx = wp.abs(p[0]) - upper[0]
|
|
36
|
+
qy = wp.abs(p[1]) - upper[1]
|
|
37
|
+
qz = wp.abs(p[2]) - upper[2]
|
|
38
|
+
|
|
39
|
+
e = wp.vec3(wp.max(qx, 0.0), wp.max(qy, 0.0), wp.max(qz, 0.0))
|
|
40
|
+
|
|
41
|
+
return wp.length(e) + wp.min(wp.max(qx, wp.max(qy, qz)), 0.0)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@wp.func
|
|
45
|
+
def sdf_plane(p: wp.vec3, plane: wp.vec4):
|
|
46
|
+
return plane[0] * p[0] + plane[1] * p[1] + plane[2] * p[2] + plane[3]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@wp.func
|
|
50
|
+
def op_union(d1: float, d2: float):
|
|
51
|
+
return wp.min(d1, d2)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@wp.func
|
|
55
|
+
def op_subtract(d1: float, d2: float):
|
|
56
|
+
return wp.max(-d1, d2)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@wp.func
|
|
60
|
+
def op_intersect(d1: float, d2: float):
|
|
61
|
+
return wp.max(d1, d2)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# simple scene
|
|
65
|
+
@wp.func
|
|
66
|
+
def sdf(p: wp.vec3):
|
|
67
|
+
sphere_1 = wp.vec3(0.0, 0.75, 0.0)
|
|
68
|
+
|
|
69
|
+
d = op_subtract(sdf_sphere(p - sphere_1, 0.75), sdf_box(wp.vec3(1.0, 0.5, 0.5), p))
|
|
70
|
+
|
|
71
|
+
# ground plane
|
|
72
|
+
d = op_union(d, sdf_plane(p, wp.vec4(0.0, 1.0, 0.0, 1.0)))
|
|
73
|
+
|
|
74
|
+
return d
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@wp.func
|
|
78
|
+
def normal(p: wp.vec3):
|
|
79
|
+
eps = 1.0e-5
|
|
80
|
+
|
|
81
|
+
# compute gradient of the SDF using finite differences
|
|
82
|
+
dx = sdf(p + wp.vec3(eps, 0.0, 0.0)) - sdf(p - wp.vec3(eps, 0.0, 0.0))
|
|
83
|
+
dy = sdf(p + wp.vec3(0.0, eps, 0.0)) - sdf(p - wp.vec3(0.0, eps, 0.0))
|
|
84
|
+
dz = sdf(p + wp.vec3(0.0, 0.0, eps)) - sdf(p - wp.vec3(0.0, 0.0, eps))
|
|
85
|
+
|
|
86
|
+
return wp.normalize(wp.vec3(dx, dy, dz))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@wp.func
|
|
90
|
+
def shadow(ro: wp.vec3, rd: wp.vec3):
|
|
91
|
+
t = float(0.0)
|
|
92
|
+
s = float(1.0)
|
|
93
|
+
|
|
94
|
+
for _ in range(64):
|
|
95
|
+
d = sdf(ro + t * rd)
|
|
96
|
+
t = t + wp.clamp(d, 0.0001, 2.0)
|
|
97
|
+
|
|
98
|
+
h = wp.clamp(4.0 * d / t, 0.0, 1.0)
|
|
99
|
+
s = wp.min(s, h * h * (3.0 - 2.0 * h))
|
|
100
|
+
|
|
101
|
+
if t > 8.0:
|
|
102
|
+
return 1.0
|
|
103
|
+
|
|
104
|
+
return s
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@wp.kernel
|
|
108
|
+
def draw(cam_pos: wp.vec3, cam_rot: wp.quat, width: int, height: int, pixels: wp.array(dtype=wp.vec3)):
|
|
109
|
+
tid = wp.tid()
|
|
110
|
+
|
|
111
|
+
x = tid % width
|
|
112
|
+
y = tid // width
|
|
113
|
+
|
|
114
|
+
# compute pixel coordinates
|
|
115
|
+
sx = (2.0 * float(x) - float(width)) / float(height)
|
|
116
|
+
sy = (2.0 * float(y) - float(height)) / float(height)
|
|
117
|
+
|
|
118
|
+
# compute view ray
|
|
119
|
+
ro = cam_pos
|
|
120
|
+
rd = wp.quat_rotate(cam_rot, wp.normalize(wp.vec3(sx, sy, -2.0)))
|
|
121
|
+
|
|
122
|
+
t = float(0.0)
|
|
123
|
+
|
|
124
|
+
# ray march
|
|
125
|
+
for _ in range(128):
|
|
126
|
+
d = sdf(ro + rd * t)
|
|
127
|
+
t = t + d
|
|
128
|
+
|
|
129
|
+
if d < 0.01:
|
|
130
|
+
p = ro + rd * t
|
|
131
|
+
n = normal(p)
|
|
132
|
+
l = wp.normalize(wp.vec3(0.6, 0.4, 0.5))
|
|
133
|
+
|
|
134
|
+
# half-vector
|
|
135
|
+
h = wp.normalize(l - rd)
|
|
136
|
+
|
|
137
|
+
diffuse = wp.dot(n, l)
|
|
138
|
+
specular = wp.clamp(wp.dot(n, h), 0.0, 1.0) ** 80.0
|
|
139
|
+
fresnel = 0.04 + 0.96 * wp.clamp(1.0 - wp.dot(h, l), 0.0, 1.0) ** 5.0
|
|
140
|
+
|
|
141
|
+
intensity = 2.0
|
|
142
|
+
result = (
|
|
143
|
+
wp.vec3(0.85, 0.9, 0.95)
|
|
144
|
+
* (diffuse * (1.0 - fresnel) + specular * fresnel * 10.0)
|
|
145
|
+
* shadow(p, l)
|
|
146
|
+
* intensity
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# gamma
|
|
150
|
+
pixels[tid] = wp.vec3(
|
|
151
|
+
wp.clamp(result[0] ** 2.2, 0.0, 1.0),
|
|
152
|
+
wp.clamp(result[1] ** 2.2, 0.0, 1.0),
|
|
153
|
+
wp.clamp(result[2] ** 2.2, 0.0, 1.0),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
else:
|
|
157
|
+
pixels[tid] = wp.vec3(0.4, 0.45, 0.5) * 1.5
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class Example:
|
|
161
|
+
def __init__(self, height=1024, width=2048):
|
|
162
|
+
self.width = width
|
|
163
|
+
self.height = height
|
|
164
|
+
self.cam_pos = (-1.25, 1.0, 2.0)
|
|
165
|
+
self.cam_rot = wp.quat_rpy(-0.5, -0.5, 0.0)
|
|
166
|
+
|
|
167
|
+
self.pixels = wp.zeros(self.width * self.height, dtype=wp.vec3)
|
|
168
|
+
|
|
169
|
+
def render(self):
|
|
170
|
+
with wp.ScopedTimer("render"):
|
|
171
|
+
wp.launch(
|
|
172
|
+
kernel=draw,
|
|
173
|
+
dim=self.width * self.height,
|
|
174
|
+
inputs=[self.cam_pos, self.cam_rot, self.width, self.height, self.pixels],
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
if __name__ == "__main__":
|
|
179
|
+
import argparse
|
|
180
|
+
|
|
181
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
182
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
183
|
+
parser.add_argument(
|
|
184
|
+
"--headless",
|
|
185
|
+
action="store_true",
|
|
186
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
187
|
+
)
|
|
188
|
+
parser.add_argument("--width", type=int, default=2048, help="Output image width in pixels.")
|
|
189
|
+
parser.add_argument("--height", type=int, default=1024, help="Output image height in pixels.")
|
|
190
|
+
|
|
191
|
+
args = parser.parse_known_args()[0]
|
|
192
|
+
|
|
193
|
+
with wp.ScopedDevice(args.device):
|
|
194
|
+
example = Example(height=args.height, width=args.width)
|
|
195
|
+
example.render()
|
|
196
|
+
|
|
197
|
+
if not args.headless:
|
|
198
|
+
import matplotlib.pyplot as plt
|
|
199
|
+
|
|
200
|
+
plt.imshow(
|
|
201
|
+
example.pixels.numpy().reshape((example.height, example.width, 3)),
|
|
202
|
+
origin="lower",
|
|
203
|
+
interpolation="antialiased",
|
|
204
|
+
)
|
|
205
|
+
plt.show()
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# OpenGL renderer example
|
|
18
|
+
#
|
|
19
|
+
# Demonstrates how to set up tiled rendering and retrieves the pixels from
|
|
20
|
+
# OpenGLRenderer as a Warp array while keeping all memory on the GPU.
|
|
21
|
+
#
|
|
22
|
+
###########################################################################
|
|
23
|
+
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
import warp as wp
|
|
27
|
+
import warp.render
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Example:
|
|
31
|
+
def __init__(self, num_tiles=4, custom_tile_arrangement=False):
|
|
32
|
+
if num_tiles < 1:
|
|
33
|
+
raise ValueError("num_tiles must be greater than or equal to 1.")
|
|
34
|
+
|
|
35
|
+
self.renderer = wp.render.OpenGLRenderer(vsync=False)
|
|
36
|
+
instance_ids = []
|
|
37
|
+
|
|
38
|
+
if custom_tile_arrangement:
|
|
39
|
+
positions = []
|
|
40
|
+
sizes = []
|
|
41
|
+
else:
|
|
42
|
+
positions = None
|
|
43
|
+
sizes = None
|
|
44
|
+
|
|
45
|
+
# set up instances to hide one of the capsules in each tile
|
|
46
|
+
for i in range(num_tiles):
|
|
47
|
+
instances = [j for j in np.arange(13) if j != i + 2]
|
|
48
|
+
instance_ids.append(instances)
|
|
49
|
+
if custom_tile_arrangement:
|
|
50
|
+
angle = np.pi * 2.0 / num_tiles * i
|
|
51
|
+
positions.append((int(np.cos(angle) * 150 + 250), int(np.sin(angle) * 150 + 250)))
|
|
52
|
+
sizes.append((150, 150))
|
|
53
|
+
self.renderer.setup_tiled_rendering(instance_ids, tile_positions=positions, tile_sizes=sizes)
|
|
54
|
+
|
|
55
|
+
self.renderer.render_ground()
|
|
56
|
+
|
|
57
|
+
def render(self):
|
|
58
|
+
time = self.renderer.clock_time
|
|
59
|
+
self.renderer.begin_frame(time)
|
|
60
|
+
for i in range(10):
|
|
61
|
+
self.renderer.render_capsule(
|
|
62
|
+
f"capsule_{i}",
|
|
63
|
+
[i - 5.0, np.sin(time + i * 0.2), -3.0],
|
|
64
|
+
[0.0, 0.0, 0.0, 1.0],
|
|
65
|
+
radius=0.5,
|
|
66
|
+
half_height=0.8,
|
|
67
|
+
)
|
|
68
|
+
self.renderer.render_cylinder(
|
|
69
|
+
"cylinder",
|
|
70
|
+
[3.2, 1.0, np.sin(time + 0.5)],
|
|
71
|
+
np.array(wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), wp.sin(time + 0.5))),
|
|
72
|
+
radius=0.5,
|
|
73
|
+
half_height=0.8,
|
|
74
|
+
)
|
|
75
|
+
self.renderer.render_cone(
|
|
76
|
+
"cone",
|
|
77
|
+
[-1.2, 1.0, 0.0],
|
|
78
|
+
np.array(wp.quat_from_axis_angle(wp.vec3(0.707, 0.707, 0.0), time)),
|
|
79
|
+
radius=0.5,
|
|
80
|
+
half_height=0.8,
|
|
81
|
+
)
|
|
82
|
+
self.renderer.end_frame()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == "__main__":
|
|
86
|
+
import argparse
|
|
87
|
+
import distutils.util
|
|
88
|
+
|
|
89
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
90
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
91
|
+
parser.add_argument("--num_tiles", type=int, default=4, help="Number of viewports to render in a single frame.")
|
|
92
|
+
parser.add_argument(
|
|
93
|
+
"--show_plot",
|
|
94
|
+
type=lambda x: bool(distutils.util.strtobool(x.strip())),
|
|
95
|
+
default=True,
|
|
96
|
+
help="Display the pixels in an additional matplotlib figure.",
|
|
97
|
+
)
|
|
98
|
+
parser.add_argument("--render_mode", type=str, choices=("depth", "rgb"), default="depth", help="")
|
|
99
|
+
parser.add_argument(
|
|
100
|
+
"--split_up_tiles",
|
|
101
|
+
type=lambda x: bool(distutils.util.strtobool(x.strip())),
|
|
102
|
+
default=True,
|
|
103
|
+
help="Whether to split tiles into subplots when --show_plot is True.",
|
|
104
|
+
)
|
|
105
|
+
parser.add_argument("--custom_tile_arrangement", action="store_true", help="Apply custom tile arrangement.")
|
|
106
|
+
|
|
107
|
+
args = parser.parse_known_args()[0]
|
|
108
|
+
|
|
109
|
+
with wp.ScopedDevice(args.device):
|
|
110
|
+
example = Example(num_tiles=args.num_tiles, custom_tile_arrangement=args.custom_tile_arrangement)
|
|
111
|
+
|
|
112
|
+
channels = 1 if args.render_mode == "depth" else 3
|
|
113
|
+
|
|
114
|
+
if args.show_plot:
|
|
115
|
+
import matplotlib.pyplot as plt
|
|
116
|
+
|
|
117
|
+
if args.split_up_tiles:
|
|
118
|
+
pixels = wp.zeros(
|
|
119
|
+
(args.num_tiles, example.renderer.tile_height, example.renderer.tile_width, channels),
|
|
120
|
+
dtype=wp.float32,
|
|
121
|
+
)
|
|
122
|
+
ncols = int(np.ceil(np.sqrt(args.num_tiles)))
|
|
123
|
+
nrows = int(np.ceil(args.num_tiles / float(ncols)))
|
|
124
|
+
img_plots = []
|
|
125
|
+
aspect_ratio = example.renderer.tile_height / example.renderer.tile_width
|
|
126
|
+
fig, axes = plt.subplots(
|
|
127
|
+
ncols=ncols,
|
|
128
|
+
nrows=nrows,
|
|
129
|
+
constrained_layout=True,
|
|
130
|
+
figsize=(ncols * 3.5, nrows * 3.5 * aspect_ratio),
|
|
131
|
+
squeeze=False,
|
|
132
|
+
sharex=True,
|
|
133
|
+
sharey=True,
|
|
134
|
+
num=1,
|
|
135
|
+
)
|
|
136
|
+
tile_temp = np.zeros(
|
|
137
|
+
(example.renderer.tile_height, example.renderer.tile_width, channels), dtype=np.float32
|
|
138
|
+
)
|
|
139
|
+
for dim in range(ncols * nrows):
|
|
140
|
+
ax = axes[dim // ncols, dim % ncols]
|
|
141
|
+
if dim >= args.num_tiles:
|
|
142
|
+
ax.axis("off")
|
|
143
|
+
continue
|
|
144
|
+
if args.render_mode == "depth":
|
|
145
|
+
img_plots.append(
|
|
146
|
+
ax.imshow(
|
|
147
|
+
tile_temp,
|
|
148
|
+
vmin=example.renderer.camera_near_plane,
|
|
149
|
+
vmax=example.renderer.camera_far_plane,
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
else:
|
|
153
|
+
img_plots.append(ax.imshow(tile_temp))
|
|
154
|
+
else:
|
|
155
|
+
fig = plt.figure(1)
|
|
156
|
+
pixels = wp.zeros(
|
|
157
|
+
(example.renderer.screen_height, example.renderer.screen_width, channels), dtype=wp.float32
|
|
158
|
+
)
|
|
159
|
+
if args.render_mode == "depth":
|
|
160
|
+
img_plot = plt.imshow(
|
|
161
|
+
pixels.numpy(), vmin=example.renderer.camera_near_plane, vmax=example.renderer.camera_far_plane
|
|
162
|
+
)
|
|
163
|
+
else:
|
|
164
|
+
img_plot = plt.imshow(pixels.numpy())
|
|
165
|
+
|
|
166
|
+
plt.ion()
|
|
167
|
+
plt.show()
|
|
168
|
+
|
|
169
|
+
while example.renderer.is_running():
|
|
170
|
+
example.render()
|
|
171
|
+
|
|
172
|
+
if args.show_plot and plt.fignum_exists(1):
|
|
173
|
+
if args.split_up_tiles:
|
|
174
|
+
pixel_shape = (args.num_tiles, example.renderer.tile_height, example.renderer.tile_width, channels)
|
|
175
|
+
else:
|
|
176
|
+
pixel_shape = (example.renderer.screen_height, example.renderer.screen_width, channels)
|
|
177
|
+
|
|
178
|
+
if pixel_shape != pixels.shape:
|
|
179
|
+
# make sure we resize the pixels array to the right dimensions if the user resizes the window
|
|
180
|
+
pixels = wp.zeros(pixel_shape, dtype=wp.float32)
|
|
181
|
+
|
|
182
|
+
example.renderer.get_pixels(pixels, split_up_tiles=args.split_up_tiles, mode=args.render_mode)
|
|
183
|
+
|
|
184
|
+
if args.split_up_tiles:
|
|
185
|
+
pixels_np = pixels.numpy()
|
|
186
|
+
for i, img_plot in enumerate(img_plots):
|
|
187
|
+
img_plot.set_data(pixels_np[i])
|
|
188
|
+
else:
|
|
189
|
+
img_plot.set_data(pixels.numpy())
|
|
190
|
+
fig.canvas.draw()
|
|
191
|
+
fig.canvas.flush_events()
|
|
192
|
+
|
|
193
|
+
example.renderer.clear()
|