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

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

Potentially problematic release.


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

Files changed (300) hide show
  1. warp/__init__.py +10 -4
  2. warp/__init__.pyi +1 -0
  3. warp/bin/warp-clang.dll +0 -0
  4. warp/bin/warp.dll +0 -0
  5. warp/build.py +5 -3
  6. warp/build_dll.py +29 -9
  7. warp/builtins.py +868 -507
  8. warp/codegen.py +1074 -638
  9. warp/config.py +3 -3
  10. warp/constants.py +6 -0
  11. warp/context.py +715 -222
  12. warp/fabric.py +326 -0
  13. warp/fem/__init__.py +27 -0
  14. warp/fem/cache.py +389 -0
  15. warp/fem/dirichlet.py +181 -0
  16. warp/fem/domain.py +263 -0
  17. warp/fem/field/__init__.py +101 -0
  18. warp/fem/field/field.py +149 -0
  19. warp/fem/field/nodal_field.py +299 -0
  20. warp/fem/field/restriction.py +21 -0
  21. warp/fem/field/test.py +181 -0
  22. warp/fem/field/trial.py +183 -0
  23. warp/fem/geometry/__init__.py +19 -0
  24. warp/fem/geometry/closest_point.py +70 -0
  25. warp/fem/geometry/deformed_geometry.py +271 -0
  26. warp/fem/geometry/element.py +744 -0
  27. warp/fem/geometry/geometry.py +186 -0
  28. warp/fem/geometry/grid_2d.py +373 -0
  29. warp/fem/geometry/grid_3d.py +435 -0
  30. warp/fem/geometry/hexmesh.py +953 -0
  31. warp/fem/geometry/partition.py +376 -0
  32. warp/fem/geometry/quadmesh_2d.py +532 -0
  33. warp/fem/geometry/tetmesh.py +840 -0
  34. warp/fem/geometry/trimesh_2d.py +577 -0
  35. warp/fem/integrate.py +1616 -0
  36. warp/fem/operator.py +191 -0
  37. warp/fem/polynomial.py +213 -0
  38. warp/fem/quadrature/__init__.py +2 -0
  39. warp/fem/quadrature/pic_quadrature.py +245 -0
  40. warp/fem/quadrature/quadrature.py +294 -0
  41. warp/fem/space/__init__.py +292 -0
  42. warp/fem/space/basis_space.py +489 -0
  43. warp/fem/space/collocated_function_space.py +105 -0
  44. warp/fem/space/dof_mapper.py +236 -0
  45. warp/fem/space/function_space.py +145 -0
  46. warp/fem/space/grid_2d_function_space.py +267 -0
  47. warp/fem/space/grid_3d_function_space.py +306 -0
  48. warp/fem/space/hexmesh_function_space.py +352 -0
  49. warp/fem/space/partition.py +350 -0
  50. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  51. warp/fem/space/restriction.py +160 -0
  52. warp/fem/space/shape/__init__.py +15 -0
  53. warp/fem/space/shape/cube_shape_function.py +738 -0
  54. warp/fem/space/shape/shape_function.py +103 -0
  55. warp/fem/space/shape/square_shape_function.py +611 -0
  56. warp/fem/space/shape/tet_shape_function.py +567 -0
  57. warp/fem/space/shape/triangle_shape_function.py +429 -0
  58. warp/fem/space/tetmesh_function_space.py +292 -0
  59. warp/fem/space/topology.py +295 -0
  60. warp/fem/space/trimesh_2d_function_space.py +221 -0
  61. warp/fem/types.py +77 -0
  62. warp/fem/utils.py +495 -0
  63. warp/native/array.h +147 -44
  64. warp/native/builtin.h +122 -149
  65. warp/native/bvh.cpp +73 -325
  66. warp/native/bvh.cu +406 -23
  67. warp/native/bvh.h +34 -43
  68. warp/native/clang/clang.cpp +13 -8
  69. warp/native/crt.h +2 -0
  70. warp/native/cuda_crt.h +5 -0
  71. warp/native/cuda_util.cpp +15 -3
  72. warp/native/cuda_util.h +3 -1
  73. warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
  74. warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
  75. warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
  76. warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
  77. warp/native/cutlass/tools/library/scripts/library.py +799 -0
  78. warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
  79. warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
  80. warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
  81. warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
  82. warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
  83. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
  84. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
  85. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
  86. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
  87. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
  88. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
  89. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
  90. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
  91. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
  92. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
  93. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
  94. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
  95. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
  96. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
  97. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
  98. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
  99. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
  100. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
  101. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
  102. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
  103. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
  104. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
  105. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
  106. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
  107. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
  108. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
  109. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
  110. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
  111. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
  112. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
  113. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
  114. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
  115. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  116. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  117. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
  118. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
  119. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
  120. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  121. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  122. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
  123. warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
  124. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
  125. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
  126. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
  127. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
  128. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
  129. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
  130. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
  131. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
  132. warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
  133. warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
  134. warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
  135. warp/native/cutlass/tools/library/scripts/rt.py +796 -0
  136. warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
  137. warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
  138. warp/native/cutlass_gemm.cu +5 -3
  139. warp/native/exports.h +1240 -952
  140. warp/native/fabric.h +228 -0
  141. warp/native/hashgrid.cpp +4 -4
  142. warp/native/hashgrid.h +22 -2
  143. warp/native/intersect.h +22 -7
  144. warp/native/intersect_adj.h +8 -8
  145. warp/native/intersect_tri.h +1 -1
  146. warp/native/marching.cu +157 -161
  147. warp/native/mat.h +80 -19
  148. warp/native/matnn.h +2 -2
  149. warp/native/mesh.cpp +33 -108
  150. warp/native/mesh.cu +114 -23
  151. warp/native/mesh.h +446 -46
  152. warp/native/noise.h +272 -329
  153. warp/native/quat.h +51 -8
  154. warp/native/rand.h +45 -35
  155. warp/native/range.h +6 -2
  156. warp/native/reduce.cpp +1 -1
  157. warp/native/reduce.cu +10 -12
  158. warp/native/runlength_encode.cu +6 -10
  159. warp/native/scan.cu +8 -11
  160. warp/native/sparse.cpp +4 -4
  161. warp/native/sparse.cu +164 -154
  162. warp/native/spatial.h +2 -2
  163. warp/native/temp_buffer.h +14 -30
  164. warp/native/vec.h +107 -23
  165. warp/native/volume.h +120 -0
  166. warp/native/warp.cpp +560 -30
  167. warp/native/warp.cu +431 -44
  168. warp/native/warp.h +13 -4
  169. warp/optim/__init__.py +1 -0
  170. warp/optim/linear.py +922 -0
  171. warp/optim/sgd.py +92 -0
  172. warp/render/render_opengl.py +335 -119
  173. warp/render/render_usd.py +11 -11
  174. warp/sim/__init__.py +2 -2
  175. warp/sim/articulation.py +385 -185
  176. warp/sim/collide.py +8 -0
  177. warp/sim/import_mjcf.py +297 -106
  178. warp/sim/import_urdf.py +389 -210
  179. warp/sim/import_usd.py +198 -97
  180. warp/sim/inertia.py +17 -18
  181. warp/sim/integrator_euler.py +14 -8
  182. warp/sim/integrator_xpbd.py +158 -16
  183. warp/sim/model.py +795 -291
  184. warp/sim/render.py +3 -3
  185. warp/sim/utils.py +3 -0
  186. warp/sparse.py +640 -150
  187. warp/stubs.py +606 -267
  188. warp/tape.py +61 -10
  189. warp/tests/__main__.py +3 -6
  190. warp/tests/assets/curlnoise_golden.npy +0 -0
  191. warp/tests/assets/pnoise_golden.npy +0 -0
  192. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  193. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  194. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  195. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  196. warp/tests/aux_test_unresolved_func.py +14 -0
  197. warp/tests/aux_test_unresolved_symbol.py +14 -0
  198. warp/tests/disabled_kinematics.py +239 -0
  199. warp/tests/run_coverage_serial.py +31 -0
  200. warp/tests/test_adam.py +103 -106
  201. warp/tests/test_arithmetic.py +128 -74
  202. warp/tests/test_array.py +212 -97
  203. warp/tests/test_array_reduce.py +57 -23
  204. warp/tests/test_atomic.py +64 -28
  205. warp/tests/test_bool.py +99 -0
  206. warp/tests/test_builtins_resolution.py +1292 -0
  207. warp/tests/test_bvh.py +42 -18
  208. warp/tests/test_closest_point_edge_edge.py +54 -57
  209. warp/tests/test_codegen.py +208 -130
  210. warp/tests/test_compile_consts.py +28 -20
  211. warp/tests/test_conditional.py +108 -24
  212. warp/tests/test_copy.py +10 -12
  213. warp/tests/test_ctypes.py +112 -88
  214. warp/tests/test_dense.py +21 -14
  215. warp/tests/test_devices.py +98 -0
  216. warp/tests/test_dlpack.py +75 -75
  217. warp/tests/test_examples.py +277 -0
  218. warp/tests/test_fabricarray.py +955 -0
  219. warp/tests/test_fast_math.py +15 -11
  220. warp/tests/test_fem.py +1271 -0
  221. warp/tests/test_fp16.py +53 -19
  222. warp/tests/test_func.py +187 -86
  223. warp/tests/test_generics.py +194 -49
  224. warp/tests/test_grad.py +178 -109
  225. warp/tests/test_grad_customs.py +176 -0
  226. warp/tests/test_hash_grid.py +52 -37
  227. warp/tests/test_import.py +10 -23
  228. warp/tests/test_indexedarray.py +32 -31
  229. warp/tests/test_intersect.py +18 -9
  230. warp/tests/test_large.py +141 -0
  231. warp/tests/test_launch.py +14 -41
  232. warp/tests/test_lerp.py +64 -65
  233. warp/tests/test_linear_solvers.py +154 -0
  234. warp/tests/test_lvalue.py +493 -0
  235. warp/tests/test_marching_cubes.py +12 -13
  236. warp/tests/test_mat.py +517 -2898
  237. warp/tests/test_mat_lite.py +115 -0
  238. warp/tests/test_mat_scalar_ops.py +2889 -0
  239. warp/tests/test_math.py +103 -9
  240. warp/tests/test_matmul.py +305 -69
  241. warp/tests/test_matmul_lite.py +410 -0
  242. warp/tests/test_mesh.py +71 -14
  243. warp/tests/test_mesh_query_aabb.py +41 -25
  244. warp/tests/test_mesh_query_point.py +140 -22
  245. warp/tests/test_mesh_query_ray.py +39 -22
  246. warp/tests/test_mlp.py +30 -22
  247. warp/tests/test_model.py +92 -89
  248. warp/tests/test_modules_lite.py +39 -0
  249. warp/tests/test_multigpu.py +88 -114
  250. warp/tests/test_noise.py +12 -11
  251. warp/tests/test_operators.py +16 -20
  252. warp/tests/test_options.py +11 -11
  253. warp/tests/test_pinned.py +17 -18
  254. warp/tests/test_print.py +32 -11
  255. warp/tests/test_quat.py +275 -129
  256. warp/tests/test_rand.py +18 -16
  257. warp/tests/test_reload.py +38 -34
  258. warp/tests/test_rounding.py +50 -43
  259. warp/tests/test_runlength_encode.py +168 -20
  260. warp/tests/test_smoothstep.py +9 -11
  261. warp/tests/test_snippet.py +143 -0
  262. warp/tests/test_sparse.py +261 -63
  263. warp/tests/test_spatial.py +276 -243
  264. warp/tests/test_streams.py +110 -85
  265. warp/tests/test_struct.py +268 -63
  266. warp/tests/test_tape.py +39 -21
  267. warp/tests/test_torch.py +118 -89
  268. warp/tests/test_transient_module.py +12 -13
  269. warp/tests/test_types.py +614 -0
  270. warp/tests/test_utils.py +494 -0
  271. warp/tests/test_vec.py +354 -2050
  272. warp/tests/test_vec_lite.py +73 -0
  273. warp/tests/test_vec_scalar_ops.py +2099 -0
  274. warp/tests/test_volume.py +457 -293
  275. warp/tests/test_volume_write.py +124 -134
  276. warp/tests/unittest_serial.py +35 -0
  277. warp/tests/unittest_suites.py +341 -0
  278. warp/tests/unittest_utils.py +568 -0
  279. warp/tests/unused_test_misc.py +71 -0
  280. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  281. warp/thirdparty/appdirs.py +36 -45
  282. warp/thirdparty/unittest_parallel.py +549 -0
  283. warp/torch.py +9 -6
  284. warp/types.py +1089 -366
  285. warp/utils.py +93 -387
  286. warp_lang-0.11.0.dist-info/METADATA +238 -0
  287. warp_lang-0.11.0.dist-info/RECORD +332 -0
  288. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
  289. warp/tests/test_all.py +0 -219
  290. warp/tests/test_array_scan.py +0 -60
  291. warp/tests/test_base.py +0 -208
  292. warp/tests/test_unresolved_func.py +0 -7
  293. warp/tests/test_unresolved_symbol.py +0 -7
  294. warp_lang-0.10.1.dist-info/METADATA +0 -21
  295. warp_lang-0.10.1.dist-info/RECORD +0 -188
  296. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  297. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  298. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  299. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/LICENSE.md +0 -0
  300. {warp_lang-0.10.1.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
@@ -13,12 +13,14 @@ from .utils import tab10_color_map
13
13
 
14
14
  from collections import defaultdict
15
15
  from typing import List, Tuple, Union, Optional
16
+ from enum import Enum
16
17
 
17
18
  import numpy as np
18
19
  import ctypes
19
20
 
20
21
  Mat44 = Union[List[float], List[List[float]], np.ndarray]
21
22
 
23
+
22
24
  wp.set_module_options({"enable_backward": False})
23
25
 
24
26
  shape_vertex_shader = """
@@ -175,12 +177,13 @@ in vec2 TexCoord;
175
177
 
176
178
  uniform vec3 color1;
177
179
  uniform vec3 color2;
180
+ uniform float farPlane;
178
181
 
179
182
  uniform vec3 sunDirection;
180
183
 
181
184
  void main()
182
185
  {
183
- float y = tanh(FragPos.y*0.01)*0.5+0.5;
186
+ float y = tanh(FragPos.y/farPlane*10.0)*0.5+0.5;
184
187
  float height = sqrt(1.0-y);
185
188
 
186
189
  float s = pow(0.5, 1.0 / 10.0);
@@ -222,6 +225,42 @@ void main() {
222
225
  }
223
226
  """
224
227
 
228
+ frame_depth_fragment_shader = """
229
+ #version 330 core
230
+ in vec2 TexCoord;
231
+
232
+ out vec4 FragColor;
233
+
234
+ uniform sampler2D textureSampler;
235
+
236
+ vec3 bourkeColorMap(float v) {
237
+ vec3 c = vec3(1.0, 1.0, 1.0);
238
+
239
+ v = clamp(v, 0.0, 1.0); // Ensures v is between 0 and 1
240
+
241
+ if (v < 0.25) {
242
+ c.r = 0.0;
243
+ c.g = 4.0 * v;
244
+ } else if (v < 0.5) {
245
+ c.r = 0.0;
246
+ c.b = 1.0 + 4.0 * (0.25 - v);
247
+ } else if (v < 0.75) {
248
+ c.r = 4.0 * (v - 0.5);
249
+ c.b = 0.0;
250
+ } else {
251
+ c.g = 1.0 + 4.0 * (0.75 - v);
252
+ c.b = 0.0;
253
+ }
254
+
255
+ return c;
256
+ }
257
+
258
+ void main() {
259
+ float depth = texture(textureSampler, TexCoord).r;
260
+ FragColor = vec4(bourkeColorMap(sqrt(1.0 - depth)), 1.0);
261
+ }
262
+ """
263
+
225
264
 
226
265
  @wp.kernel
227
266
  def update_vbo_transforms(
@@ -411,7 +450,7 @@ def assemble_gfx_vertices(
411
450
 
412
451
 
413
452
  @wp.kernel
414
- def copy_frame(
453
+ def copy_rgb_frame(
415
454
  input_img: wp.array(dtype=wp.uint8),
416
455
  width: int,
417
456
  height: int,
@@ -432,7 +471,26 @@ def copy_frame(
432
471
 
433
472
 
434
473
  @wp.kernel
435
- def copy_frame_tiles(
474
+ def copy_depth_frame(
475
+ input_img: wp.array(dtype=wp.float32),
476
+ width: int,
477
+ height: int,
478
+ near: float,
479
+ far: float,
480
+ # outputs
481
+ output_img: wp.array(dtype=wp.float32, ndim=3),
482
+ ):
483
+ w, v = wp.tid()
484
+ pixel = v * width + w
485
+ # flip vertically (OpenGL coordinates start at bottom)
486
+ v = height - v - 1
487
+ d = 2.0 * input_img[pixel] - 1.0
488
+ d = 2.0 * near * far / ((far - near) * d - near - far)
489
+ output_img[v, w, 0] = -d
490
+
491
+
492
+ @wp.kernel
493
+ def copy_rgb_frame_tiles(
436
494
  input_img: wp.array(dtype=wp.uint8),
437
495
  positions: wp.array(dtype=int, ndim=2),
438
496
  screen_width: int,
@@ -463,7 +521,34 @@ def copy_frame_tiles(
463
521
 
464
522
 
465
523
  @wp.kernel
466
- def copy_frame_tile(
524
+ def copy_depth_frame_tiles(
525
+ input_img: wp.array(dtype=wp.float32),
526
+ positions: wp.array(dtype=int, ndim=2),
527
+ screen_width: int,
528
+ screen_height: int,
529
+ tile_height: int,
530
+ near: float,
531
+ far: float,
532
+ # outputs
533
+ output_img: wp.array(dtype=wp.float32, ndim=4),
534
+ ):
535
+ tile, x, y = wp.tid()
536
+ p = positions[tile]
537
+ qx = x + p[0]
538
+ qy = y + p[1]
539
+ pixel = qy * screen_width + qx
540
+ # flip vertically (OpenGL coordinates start at bottom)
541
+ y = tile_height - y - 1
542
+ if qx >= screen_width or qy >= screen_height:
543
+ output_img[tile, y, x, 0] = far
544
+ return # prevent out-of-bounds access
545
+ d = 2.0 * input_img[pixel] - 1.0
546
+ d = 2.0 * near * far / ((far - near) * d - near - far)
547
+ output_img[tile, y, x, 0] = -d
548
+
549
+
550
+ @wp.kernel
551
+ def copy_rgb_frame_tile(
467
552
  input_img: wp.array(dtype=wp.uint8),
468
553
  offset_x: int,
469
554
  offset_y: int,
@@ -765,22 +850,28 @@ class OpenGLRenderer:
765
850
  title="Warp sim",
766
851
  scaling=1.0,
767
852
  fps=60,
768
- up_axis="y",
853
+ up_axis="Y",
769
854
  screen_width=1024,
770
855
  screen_height=768,
771
- near_plane=0.01,
772
- far_plane=1000.0,
856
+ near_plane=1.0,
857
+ far_plane=100.0,
773
858
  camera_fov=45.0,
859
+ camera_pos=(0.0, 2.0, 10.0),
860
+ camera_front=(0.0, 0.0, -1.0),
861
+ camera_up=(0.0, 1.0, 0.0),
774
862
  background_color=(0.53, 0.8, 0.92),
775
863
  draw_grid=True,
776
864
  draw_sky=True,
777
865
  draw_axis=True,
778
866
  show_info=True,
779
867
  render_wireframe=False,
868
+ render_depth=False,
780
869
  axis_scale=1.0,
781
870
  vsync=False,
782
871
  headless=False,
783
872
  enable_backface_culling=True,
873
+ enable_mouse_interaction=True,
874
+ enable_keyboard_interaction=True,
784
875
  ):
785
876
  try:
786
877
  import pyglet
@@ -804,6 +895,7 @@ class OpenGLRenderer:
804
895
  self.draw_axis = draw_axis
805
896
  self.show_info = show_info
806
897
  self.render_wireframe = render_wireframe
898
+ self.render_depth = render_depth
807
899
  self.enable_backface_culling = enable_backface_culling
808
900
 
809
901
  self._device = wp.get_cuda_device()
@@ -819,19 +911,26 @@ class OpenGLRenderer:
819
911
 
820
912
  self.screen_width, self.screen_height = self.window.get_framebuffer_size()
821
913
 
822
- self._camera_pos = PyVec3(0.0, 2.0, 10.0)
823
- self._camera_front = PyVec3(0.0, 0.0, -1.0)
824
- self._camera_up = PyVec3(0.0, 1.0, 0.0)
914
+ self.enable_mouse_interaction = enable_mouse_interaction
915
+ self.enable_keyboard_interaction = enable_keyboard_interaction
916
+
917
+ self._camera_pos = PyVec3(*camera_pos)
918
+ self._camera_front = PyVec3(*camera_front)
919
+ self._camera_up = PyVec3(*camera_up)
825
920
  self._camera_speed = 0.04
826
921
  if isinstance(up_axis, int):
827
922
  self._camera_axis = up_axis
828
923
  else:
829
- self._camera_axis = "xyz".index(up_axis.lower())
924
+ self._camera_axis = "XYZ".index(up_axis.upper())
830
925
  self._yaw, self._pitch = -90.0, 0.0
831
926
  self._last_x, self._last_y = self.screen_width // 2, self.screen_height // 2
832
927
  self._first_mouse = True
833
928
  self._left_mouse_pressed = False
834
929
  self._keys_pressed = defaultdict(bool)
930
+ self._key_callbacks = []
931
+
932
+ self.render_2d_callbacks = []
933
+ self.render_3d_callbacks = []
835
934
 
836
935
  self.update_view_matrix()
837
936
  self.update_projection_matrix()
@@ -854,6 +953,7 @@ class OpenGLRenderer:
854
953
  self._shape_gl_buffers = {}
855
954
  self._shape_instances = defaultdict(list)
856
955
  self._instances = {}
956
+ self._instance_custom_ids = {}
857
957
  self._instance_shape = {}
858
958
  self._instance_gl_buffers = {}
859
959
  self._instance_transform_gl_buffer = None
@@ -862,6 +962,8 @@ class OpenGLRenderer:
862
962
  self._instance_color2_buffer = None
863
963
  self._instance_count = 0
864
964
  self._wp_instance_ids = None
965
+ self._wp_instance_custom_ids = None
966
+ self._np_instance_visible = None
865
967
  self._instance_ids = None
866
968
  self._inverse_instance_ids = None
867
969
  self._wp_instance_transforms = None
@@ -888,6 +990,7 @@ class OpenGLRenderer:
888
990
  self._tile_projection_matrices = None
889
991
 
890
992
  self._frame_texture = None
993
+ self._frame_depth_texture = None
891
994
  self._frame_fbo = None
892
995
  self._frame_pbo = None
893
996
 
@@ -903,6 +1006,8 @@ class OpenGLRenderer:
903
1006
 
904
1007
  gl.glClearColor(*self.background_color, 1)
905
1008
  gl.glEnable(gl.GL_DEPTH_TEST)
1009
+ gl.glDepthMask(True)
1010
+ gl.glDepthRange(0.0, 1.0)
906
1011
 
907
1012
  self._shape_shader = ShaderProgram(
908
1013
  Shader(shape_vertex_shader, "vertex"), Shader(shape_fragment_shader, "fragment")
@@ -969,15 +1074,17 @@ class OpenGLRenderer:
969
1074
 
970
1075
  self._loc_sky_color1 = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("color1"))
971
1076
  self._loc_sky_color2 = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("color2"))
1077
+ self._loc_sky_far_plane = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("farPlane"))
972
1078
  gl.glUniform3f(self._loc_sky_color1, *background_color)
973
1079
  # glUniform3f(self._loc_sky_color2, *np.clip(np.array(background_color)+0.5, 0.0, 1.0))
974
1080
  gl.glUniform3f(self._loc_sky_color2, 0.8, 0.4, 0.05)
1081
+ gl.glUniform1f(self._loc_sky_far_plane, self.camera_far_plane)
975
1082
  self._loc_sky_view_pos = gl.glGetUniformLocation(self._sky_shader.id, str_buffer("viewPos"))
976
1083
  gl.glUniform3f(
977
1084
  gl.glGetUniformLocation(self._sky_shader.id, str_buffer("sunDirection")), *self._sun_direction
978
1085
  )
979
1086
 
980
- # Create VAO, VBO, and EBO
1087
+ # create VAO, VBO, and EBO
981
1088
  self._sky_vao = gl.GLuint()
982
1089
  gl.glGenVertexArrays(1, self._sky_vao)
983
1090
  gl.glBindVertexArray(self._sky_vao)
@@ -995,7 +1102,7 @@ class OpenGLRenderer:
995
1102
  gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._sky_ebo)
996
1103
  gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices.ctypes.data, gl.GL_STATIC_DRAW)
997
1104
 
998
- # Set up vertex attributes
1105
+ # set up vertex attributes
999
1106
  vertex_stride = vertices.shape[1] * vertices.itemsize
1000
1107
  # positions
1001
1108
  gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, vertex_stride, ctypes.c_void_p(0))
@@ -1029,6 +1136,7 @@ class OpenGLRenderer:
1029
1136
 
1030
1137
  # create frame buffer for rendering to a texture
1031
1138
  self._frame_texture = None
1139
+ self._frame_depth_texture = None
1032
1140
  self._frame_fbo = None
1033
1141
  self._setup_framebuffer()
1034
1142
 
@@ -1076,7 +1184,15 @@ class OpenGLRenderer:
1076
1184
  gl.glUseProgram(self._frame_shader.id)
1077
1185
  self._frame_loc_texture = gl.glGetUniformLocation(self._frame_shader.id, str_buffer("textureSampler"))
1078
1186
 
1079
- # Unbind the VBO and VAO
1187
+ self._frame_depth_shader = ShaderProgram(
1188
+ Shader(frame_vertex_shader, "vertex"), Shader(frame_depth_fragment_shader, "fragment")
1189
+ )
1190
+ gl.glUseProgram(self._frame_depth_shader.id)
1191
+ self._frame_loc_depth_texture = gl.glGetUniformLocation(
1192
+ self._frame_depth_shader.id, str_buffer("textureSampler")
1193
+ )
1194
+
1195
+ # unbind the VBO and VAO
1080
1196
  gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
1081
1197
  gl.glBindVertexArray(0)
1082
1198
 
@@ -1164,11 +1280,17 @@ class OpenGLRenderer:
1164
1280
  self._instance_color1_buffer = None
1165
1281
  self._instance_color2_buffer = None
1166
1282
  self._wp_instance_ids = None
1283
+ self._wp_instance_custom_ids = None
1167
1284
  self._wp_instance_transforms = None
1168
1285
  self._wp_instance_scalings = None
1169
1286
  self._wp_instance_bodies = None
1287
+ self._np_instance_visible = None
1170
1288
  self._update_shape_instances = False
1171
1289
 
1290
+ def close(self):
1291
+ self.clear()
1292
+ self.window.close()
1293
+
1172
1294
  @property
1173
1295
  def tiled_rendering(self):
1174
1296
  return self._tiled_rendering
@@ -1322,7 +1444,11 @@ class OpenGLRenderer:
1322
1444
  if self._frame_texture is None:
1323
1445
  self._frame_texture = gl.GLuint()
1324
1446
  gl.glGenTextures(1, self._frame_texture)
1447
+ if self._frame_depth_texture is None:
1448
+ self._frame_depth_texture = gl.GLuint()
1449
+ gl.glGenTextures(1, self._frame_depth_texture)
1325
1450
 
1451
+ # set up RGB texture
1326
1452
  gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
1327
1453
  gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0)
1328
1454
  gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
@@ -1339,6 +1465,22 @@ class OpenGLRenderer:
1339
1465
  )
1340
1466
  gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
1341
1467
  gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
1468
+
1469
+ # set up depth texture
1470
+ gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_depth_texture)
1471
+ gl.glTexImage2D(
1472
+ gl.GL_TEXTURE_2D,
1473
+ 0,
1474
+ gl.GL_DEPTH_COMPONENT32,
1475
+ self.screen_width,
1476
+ self.screen_height,
1477
+ 0,
1478
+ gl.GL_DEPTH_COMPONENT,
1479
+ gl.GL_FLOAT,
1480
+ None,
1481
+ )
1482
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
1483
+ gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
1342
1484
  gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
1343
1485
 
1344
1486
  # create a framebuffer object (FBO)
@@ -1351,15 +1493,9 @@ class OpenGLRenderer:
1351
1493
  gl.glFramebufferTexture2D(
1352
1494
  gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self._frame_texture, 0
1353
1495
  )
1354
-
1355
- self._frame_depth_renderbuffer = gl.GLuint()
1356
- gl.glGenRenderbuffers(1, self._frame_depth_renderbuffer)
1357
- gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self._frame_depth_renderbuffer)
1358
- gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, self.screen_width, self.screen_height)
1359
-
1360
- # attach the depth renderbuffer to the FBO
1361
- gl.glFramebufferRenderbuffer(
1362
- gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, self._frame_depth_renderbuffer
1496
+ # attach the depth texture to the FBO as its depth attachment
1497
+ gl.glFramebufferTexture2D(
1498
+ gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_TEXTURE_2D, self._frame_depth_texture, 0
1363
1499
  )
1364
1500
 
1365
1501
  if gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE:
@@ -1367,13 +1503,6 @@ class OpenGLRenderer:
1367
1503
  gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
1368
1504
  sys.exit(1)
1369
1505
 
1370
- gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, 0)
1371
- else:
1372
- # rescale framebuffer
1373
- gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self._frame_depth_renderbuffer)
1374
- gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, self.screen_width, self.screen_height)
1375
- gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, 0)
1376
-
1377
1506
  # unbind the FBO (switch back to the default framebuffer)
1378
1507
  gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
1379
1508
 
@@ -1383,7 +1512,11 @@ class OpenGLRenderer:
1383
1512
  gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, self._frame_pbo) # binding to this buffer
1384
1513
 
1385
1514
  # allocate memory for PBO
1386
- pixels = np.zeros((self.screen_height, self.screen_width, 3), dtype=np.uint8)
1515
+ rgb_bytes_per_pixel = 3
1516
+ depth_bytes_per_pixel = 4
1517
+ pixels = np.zeros(
1518
+ (self.screen_height, self.screen_width, rgb_bytes_per_pixel + depth_bytes_per_pixel), dtype=np.uint8
1519
+ )
1387
1520
  gl.glBufferData(gl.GL_PIXEL_PACK_BUFFER, pixels.nbytes, pixels.ctypes.data, gl.GL_DYNAMIC_DRAW)
1388
1521
  gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
1389
1522
 
@@ -1542,7 +1675,6 @@ class OpenGLRenderer:
1542
1675
 
1543
1676
  if self._frame_fbo is not None:
1544
1677
  gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._frame_fbo)
1545
- gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, self._frame_fbo)
1546
1678
 
1547
1679
  gl.glClearColor(*self.background_color, 1)
1548
1680
  gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
@@ -1571,6 +1703,9 @@ class OpenGLRenderer:
1571
1703
  else:
1572
1704
  self._render_scene()
1573
1705
 
1706
+ for cb in self.render_3d_callbacks:
1707
+ cb()
1708
+
1574
1709
  gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL)
1575
1710
 
1576
1711
  gl.glBindBuffer(gl.GL_PIXEL_UNPACK_BUFFER, 0)
@@ -1580,15 +1715,26 @@ class OpenGLRenderer:
1580
1715
 
1581
1716
  # render frame buffer texture to screen
1582
1717
  if self._frame_fbo is not None:
1583
- with self._frame_shader:
1584
- gl.glActiveTexture(gl.GL_TEXTURE0)
1585
- gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
1586
- gl.glUniform1i(self._frame_loc_texture, 0)
1718
+ if self.render_depth:
1719
+ with self._frame_depth_shader:
1720
+ gl.glActiveTexture(gl.GL_TEXTURE0)
1721
+ gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_depth_texture)
1722
+ gl.glUniform1i(self._frame_loc_depth_texture, 0)
1723
+
1724
+ gl.glBindVertexArray(self._frame_vao)
1725
+ gl.glDrawElements(gl.GL_TRIANGLES, len(self._frame_indices), gl.GL_UNSIGNED_INT, None)
1726
+ gl.glBindVertexArray(0)
1727
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
1728
+ else:
1729
+ with self._frame_shader:
1730
+ gl.glActiveTexture(gl.GL_TEXTURE0)
1731
+ gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
1732
+ gl.glUniform1i(self._frame_loc_texture, 0)
1587
1733
 
1588
- gl.glBindVertexArray(self._frame_vao)
1589
- gl.glDrawElements(gl.GL_TRIANGLES, len(self._frame_indices), gl.GL_UNSIGNED_INT, None)
1590
- gl.glBindVertexArray(0)
1591
- gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
1734
+ gl.glBindVertexArray(self._frame_vao)
1735
+ gl.glDrawElements(gl.GL_TRIANGLES, len(self._frame_indices), gl.GL_UNSIGNED_INT, None)
1736
+ gl.glBindVertexArray(0)
1737
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
1592
1738
 
1593
1739
  # check for OpenGL errors
1594
1740
  # check_gl_error()
@@ -1611,6 +1757,9 @@ Instances: {len(self._instances)}"""
1611
1757
  self._info_label.y = self.screen_height - 5
1612
1758
  self._info_label.draw()
1613
1759
 
1760
+ for cb in self.render_2d_callbacks:
1761
+ cb()
1762
+
1614
1763
  def _draw_grid(self, is_tiled=False):
1615
1764
  from pyglet import gl
1616
1765
 
@@ -1708,6 +1857,9 @@ Instances: {len(self._instances)}"""
1708
1857
  gl.glBindVertexArray(0)
1709
1858
 
1710
1859
  def _mouse_drag_callback(self, x, y, dx, dy, buttons, modifiers):
1860
+ if not self.enable_mouse_interaction:
1861
+ return
1862
+
1711
1863
  import pyglet
1712
1864
 
1713
1865
  if buttons & pyglet.window.mouse.LEFT:
@@ -1727,6 +1879,9 @@ Instances: {len(self._instances)}"""
1727
1879
  self.update_view_matrix()
1728
1880
 
1729
1881
  def _scroll_callback(self, x, y, scroll_x, scroll_y):
1882
+ if not self.enable_mouse_interaction:
1883
+ return
1884
+
1730
1885
  self.camera_fov -= scroll_y
1731
1886
  self.camera_fov = max(min(self.camera_fov, 90.0), 15.0)
1732
1887
  self.update_projection_matrix()
@@ -1753,8 +1908,11 @@ Instances: {len(self._instances)}"""
1753
1908
  def _key_press_callback(self, symbol, modifiers):
1754
1909
  import pyglet
1755
1910
 
1911
+ if not self.enable_keyboard_interaction:
1912
+ return
1913
+
1756
1914
  if symbol == pyglet.window.key.ESCAPE:
1757
- self.window.close()
1915
+ self.close()
1758
1916
  if symbol == pyglet.window.key.SPACE:
1759
1917
  self.paused = not self.paused
1760
1918
  if symbol == pyglet.window.key.TAB:
@@ -1767,9 +1925,17 @@ Instances: {len(self._instances)}"""
1767
1925
  self.show_info = not self.show_info
1768
1926
  if symbol == pyglet.window.key.X:
1769
1927
  self.render_wireframe = not self.render_wireframe
1928
+ if symbol == pyglet.window.key.T:
1929
+ self.render_depth = not self.render_depth
1770
1930
  if symbol == pyglet.window.key.B:
1771
1931
  self.enable_backface_culling = not self.enable_backface_culling
1772
1932
 
1933
+ for cb in self._key_callbacks:
1934
+ cb(symbol, modifiers)
1935
+
1936
+ def register_key_press_callback(self, callback):
1937
+ self._key_callbacks.append(callback)
1938
+
1773
1939
  def _window_resize_callback(self, width, height):
1774
1940
  self._first_mouse = True
1775
1941
  self.screen_width, self.screen_height = self.window.get_framebuffer_size()
@@ -1826,7 +1992,17 @@ Instances: {len(self._instances)}"""
1826
1992
  return shape
1827
1993
 
1828
1994
  def add_shape_instance(
1829
- self, name: str, shape: int, body, pos, rot, scale=(1.0, 1.0, 1.0), color1=None, color2=None
1995
+ self,
1996
+ name: str,
1997
+ shape: int,
1998
+ body,
1999
+ pos,
2000
+ rot,
2001
+ scale=(1.0, 1.0, 1.0),
2002
+ color1=None,
2003
+ color2=None,
2004
+ custom_index: int = -1,
2005
+ visible: bool = True,
1830
2006
  ):
1831
2007
  if color1 is None:
1832
2008
  color1 = self._shapes[shape][2]
@@ -1835,8 +2011,9 @@ Instances: {len(self._instances)}"""
1835
2011
  instance = len(self._instances)
1836
2012
  self._shape_instances[shape].append(instance)
1837
2013
  body = self._resolve_body_id(body)
1838
- self._instances[name] = (instance, body, shape, [*pos, *rot], scale, color1, color2)
2014
+ self._instances[name] = (instance, body, shape, [*pos, *rot], scale, color1, color2, visible)
1839
2015
  self._instance_shape[instance] = shape
2016
+ self._instance_custom_ids[instance] = custom_index
1840
2017
  self._add_shape_instances = True
1841
2018
  self._instance_count = len(self._instances)
1842
2019
  return instance
@@ -1861,7 +2038,7 @@ Instances: {len(self._instances)}"""
1861
2038
  gl.glDeleteBuffers(1, self._instance_color1_buffer)
1862
2039
  gl.glDeleteBuffers(1, self._instance_color2_buffer)
1863
2040
 
1864
- # Create instance buffer and bind it as an instanced array
2041
+ # create instance buffer and bind it as an instanced array
1865
2042
  self._instance_transform_gl_buffer = gl.GLuint()
1866
2043
  gl.glGenBuffers(1, self._instance_transform_gl_buffer)
1867
2044
  gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_transform_gl_buffer)
@@ -1869,7 +2046,7 @@ Instances: {len(self._instances)}"""
1869
2046
  transforms = np.tile(np.diag(np.ones(4, dtype=np.float32)), (len(self._instances), 1, 1))
1870
2047
  gl.glBufferData(gl.GL_ARRAY_BUFFER, transforms.nbytes, transforms.ctypes.data, gl.GL_DYNAMIC_DRAW)
1871
2048
 
1872
- # Create CUDA buffer for instance transforms
2049
+ # create CUDA buffer for instance transforms
1873
2050
  self._instance_transform_cuda_buffer = wp.RegisteredGLBuffer(
1874
2051
  int(self._instance_transform_gl_buffer.value), self._device
1875
2052
  )
@@ -1897,10 +2074,13 @@ Instances: {len(self._instances)}"""
1897
2074
  gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
1898
2075
  gl.glBufferData(gl.GL_ARRAY_BUFFER, colors2.nbytes, colors2.ctypes.data, gl.GL_STATIC_DRAW)
1899
2076
 
1900
- # Set up instance attribute pointers
2077
+ # set up instance attribute pointers
1901
2078
  matrix_size = transforms[0].nbytes
1902
2079
 
1903
2080
  instance_ids = []
2081
+ instance_custom_ids = []
2082
+ instance_visible = []
2083
+ instances = list(self._instances.values())
1904
2084
  inverse_instance_ids = {}
1905
2085
  instance_count = 0
1906
2086
  for shape, (vao, vbo, ebo, tri_count, vertex_cuda_buffer) in self._shape_gl_buffers.items():
@@ -1930,27 +2110,45 @@ Instances: {len(self._instances)}"""
1930
2110
  for i in self._shape_instances[shape]:
1931
2111
  inverse_instance_ids[i] = instance_count
1932
2112
  instance_count += 1
2113
+ instance_custom_ids.append(self._instance_custom_ids[i])
2114
+ instance_visible.append(instances[i][7])
1933
2115
 
1934
2116
  # trigger update to the instance transforms
1935
2117
  self._update_shape_instances = True
1936
2118
 
1937
2119
  self._wp_instance_ids = wp.array(instance_ids, dtype=wp.int32, device=self._device)
2120
+ self._wp_instance_custom_ids = wp.array(instance_custom_ids, dtype=wp.int32, device=self._device)
2121
+ self._np_instance_visible = np.array(instance_visible)
1938
2122
  self._instance_ids = instance_ids
1939
2123
  self._inverse_instance_ids = inverse_instance_ids
1940
2124
 
1941
2125
  gl.glBindVertexArray(0)
1942
2126
 
1943
- def update_shape_instance(self, name, pos, rot, color1=None, color2=None):
2127
+ def update_shape_instance(self, name, pos, rot, color1=None, color2=None, visible=None):
1944
2128
  """Update the instance transform of the shape
1945
2129
 
1946
2130
  Args:
1947
2131
  name: The name of the shape
1948
2132
  pos: The position of the shape
1949
2133
  rot: The rotation of the shape
2134
+ color1: The first color of the checker pattern
2135
+ color2: The second color of the checker pattern
2136
+ visible: Whether the shape is visible
1950
2137
  """
1951
2138
  if name in self._instances:
1952
- i, body, shape, _, scale, old_color1, old_color2 = self._instances[name]
1953
- self._instances[name] = (i, body, shape, [*pos, *rot], scale, color1 or old_color1, color2 or old_color2)
2139
+ i, body, shape, _, scale, old_color1, old_color2, v = self._instances[name]
2140
+ if visible is None:
2141
+ visible = v
2142
+ self._instances[name] = (
2143
+ i,
2144
+ body,
2145
+ shape,
2146
+ [*pos, *rot],
2147
+ scale,
2148
+ color1 or old_color1,
2149
+ color2 or old_color2,
2150
+ visible,
2151
+ )
1954
2152
  self._update_shape_instances = True
1955
2153
  return True
1956
2154
  return False
@@ -2018,9 +2216,27 @@ Instances: {len(self._instances)}"""
2018
2216
  self.clear()
2019
2217
  self.app.event_loop.exit()
2020
2218
 
2021
- def get_pixels(self, target_image: wp.array, split_up_tiles=True):
2219
+ def get_pixels(self, target_image: wp.array, split_up_tiles=True, mode="rgb"):
2220
+ """
2221
+ Read the pixels from the frame buffer (RGB or depth are supported) into the given array.
2222
+
2223
+ If `split_up_tiles` is False, array must be of shape (screen_height, screen_width, 3) for RGB mode or
2224
+ (screen_height, screen_width, 1) for depth mode.
2225
+ If `split_up_tiles` is True, the pixels will be split up into tiles (see :attr:`tile_width` and :attr:`tile_height` for dimensions):
2226
+ array must be of shape (num_tiles, tile_height, tile_width, 3) for RGB mode or (num_tiles, tile_height, tile_width, 1) for depth mode.
2227
+
2228
+ Args:
2229
+ target_image (array): The array to read the pixels into. Must have float32 as dtype and be on a CUDA device.
2230
+ split_up_tiles (bool): Whether to split up the viewport into tiles, see :meth:`setup_tiled_rendering`.
2231
+ mode (str): can be either "rgb" or "depth"
2232
+
2233
+ Returns:
2234
+ bool: Whether the pixels were successfully read.
2235
+ """
2022
2236
  from pyglet import gl
2023
2237
 
2238
+ channels = 3 if mode == "rgb" else 1
2239
+
2024
2240
  if split_up_tiles:
2025
2241
  assert (
2026
2242
  self._tile_width is not None and self._tile_height is not None
@@ -2035,20 +2251,26 @@ Instances: {len(self._instances)}"""
2035
2251
  self.num_tiles,
2036
2252
  self._tile_height,
2037
2253
  self._tile_width,
2038
- 3,
2039
- ), f"Shape of `target_image` array does not match {self.num_tiles} x {self.screen_height} x {self.screen_width} x 3"
2254
+ channels,
2255
+ ), f"Shape of `target_image` array does not match {self.num_tiles} x {self.screen_height} x {self.screen_width} x {channels}"
2040
2256
  else:
2041
2257
  assert target_image.shape == (
2042
2258
  self.screen_height,
2043
2259
  self.screen_width,
2044
- 3,
2045
- ), f"Shape of `target_image` array does not match {self.screen_height} x {self.screen_width} x 3"
2260
+ channels,
2261
+ ), f"Shape of `target_image` array does not match {self.screen_height} x {self.screen_width} x {channels}"
2046
2262
 
2047
2263
  gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, self._frame_pbo)
2048
- gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
2264
+ if mode == "rgb":
2265
+ gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
2266
+ if mode == "depth":
2267
+ gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_depth_texture)
2049
2268
  try:
2050
2269
  # read screen texture into PBO
2051
- gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, ctypes.c_void_p(0))
2270
+ if mode == "rgb":
2271
+ gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, ctypes.c_void_p(0))
2272
+ elif mode == "depth":
2273
+ gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT, ctypes.c_void_p(0))
2052
2274
  except gl.GLException:
2053
2275
  # this can happen if the window is closed/being moved to a different display
2054
2276
  gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
@@ -2061,63 +2283,54 @@ Instances: {len(self._instances)}"""
2061
2283
  int(self._frame_pbo.value), self._device, wp.RegisteredGLBuffer.WRITE_DISCARD
2062
2284
  )
2063
2285
  screen_size = self.screen_height * self.screen_width
2064
- img = pbo_buffer.map(dtype=wp.uint8, shape=(screen_size * 3))
2286
+ if mode == "rgb":
2287
+ img = pbo_buffer.map(dtype=wp.uint8, shape=(screen_size * channels))
2288
+ elif mode == "depth":
2289
+ img = pbo_buffer.map(dtype=wp.float32, shape=(screen_size * channels))
2065
2290
  img = img.to(target_image.device)
2066
2291
  if split_up_tiles:
2067
2292
  positions = wp.array(self._tile_viewports, ndim=2, dtype=wp.int32, device=target_image.device)
2068
- wp.launch(
2069
- copy_frame_tiles,
2070
- dim=(self.num_tiles, self._tile_width, self._tile_height),
2071
- inputs=[img, positions, self.screen_width, self.screen_height, self._tile_height],
2072
- outputs=[target_image],
2073
- device=target_image.device,
2074
- )
2293
+ if mode == "rgb":
2294
+ wp.launch(
2295
+ copy_rgb_frame_tiles,
2296
+ dim=(self.num_tiles, self._tile_width, self._tile_height),
2297
+ inputs=[img, positions, self.screen_width, self.screen_height, self._tile_height],
2298
+ outputs=[target_image],
2299
+ device=target_image.device,
2300
+ )
2301
+ elif mode == "depth":
2302
+ wp.launch(
2303
+ copy_depth_frame_tiles,
2304
+ dim=(self.num_tiles, self._tile_width, self._tile_height),
2305
+ inputs=[
2306
+ img,
2307
+ positions,
2308
+ self.screen_width,
2309
+ self.screen_height,
2310
+ self._tile_height,
2311
+ self.camera_near_plane,
2312
+ self.camera_far_plane,
2313
+ ],
2314
+ outputs=[target_image],
2315
+ device=target_image.device,
2316
+ )
2075
2317
  else:
2076
- wp.launch(
2077
- copy_frame,
2078
- dim=(self.screen_width, self.screen_height),
2079
- inputs=[img, self.screen_width, self.screen_height],
2080
- outputs=[target_image],
2081
- device=target_image.device,
2082
- )
2083
- pbo_buffer.unmap()
2084
- return True
2085
-
2086
- def get_tile_pixels(self, tile_id: int, target_image: wp.array):
2087
- from pyglet import gl
2088
-
2089
- viewport = self._tile_viewports[tile_id]
2090
- assert target_image.shape == (
2091
- viewport[3],
2092
- viewport[2],
2093
- 3,
2094
- ), f"Shape of `target_image` array does not match {viewport[3]} x {viewport[2]} x 3"
2095
- gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, self._frame_pbo)
2096
- gl.glBindTexture(gl.GL_TEXTURE_2D, self._frame_texture)
2097
- try:
2098
- # read screen texture into PBO
2099
- gl.glGetTexImage(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, ctypes.c_void_p(0))
2100
- except gl.GLException:
2101
- # this can happen if the window is closed/being moved to a different display
2102
- gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
2103
- gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
2104
- return False
2105
- gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
2106
- gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
2107
-
2108
- pbo_buffer = wp.RegisteredGLBuffer(
2109
- int(self._frame_pbo.value), self._device, wp.RegisteredGLBuffer.WRITE_DISCARD
2110
- )
2111
- screen_size = self.screen_height * self.screen_width
2112
- img = pbo_buffer.map(dtype=wp.uint8, shape=(screen_size * 3))
2113
- img = img.to(target_image.device)
2114
- wp.launch(
2115
- copy_frame_tiles,
2116
- dim=(self.num_tiles, self._tile_width, self._tile_height),
2117
- inputs=[img, viewport[0], viewport[1], self.screen_width, self.screen_height, self._tile_height],
2118
- outputs=[target_image],
2119
- device=target_image.device,
2120
- )
2318
+ if mode == "rgb":
2319
+ wp.launch(
2320
+ copy_rgb_frame,
2321
+ dim=(self.screen_width, self.screen_height),
2322
+ inputs=[img, self.screen_width, self.screen_height],
2323
+ outputs=[target_image],
2324
+ device=target_image.device,
2325
+ )
2326
+ elif mode == "depth":
2327
+ wp.launch(
2328
+ copy_depth_frame,
2329
+ dim=(self.screen_width, self.screen_height),
2330
+ inputs=[img, self.screen_width, self.screen_height, self.camera_near_plane, self.camera_far_plane],
2331
+ outputs=[target_image],
2332
+ device=target_image.device,
2333
+ )
2121
2334
  pbo_buffer.unmap()
2122
2335
  return True
2123
2336
 
@@ -2570,7 +2783,7 @@ Instances: {len(self._instances)}"""
2570
2783
  if name not in self._shape_instancers:
2571
2784
  instancer = ShapeInstancer(self._shape_shader, self._device)
2572
2785
  vertices, indices = self._create_capsule_mesh(radius, 0.5)
2573
- if color is None or isinstance(color, list):
2786
+ if color is None or isinstance(color, list) and len(color) > 0 and isinstance(color[0], list):
2574
2787
  color = tab10_color_map(len(self._shape_geo_hash))
2575
2788
  instancer.register_shape(vertices, indices, color, color)
2576
2789
  instancer.allocate_instances(np.zeros((len(lines), 3)))
@@ -2590,7 +2803,7 @@ Instances: {len(self._instances)}"""
2590
2803
  device=self._device,
2591
2804
  )
2592
2805
 
2593
- def render_line_list(self, name, vertices, indices, color, radius):
2806
+ def render_line_list(self, name: str, vertices, indices, color: tuple = None, radius: float = 0.01):
2594
2807
  """Add a line list as a set of capsules
2595
2808
 
2596
2809
  Args:
@@ -2605,7 +2818,7 @@ Instances: {len(self._instances)}"""
2605
2818
  lines = np.array(lines)
2606
2819
  self._render_lines(name, lines, color, radius)
2607
2820
 
2608
- def render_line_strip(self, name: str, vertices, color: tuple, radius: float = 0.01):
2821
+ def render_line_strip(self, name: str, vertices, color: tuple = None, radius: float = 0.01):
2609
2822
  """Add a line strip as a set of capsules
2610
2823
 
2611
2824
  Args:
@@ -2640,7 +2853,12 @@ Instances: {len(self._instances)}"""
2640
2853
  cuda_buffer.unmap()
2641
2854
 
2642
2855
  @staticmethod
2643
- def _create_sphere_mesh(radius=1.0, num_latitudes=default_num_segments, num_longitudes=default_num_segments, reverse_winding=False):
2856
+ def _create_sphere_mesh(
2857
+ radius=1.0,
2858
+ num_latitudes=default_num_segments,
2859
+ num_longitudes=default_num_segments,
2860
+ reverse_winding=False,
2861
+ ):
2644
2862
  vertices = []
2645
2863
  indices = []
2646
2864
 
@@ -2754,7 +2972,7 @@ Instances: {len(self._instances)}"""
2754
2972
  top_radius = radius
2755
2973
  side_slope = -np.arctan2(top_radius - radius, 2 * half_height)
2756
2974
 
2757
- # Create the cylinder base and top vertices
2975
+ # create the cylinder base and top vertices
2758
2976
  for j in (-1, 1):
2759
2977
  center_index = max(j, 0)
2760
2978
  if j == 1:
@@ -2782,12 +3000,10 @@ Instances: {len(self._instances)}"""
2782
3000
  vertex = np.hstack([position[[x_dir, y_dir, z_dir]], normal[[x_dir, y_dir, z_dir]], uv])
2783
3001
  cap_vertices.append(vertex)
2784
3002
 
2785
- indices.extend(
2786
- [center_index, i + center_index * segments + 2,
2787
- (i + 1) % segments + center_index * segments + 2][::-j]
2788
- )
3003
+ cs = center_index * segments
3004
+ indices.extend([center_index, i + cs + 2, (i + 1) % segments + cs + 2][::-j])
2789
3005
 
2790
- # Create the cylinder side indices
3006
+ # create the cylinder side indices
2791
3007
  for i in range(segments):
2792
3008
  index1 = len(cap_vertices) + i + segments
2793
3009
  index2 = len(cap_vertices) + ((i + 1) % segments) + segments