hyperdrone 0.1.0__py3-none-any.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.
Files changed (660) hide show
  1. hyperdrone/__init__.py +28 -0
  2. hyperdrone/_native/cmake/hyperdrone_jit.cmake +43 -0
  3. hyperdrone/_native/common/bindings.h +39 -0
  4. hyperdrone/_native/common/cuda_staging.h +68 -0
  5. hyperdrone/_native/common/jit_host.h +69 -0
  6. hyperdrone/_native/dynamics/CMakeLists.txt +66 -0
  7. hyperdrone/_native/dynamics/host.cpp +191 -0
  8. hyperdrone/_native/dynamics/iface.h +81 -0
  9. hyperdrone/_native/dynamics/impl.cpp +659 -0
  10. hyperdrone/_native/render/CMakeLists.txt +96 -0
  11. hyperdrone/_native/render/host.cpp +276 -0
  12. hyperdrone/_native/render/iface.h +132 -0
  13. hyperdrone/_native/render/impl.cpp +620 -0
  14. hyperdrone/_native/render/scene_bindings.cpp +279 -0
  15. hyperdrone/_vendor/rl-tools/CMakeLists.txt +159 -0
  16. hyperdrone/_vendor/rl-tools/LICENSE +21 -0
  17. hyperdrone/_vendor/rl-tools/cmake/autodetect/all.cmake +14 -0
  18. hyperdrone/_vendor/rl-tools/cmake/autodetect/git-diff.cmake +103 -0
  19. hyperdrone/_vendor/rl-tools/cmake/autodetect/git-hash.cmake +13 -0
  20. hyperdrone/_vendor/rl-tools/cmake/autodetect/tier1-blas.cmake +43 -0
  21. hyperdrone/_vendor/rl-tools/cmake/autodetect/tier2-json-hdf5-zlib.cmake +84 -0
  22. hyperdrone/_vendor/rl-tools/cmake/autodetect/tier3-tensorboard.cmake +29 -0
  23. hyperdrone/_vendor/rl-tools/cmake/autodetect/tier4-cuda.cmake +33 -0
  24. hyperdrone/_vendor/rl-tools/cmake/autodetect/tier5-cli11.cmake +26 -0
  25. hyperdrone/_vendor/rl-tools/cmake/optional/assimp_fixup.cmake +16 -0
  26. hyperdrone/_vendor/rl-tools/cmake/optional/googletest.cmake +17 -0
  27. hyperdrone/_vendor/rl-tools/cmake/optional/metal.cmake +27 -0
  28. hyperdrone/_vendor/rl-tools/cmake/optional/mujoco.cmake +32 -0
  29. hyperdrone/_vendor/rl-tools/cmake/optional/optix.cmake +17 -0
  30. hyperdrone/_vendor/rl-tools/cmake/optional/raytracing_generic.cmake +4 -0
  31. hyperdrone/_vendor/rl-tools/cmake/optional/vulkan.cmake +6 -0
  32. hyperdrone/_vendor/rl-tools/cmake/scripts/embed_text.cmake +7 -0
  33. hyperdrone/_vendor/rl-tools/cmake/scripts/generate-git-snapshot.cmake +138 -0
  34. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/matrix.h +143 -0
  35. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_arm.h +33 -0
  36. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_cpu.h +314 -0
  37. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_cpu_accelerate.h +37 -0
  38. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_cpu_blas.h +67 -0
  39. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_cpu_mkl.h +38 -0
  40. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_cpu_openblas.h +34 -0
  41. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_cuda.h +289 -0
  42. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_dummy.h +20 -0
  43. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_esp32.h +29 -0
  44. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_generic.h +946 -0
  45. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/operations_wasm32.h +13 -0
  46. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/matrix/persist_code.h +136 -0
  47. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_arm.h +1 -0
  48. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_cpu.h +94 -0
  49. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_cpu_accelerate.h +25 -0
  50. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_cpu_blas.h +115 -0
  51. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_cpu_mkl.h +25 -0
  52. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_cpu_openblas.h +25 -0
  53. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_cuda.h +703 -0
  54. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/operations_generic.h +1334 -0
  55. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/persist_code.h +130 -0
  56. hyperdrone/_vendor/rl-tools/include/rl_tools/containers/tensor/tensor.h +490 -0
  57. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/arm.h +91 -0
  58. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cpu.h +205 -0
  59. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cpu_accelerate.h +23 -0
  60. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cpu_blas.h +21 -0
  61. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cpu_mkl.h +45 -0
  62. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cpu_openblas.h +56 -0
  63. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cpu_tensorboard.h +34 -0
  64. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/cuda.h +411 -0
  65. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/devices.h +92 -0
  66. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/dummy.h +55 -0
  67. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/esp32.h +85 -0
  68. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/generic.h +0 -0
  69. hyperdrone/_vendor/rl-tools/include/rl_tools/devices/wasm32.h +59 -0
  70. hyperdrone/_vendor/rl-tools/include/rl_tools/dyn/model.h +218 -0
  71. hyperdrone/_vendor/rl-tools/include/rl_tools/dyn/operations_generic.h +771 -0
  72. hyperdrone/_vendor/rl-tools/include/rl_tools/dyn/persist.h +278 -0
  73. hyperdrone/_vendor/rl-tools/include/rl_tools/dyn/policy_adapter.h +100 -0
  74. hyperdrone/_vendor/rl-tools/include/rl_tools/dyn/policy_adapter_persist.h +52 -0
  75. hyperdrone/_vendor/rl-tools/include/rl_tools/dyn/tensor_operations_generic.h +55 -0
  76. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/applications/l2f/c_backend.h +112 -0
  77. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/applications/l2f/c_interface.h +36 -0
  78. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/applications/l2f/l2f.h +98 -0
  79. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/applications/l2f/operations_dyn.h +18 -0
  80. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/applications/l2f/operations_generic.h +268 -0
  81. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/debugging_pool/c_backend.h +31 -0
  82. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/debugging_pool/c_interface.h +12 -0
  83. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/executor/c_backend.h +98 -0
  84. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/executor/c_interface.h +50 -0
  85. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/executor/executor.h +133 -0
  86. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/executor/helper.h +109 -0
  87. hyperdrone/_vendor/rl-tools/include/rl_tools/inference/executor/operations_generic.h +219 -0
  88. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_arduino.h +117 -0
  89. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_arm.h +56 -0
  90. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_cpu.h +93 -0
  91. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_cpu_tensorboard.h +151 -0
  92. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_cuda.h +65 -0
  93. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_dummy.h +45 -0
  94. hyperdrone/_vendor/rl-tools/include/rl_tools/logging/operations_wasm32.h +56 -0
  95. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_arm.h +98 -0
  96. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_cpu.h +139 -0
  97. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_cuda.h +382 -0
  98. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_dummy.h +93 -0
  99. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_esp32.h +92 -0
  100. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_generic.h +297 -0
  101. hyperdrone/_vendor/rl-tools/include/rl_tools/math/operations_wasm32.h +225 -0
  102. hyperdrone/_vendor/rl-tools/include/rl_tools/mode/mode.h +75 -0
  103. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/activation_functions.h +115 -0
  104. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/capability/capability.h +63 -0
  105. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/capability/persist_code.h +27 -0
  106. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/avg_pool2d/layer.h +122 -0
  107. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/avg_pool2d/operations_cuda.h +64 -0
  108. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/avg_pool2d/operations_generic.h +184 -0
  109. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/avg_pool2d/persist.h +33 -0
  110. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/conv2d/layer.h +300 -0
  111. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/conv2d/operations_cpu_mkl.h +590 -0
  112. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/conv2d/operations_cuda.h +739 -0
  113. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/conv2d/operations_generic.h +1185 -0
  114. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/conv2d/persist.h +99 -0
  115. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/conv2d/persist_code.h +170 -0
  116. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/layer.h +145 -0
  117. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_arm/dsp.h +63 -0
  118. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_arm/opt.h +173 -0
  119. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_cpu.h +13 -0
  120. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_cpu_accelerate.h +66 -0
  121. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_cpu_blas.h +282 -0
  122. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_cpu_mkl.h +66 -0
  123. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_cpu_openblas.h +65 -0
  124. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_cuda.h +519 -0
  125. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_dummy.h +8 -0
  126. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_esp32/dsp.h +58 -0
  127. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_esp32/opt.h +167 -0
  128. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/operations_generic.h +421 -0
  129. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/persist.h +62 -0
  130. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/persist_code.h +178 -0
  131. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dense/persist_common.h +55 -0
  132. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dynamic_conv2d/layer.h +188 -0
  133. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dynamic_conv2d/operations_cuda.h +356 -0
  134. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dynamic_conv2d/operations_generic.h +534 -0
  135. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/dynamic_conv2d/persist.h +32 -0
  136. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/embedding/layer.h +119 -0
  137. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/embedding/operations_generic.h +217 -0
  138. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/embedding/persist.h +46 -0
  139. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/flatten/layer.h +121 -0
  140. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/flatten/operations_generic.h +152 -0
  141. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/flatten/persist.h +44 -0
  142. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/flatten/persist_code.h +106 -0
  143. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/gru/helper_operations_cuda.h +375 -0
  144. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/gru/helper_operations_generic.h +158 -0
  145. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/gru/layer.h +218 -0
  146. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/gru/operations_generic.h +947 -0
  147. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/gru/persist.h +75 -0
  148. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/gru/persist_code.h +199 -0
  149. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/layers.h +3 -0
  150. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/max_pool2d/layer.h +143 -0
  151. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/max_pool2d/operations_cuda.h +80 -0
  152. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/max_pool2d/operations_generic.h +214 -0
  153. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/max_pool2d/persist.h +39 -0
  154. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_cpu.h +1 -0
  155. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_cpu_accelerate.h +1 -0
  156. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_cpu_blas.h +1 -0
  157. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_cpu_mkl.h +3 -0
  158. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_cpu_openblas.h +1 -0
  159. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_cuda.h +9 -0
  160. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_dummy.h +1 -0
  161. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/operations_generic.h +3 -0
  162. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/resnet_block/layer.h +223 -0
  163. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/resnet_block/operations_cuda.h +138 -0
  164. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/resnet_block/operations_generic.h +428 -0
  165. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/resnet_block/persist.h +70 -0
  166. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/sample_and_squash/layer.h +154 -0
  167. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/sample_and_squash/operations_cuda.h +119 -0
  168. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/sample_and_squash/operations_generic.h +494 -0
  169. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/sample_and_squash/persist.h +50 -0
  170. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/sample_and_squash/persist_code.h +173 -0
  171. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/standardize/layer.h +116 -0
  172. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/standardize/operations_cuda.h +156 -0
  173. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/standardize/operations_generic.h +291 -0
  174. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/standardize/persist.h +83 -0
  175. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/standardize/persist_code.h +163 -0
  176. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/td3_sampling/layer.h +123 -0
  177. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/td3_sampling/operations_generic.h +268 -0
  178. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/td3_sampling/persist.h +17 -0
  179. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/td3_sampling/persist_code.h +164 -0
  180. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/unflatten/layer.h +122 -0
  181. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/unflatten/operations_cuda.h +55 -0
  182. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/unflatten/operations_generic.h +158 -0
  183. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/unflatten/persist.h +47 -0
  184. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/unflatten/persist_code.h +106 -0
  185. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/upsample2d/layer.h +132 -0
  186. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/upsample2d/operations_cuda.h +141 -0
  187. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/layers/upsample2d/operations_generic.h +228 -0
  188. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/loss_functions/categorical_cross_entropy/operations_generic.h +102 -0
  189. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/loss_functions/mse/operations_cuda.h +97 -0
  190. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/loss_functions/mse/operations_generic.h +101 -0
  191. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/loss_functions/operations_generic.h +2 -0
  192. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/nn.h +16 -0
  193. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cpu.h +1 -0
  194. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cpu_accelerate.h +1 -0
  195. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cpu_blas.h +1 -0
  196. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cpu_mkl.h +1 -0
  197. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cpu_mux.h +16 -0
  198. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cpu_openblas.h +1 -0
  199. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_cuda.h +2 -0
  200. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_dummy.h +1 -0
  201. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/operations_generic.h +17 -0
  202. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/adam.h +120 -0
  203. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/instance/operations_cuda.h +90 -0
  204. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/instance/operations_generic.h +144 -0
  205. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/instance/persist.h +39 -0
  206. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/instance/persist_code.h +79 -0
  207. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/operations_cuda.h +72 -0
  208. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/operations_generic.h +102 -0
  209. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/adam/persist.h +25 -0
  210. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/lamb/instance/operations_generic.h +101 -0
  211. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/lamb/lamb.h +40 -0
  212. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/lamb/operations_generic.h +61 -0
  213. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/optimizers.h +3 -0
  214. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/instance/operations_cuda.h +77 -0
  215. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/instance/operations_generic.h +134 -0
  216. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/instance/persist.h +37 -0
  217. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/instance/persist_code.h +71 -0
  218. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/operations_cuda.h +40 -0
  219. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/operations_generic.h +43 -0
  220. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/optimizers/sgd/sgd.h +91 -0
  221. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/parameters/operations_cuda.h +0 -0
  222. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/parameters/operations_generic.h +90 -0
  223. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/parameters/parameters.h +78 -0
  224. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/parameters/persist.h +34 -0
  225. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/parameters/persist_code.h +133 -0
  226. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/persist.h +2 -0
  227. hyperdrone/_vendor/rl-tools/include/rl_tools/nn/persist_code.h +27 -0
  228. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp/network.h +174 -0
  229. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp/operations_cuda.h +10 -0
  230. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp/operations_dummy.h +8 -0
  231. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp/operations_generic.h +381 -0
  232. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp/persist.h +56 -0
  233. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp/persist_code.h +137 -0
  234. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp_unconditional_stddev/network.h +45 -0
  235. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp_unconditional_stddev/operations_generic.h +76 -0
  236. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp_unconditional_stddev/persist.h +43 -0
  237. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/mlp_unconditional_stddev/persist_code.h +135 -0
  238. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/models.h +3 -0
  239. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/multi_agent_wrapper/model.h +148 -0
  240. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/multi_agent_wrapper/operations_generic.h +280 -0
  241. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/multi_agent_wrapper/persist.h +25 -0
  242. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/multi_agent_wrapper/persist_code.h +71 -0
  243. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/operations_cpu.h +0 -0
  244. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/operations_cuda.h +1 -0
  245. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/operations_dummy.h +1 -0
  246. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/operations_generic.h +6 -0
  247. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/parallel/model.h +276 -0
  248. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/parallel/operations_cuda.h +165 -0
  249. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/parallel/operations_generic.h +571 -0
  250. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/parallel/persist.h +80 -0
  251. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/parallel/persist_code.h +196 -0
  252. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/persist.h +1 -0
  253. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/persist_code.h +1 -0
  254. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/random_uniform/model.h +43 -0
  255. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/random_uniform/operations_generic.h +73 -0
  256. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/resnet/resnet.h +97 -0
  257. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/sequential/model.h +256 -0
  258. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/sequential/operations_generic.h +564 -0
  259. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/sequential/persist.h +99 -0
  260. hyperdrone/_vendor/rl-tools/include/rl_tools/nn_models/sequential/persist_code.h +107 -0
  261. hyperdrone/_vendor/rl-tools/include/rl_tools/numeric_types/bf16.h +28 -0
  262. hyperdrone/_vendor/rl-tools/include/rl_tools/numeric_types/categories.h +22 -0
  263. hyperdrone/_vendor/rl-tools/include/rl_tools/numeric_types/persist_code.h +54 -0
  264. hyperdrone/_vendor/rl-tools/include/rl_tools/numeric_types/policy.h +48 -0
  265. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/arm/group_1.h +18 -0
  266. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/arm/group_2.h +14 -0
  267. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/arm/group_3.h +14 -0
  268. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/arm.h +19 -0
  269. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu/group_1.h +16 -0
  270. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu/group_2.h +12 -0
  271. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu/group_3.h +15 -0
  272. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu.h +19 -0
  273. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_accelerate/group_1.h +16 -0
  274. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_accelerate/group_2.h +12 -0
  275. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_accelerate/group_3.h +15 -0
  276. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_accelerate.h +19 -0
  277. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_mkl/group_1.h +17 -0
  278. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_mkl/group_2.h +12 -0
  279. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_mkl/group_3.h +15 -0
  280. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_mkl.h +18 -0
  281. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_mux.h +148 -0
  282. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_openblas/group_1.h +16 -0
  283. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_openblas/group_2.h +12 -0
  284. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_openblas/group_3.h +15 -0
  285. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_openblas.h +18 -0
  286. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_tensorboard/group_1.h +16 -0
  287. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_tensorboard/group_2.h +12 -0
  288. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_tensorboard/group_3.h +15 -0
  289. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cpu_tensorboard.h +19 -0
  290. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cuda/group_1.h +18 -0
  291. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cuda/group_2.h +12 -0
  292. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cuda/group_3.h +12 -0
  293. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/cuda.h +19 -0
  294. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/dummy/group_1.h +15 -0
  295. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/dummy/group_2.h +12 -0
  296. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/dummy/group_3.h +12 -0
  297. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/dummy.h +19 -0
  298. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/esp32/group_1.h +16 -0
  299. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/esp32/group_2.h +12 -0
  300. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/esp32/group_3.h +13 -0
  301. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/esp32.h +19 -0
  302. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/wasm32/group_1.h +15 -0
  303. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/wasm32/group_2.h +12 -0
  304. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/wasm32/group_3.h +12 -0
  305. hyperdrone/_vendor/rl-tools/include/rl_tools/operations/wasm32.h +19 -0
  306. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/hdf5/hdf5.h +54 -0
  307. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/hdf5/operations_cpu.h +419 -0
  308. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/tar/io.h +55 -0
  309. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/tar/operations_cpu.h +58 -0
  310. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/tar/operations_generic.h +620 -0
  311. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/tar/operations_posix.h +63 -0
  312. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/backends/tar/tar.h +74 -0
  313. hyperdrone/_vendor/rl-tools/include/rl_tools/persist/code.h +38 -0
  314. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_arm.h +39 -0
  315. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_cpu.h +61 -0
  316. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_cuda.h +164 -0
  317. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_dummy.h +72 -0
  318. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_esp32.h +45 -0
  319. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_generic.h +133 -0
  320. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_generic_array.h +64 -0
  321. hyperdrone/_vendor/rl-tools/include/rl_tools/random/operations_wasm32.h +57 -0
  322. hyperdrone/_vendor/rl-tools/include/rl_tools/random/persist.h +77 -0
  323. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/README.md +149 -0
  324. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/generic/operations_cpu.h +768 -0
  325. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/generic/operations_generic.h +1173 -0
  326. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/metal/context.h +177 -0
  327. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/metal/device_source.h +17 -0
  328. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/metal/operations_cpu.h +1122 -0
  329. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/optix/device.h +212 -0
  330. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/optix/device_impl.h +934 -0
  331. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/optix/operations_cuda.h +1678 -0
  332. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/optix/overlay_accel.h +57 -0
  333. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/vulkan/context.h +220 -0
  334. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/vulkan/device_source.h +40 -0
  335. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/backends/vulkan/operations_cpu.h +1967 -0
  336. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/operations_cpu_common.h +1986 -0
  337. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/operations_cpu_mux.h +19 -0
  338. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/renderer.h +376 -0
  339. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/scene/procthor/operations_cpu.h +226 -0
  340. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/scene/procthor/scene.h +25 -0
  341. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/scene/scene.h +31 -0
  342. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/scene.h +107 -0
  343. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/transforms_generic.h +159 -0
  344. hyperdrone/_vendor/rl-tools/include/rl_tools/rendering/raytracing/types.h +39 -0
  345. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/algorithms.h +6 -0
  346. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/operations_cpu.h +1 -0
  347. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/operations_cpu_mkl.h +1 -0
  348. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/operations_generic.h +1 -0
  349. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/loop/core/config.h +240 -0
  350. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/loop/core/operations_cuda.h +62 -0
  351. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/loop/core/operations_generic.h +245 -0
  352. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/loop/core/persist.h +102 -0
  353. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/loop/core/state.h +52 -0
  354. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/operations_cuda.h +193 -0
  355. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/operations_generic.h +334 -0
  356. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/operations_generic_extensions.h +244 -0
  357. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/persist.h +28 -0
  358. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/ppo/ppo.h +105 -0
  359. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/loop/core/approximators_gru.h +84 -0
  360. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/loop/core/approximators_mlp.h +61 -0
  361. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/loop/core/config.h +106 -0
  362. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/loop/core/operations_generic.h +193 -0
  363. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/loop/core/state.h +52 -0
  364. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/operations_cpu.h +9 -0
  365. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/operations_cpu_accelerate.h +2 -0
  366. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/operations_cpu_mkl.h +2 -0
  367. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/operations_cpu_mux.h +9 -0
  368. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/operations_cuda.h +131 -0
  369. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/operations_generic.h +580 -0
  370. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/sac/sac.h +151 -0
  371. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/loop/core/approximators_gru.h +72 -0
  372. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/loop/core/approximators_mlp.h +54 -0
  373. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/loop/core/config.h +107 -0
  374. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/loop/core/operations_generic.h +172 -0
  375. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/loop/core/state.h +46 -0
  376. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/operations_cpu.h +9 -0
  377. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/operations_cpu_accelerate.h +2 -0
  378. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/operations_cpu_mkl.h +2 -0
  379. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/operations_cpu_mux.h +9 -0
  380. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/operations_cuda.h +111 -0
  381. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/operations_generic.h +359 -0
  382. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/algorithms/td3/td3.h +141 -0
  383. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/components.h +4 -0
  384. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/off_policy_runner.h +225 -0
  385. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/operations_cpu.h +95 -0
  386. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/operations_cpu_accelerate.h +21 -0
  387. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/operations_cpu_mkl.h +21 -0
  388. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/operations_cuda.h +237 -0
  389. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/operations_generic.h +498 -0
  390. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/off_policy_runner/operations_generic_per_env.h +112 -0
  391. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/on_policy_runner.h +106 -0
  392. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_cpu.h +16 -0
  393. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_cpu_accelerate.h +28 -0
  394. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_cpu_mkl.h +15 -0
  395. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_cuda.h +195 -0
  396. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_generic.h +197 -0
  397. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_generic_extensions.h +98 -0
  398. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/operations_generic_per_env.h +91 -0
  399. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/on_policy_runner/persist.h +61 -0
  400. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/operations_cpu.h +2 -0
  401. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/operations_cpu_accelerate.h +1 -0
  402. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/operations_cpu_mkl.h +1 -0
  403. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/operations_generic.h +2 -0
  404. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/replay_buffer/operations_cpu.h +9 -0
  405. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/replay_buffer/operations_generic.h +123 -0
  406. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/replay_buffer/persist.h +57 -0
  407. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/replay_buffer/replay_buffer.h +93 -0
  408. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/running_normalizer/operations_generic.h +76 -0
  409. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/running_normalizer/persist.h +31 -0
  410. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/components/running_normalizer/running_normalizer.h +33 -0
  411. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environment_wrappers/operations_generic.h +58 -0
  412. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environment_wrappers/scale_observations/operations_generic.h +28 -0
  413. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environment_wrappers/scale_observations/wrapper.h +26 -0
  414. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environment_wrappers/wrappers.h +29 -0
  415. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/acrobot/acrobot.h +88 -0
  416. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/acrobot/operations_cpu.h +152 -0
  417. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/acrobot/operations_generic.h +202 -0
  418. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/car/car.h +119 -0
  419. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/car/operations_cpu.h +110 -0
  420. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/car/operations_generic.h +206 -0
  421. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/car/operations_json.h +59 -0
  422. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/car/track.h +23 -0
  423. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/car/ui.h +189 -0
  424. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/environments.h +28 -0
  425. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/flag/environment.h +87 -0
  426. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/flag/operations_cpu.h +212 -0
  427. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/flag/operations_generic.h +215 -0
  428. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/metrics.h +266 -0
  429. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/multirotor.h +1083 -0
  430. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_cpu.h +2119 -0
  431. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_cuda.h +38 -0
  432. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/05_state_is_nan.h +126 -0
  433. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/10_sample_initial_parameters.h +228 -0
  434. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/20_initial_state.h +189 -0
  435. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/30_sample_initial_state.h +276 -0
  436. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/35_get_desired_state.h +63 -0
  437. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/40_observe.h +625 -0
  438. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/50_state_algebra.h +57 -0
  439. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/60_dynamics.h +134 -0
  440. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/70_post_integration.h +329 -0
  441. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic/80_abs_diff.h +290 -0
  442. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_generic.h +369 -0
  443. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_helper_generic.h +45 -0
  444. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_multitask_generic.h +72 -0
  445. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/operations_multitask_generic_forward.h +26 -0
  446. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/default.h +202 -0
  447. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/arpl.h +112 -0
  448. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/crazyflie.h +127 -0
  449. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/crazyflie_openmv.h +119 -0
  450. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/flightmare.h +111 -0
  451. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/fs.h +113 -0
  452. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/mrs.h +110 -0
  453. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/soft.h +117 -0
  454. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/soft_rigid.h +118 -0
  455. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/x500_real.h +88 -0
  456. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/dynamics/x500_sim.h +114 -0
  457. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/init/default.h +56 -0
  458. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/registry.h +90 -0
  459. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/reward_functions/default.h +64 -0
  460. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/reward_functions/reward_functions.h +1 -0
  461. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/reward_functions/squared/operations_generic.h +202 -0
  462. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/reward_functions/squared/squared.h +52 -0
  463. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/termination/default.h +33 -0
  464. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/trajectories/lissajous.h +72 -0
  465. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/parameters/trajectories/trajectory.h +78 -0
  466. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/persist_code.h +53 -0
  467. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/quaternion_helper.h +94 -0
  468. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f/ui.h +180 -0
  469. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f_visual/multirotor_visual.h +135 -0
  470. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f_visual/operations_cpu.h +244 -0
  471. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f_visual/operations_cuda.h +180 -0
  472. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/l2f_visual/operations_generic.h +149 -0
  473. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/memory/environment.h +69 -0
  474. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/memory/operations_cpu.h +46 -0
  475. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/memory/operations_generic.h +78 -0
  476. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/mujoco/ant/README.MD +5 -0
  477. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/mujoco/ant/ant.h +77 -0
  478. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/mujoco/ant/model.h +415 -0
  479. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/mujoco/ant/operations_cpu.h +160 -0
  480. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/mujoco/ant/ui.h +141 -0
  481. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/mujoco/mujoco.h +1 -0
  482. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/multi_agent/bottleneck/bottleneck.h +113 -0
  483. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/multi_agent/bottleneck/operations_cpu.h +289 -0
  484. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/multi_agent/bottleneck/operations_generic.h +495 -0
  485. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/multi_agent/environments.h +16 -0
  486. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/observation.h +37 -0
  487. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/operations_cpu.h +2 -0
  488. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/operations_generic.h +33 -0
  489. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/pendulum/operations_cpu.h +146 -0
  490. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/pendulum/operations_generic.h +262 -0
  491. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/pendulum/pendulum.h +197 -0
  492. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/pendulum/ui.h +97 -0
  493. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/pendulum/ui_xeus.h +124 -0
  494. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/reacher/operations_cpu.h +426 -0
  495. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/reacher/operations_generic.h +424 -0
  496. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/environments/reacher/reacher.h +137 -0
  497. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/loop.h +15 -0
  498. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/checkpoint/config.h +28 -0
  499. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/checkpoint/operations_cpu.h +233 -0
  500. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/checkpoint/persist.h +30 -0
  501. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/checkpoint/state.h +21 -0
  502. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/curriculum/config.h +25 -0
  503. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/curriculum/operations_generic.h +47 -0
  504. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/curriculum/persist.h +20 -0
  505. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/curriculum/state.h +17 -0
  506. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/evaluation/config.h +47 -0
  507. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/evaluation/operations_generic.h +106 -0
  508. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/evaluation/persist.h +40 -0
  509. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/evaluation/state.h +36 -0
  510. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/extrack/config.h +22 -0
  511. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/extrack/operations_cpu.h +44 -0
  512. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/extrack/persist.h +20 -0
  513. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/extrack/state.h +26 -0
  514. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/nn_analytics/config.h +37 -0
  515. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/nn_analytics/operations_cpu.h +113 -0
  516. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/nn_analytics/persist.h +20 -0
  517. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/nn_analytics/state.h +24 -0
  518. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/save_trajectories/config.h +43 -0
  519. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/save_trajectories/operations_cpu.h +190 -0
  520. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/save_trajectories/persist.h +30 -0
  521. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/save_trajectories/state.h +37 -0
  522. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/steps.h +4 -0
  523. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/timing/config.h +27 -0
  524. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/timing/operations_cpu.h +52 -0
  525. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/timing/persist.h +20 -0
  526. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/loop/steps/timing/state.h +25 -0
  527. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/operations_generic.h +3 -0
  528. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/rl.h +5 -0
  529. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/utils/evaluation/evaluation.h +106 -0
  530. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/utils/evaluation/operations_cpu.h +48 -0
  531. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/utils/evaluation/operations_generic.h +275 -0
  532. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/utils/validation.h +269 -0
  533. hyperdrone/_vendor/rl-tools/include/rl_tools/rl/utils/validation_analysis.h +85 -0
  534. hyperdrone/_vendor/rl-tools/include/rl_tools/rl_tools.h +37 -0
  535. hyperdrone/_vendor/rl-tools/include/rl_tools/ui_server/client/client.h +50 -0
  536. hyperdrone/_vendor/rl-tools/include/rl_tools/ui_server/client/operations_boost.h +92 -0
  537. hyperdrone/_vendor/rl-tools/include/rl_tools/ui_server/client/operations_cpu.h +174 -0
  538. hyperdrone/_vendor/rl-tools/include/rl_tools/ui_server/client/operations_websocket.h +208 -0
  539. hyperdrone/_vendor/rl-tools/include/rl_tools/ui_server/server.h +448 -0
  540. hyperdrone/_vendor/rl-tools/include/rl_tools/universe.h +4 -0
  541. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/declarations_cpu.h +13 -0
  542. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_arm.h +25 -0
  543. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_cpu.h +21 -0
  544. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_cuda.h +25 -0
  545. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_dummy.h +18 -0
  546. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_esp32.h +20 -0
  547. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_generic.h +19 -0
  548. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/assert/operations_wasm32.h +18 -0
  549. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/env/operations_cpu.h +16 -0
  550. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/env/operations_generic.h +14 -0
  551. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/extrack/extrack.h +129 -0
  552. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/extrack/operations_cpu.h +588 -0
  553. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/generic/integrators.h +105 -0
  554. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/generic/memcpy.h +16 -0
  555. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/generic/tuple/operations_generic.h +48 -0
  556. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/generic/tuple/tuple.h +149 -0
  557. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/generic/typing.h +118 -0
  558. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/generic/vector_operations.h +174 -0
  559. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/polyak/operations_cuda.h +53 -0
  560. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/polyak/operations_generic.h +93 -0
  561. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/string/operations_generic.h +201 -0
  562. hyperdrone/_vendor/rl-tools/include/rl_tools/utils/zlib/operations_cpu.h +45 -0
  563. hyperdrone/_vendor/rl-tools/include/rl_tools/version.h +28 -0
  564. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/CMakeLists.txt +15 -0
  565. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/CMakeLists.txt +9 -0
  566. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/generic/CMakeLists.txt +17 -0
  567. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/generic/freestanding_check.cpp +113 -0
  568. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/metal/CMakeLists.txt +31 -0
  569. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/metal/device.metal +815 -0
  570. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/metal/metal_cpp_impl.cpp +6 -0
  571. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/optix/CMakeLists.txt +51 -0
  572. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/optix/device.cu +1 -0
  573. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/optix/overlay_accel.cu +275 -0
  574. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/vulkan/CMakeLists.txt +37 -0
  575. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/vulkan/device.comp +865 -0
  576. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/backends/vulkan/device_spirv.cpp +34 -0
  577. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/CMakeLists.txt +205 -0
  578. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/README.md +281 -0
  579. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/benchmark.cpp +175 -0
  580. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/benchmark_dynamic.cpp +494 -0
  581. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/simulator_matrix.cpp +1629 -0
  582. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/simulator_matrix_physics.cu +523 -0
  583. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/benchmark/simulator_matrix_physics.h +37 -0
  584. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/CMakeLists.txt +164 -0
  585. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/antialiasing.cpp +213 -0
  586. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/drone.cpp +367 -0
  587. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/drone_device.cu +385 -0
  588. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/environment/environment.h +85 -0
  589. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/environment/operations_cpu.h +270 -0
  590. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/example.cpp +276 -0
  591. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/fixed_pose.cpp +218 -0
  592. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/interactive.cpp +866 -0
  593. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/make_drone_glb.py +172 -0
  594. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/motion_blur.cpp +232 -0
  595. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/render_pose_trace.cpp +1833 -0
  596. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/example/render_pose_trace_motion_blur.cpp +646 -0
  597. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/CMakeLists.txt +147 -0
  598. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/README.md +15 -0
  599. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/job.sbatch +28 -0
  600. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/model.h +260 -0
  601. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/model_config.h +24 -0
  602. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/model_forward_cuda.h +397 -0
  603. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/model_operations.h +418 -0
  604. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/model_persist.h +45 -0
  605. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/model_student.h +70 -0
  606. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/scene.cpp +221 -0
  607. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/scene.h +68 -0
  608. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/.build-check/inference_ios.o +0 -0
  609. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/.build-check/libinference_ios.a +0 -0
  610. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/.gitignore +4 -0
  611. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/CMakeLists.txt +4 -0
  612. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/Info.plist +24 -0
  613. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/Info_ios.plist +36 -0
  614. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/Sources/CameraManager.swift +120 -0
  615. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/Sources/ContentView.swift +703 -0
  616. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/Sources/DatasetRecorder.swift +285 -0
  617. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/Sources/YawPredictorApp.swift +25 -0
  618. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/YawPredictor.entitlements +8 -0
  619. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/build.sh +66 -0
  620. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/build_ios.sh +133 -0
  621. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/generate.sh +6 -0
  622. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/h5_to_tar.cpp +82 -0
  623. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/inference.cpp +166 -0
  624. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/inference.h +26 -0
  625. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/project.yml +30 -0
  626. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/swift_app/test_tar_vs_hdf5.cpp +173 -0
  627. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/yaw_prediction_cuda.cu +699 -0
  628. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/yaw_prediction_dataset_overlay.cpp +475 -0
  629. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/yaw_prediction_distill_cuda.cu +995 -0
  630. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/yaw_prediction_eval.cu +456 -0
  631. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/yaw_prediction_real_world_eval.cpp +660 -0
  632. hyperdrone/_vendor/rl-tools/src/rendering/raytracing/yaw_prediction/yaw_prediction_viewer.cu +445 -0
  633. hyperdrone/cuda/__init__.py +78 -0
  634. hyperdrone/dynamics/__init__.py +22 -0
  635. hyperdrone/dynamics/_component.py +40 -0
  636. hyperdrone/dynamics/_config.py +47 -0
  637. hyperdrone/dynamics/_sim.py +201 -0
  638. hyperdrone/env/__init__.py +15 -0
  639. hyperdrone/env/_sampling.py +67 -0
  640. hyperdrone/env/_world.py +60 -0
  641. hyperdrone/examples/__init__.py +11 -0
  642. hyperdrone/examples/benchmark.py +236 -0
  643. hyperdrone/examples/benchmark_minimal.py +66 -0
  644. hyperdrone/examples/data.py +42 -0
  645. hyperdrone/examples/drone_flythrough.py +142 -0
  646. hyperdrone/examples/render_procthor.py +41 -0
  647. hyperdrone/jit/__init__.py +111 -0
  648. hyperdrone/jit/_build.py +94 -0
  649. hyperdrone/jit/_lock.py +23 -0
  650. hyperdrone/jit/_patches.py +95 -0
  651. hyperdrone/jit/_toolchain.py +13 -0
  652. hyperdrone/jit/_workspace.py +70 -0
  653. hyperdrone/render/__init__.py +48 -0
  654. hyperdrone/render/_component.py +35 -0
  655. hyperdrone/render/_config.py +90 -0
  656. hyperdrone/render/_renderer.py +306 -0
  657. hyperdrone/render/_scene.py +34 -0
  658. hyperdrone-0.1.0.dist-info/METADATA +15 -0
  659. hyperdrone-0.1.0.dist-info/RECORD +660 -0
  660. hyperdrone-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,1986 @@
1
+ #include "../../version.h"
2
+ #include "../../rl_tools.h"
3
+ #if (defined(RL_TOOLS_DISABLE_INCLUDE_GUARDS) || !defined(RL_TOOLS_RENDERING_RAYTRACING_OPERATIONS_CPU_COMMON_H)) && (RL_TOOLS_USE_THIS_VERSION == 1)
4
+ #pragma once
5
+ #define RL_TOOLS_RENDERING_RAYTRACING_OPERATIONS_CPU_COMMON_H
6
+
7
+ #include "renderer.h"
8
+ #include "transforms_generic.h"
9
+
10
+ // STATIC gives the stb implementations internal linkage so multiple TUs of one binary may include
11
+ // this header without duplicate-symbol link errors; RL_TOOLS_STB_PROVIDED arbitrates with other
12
+ // stb-providing headers (e.g. the test golden_io.h) so the implementation lands exactly once per
13
+ // TU regardless of include order (stb's implementation section has no include guard).
14
+ #ifndef RL_TOOLS_STB_PROVIDED
15
+ #define RL_TOOLS_STB_PROVIDED
16
+ #define STB_IMAGE_WRITE_STATIC
17
+ #define STB_IMAGE_WRITE_IMPLEMENTATION
18
+ #include "stb_image_write.h"
19
+ #define STB_IMAGE_STATIC
20
+ #define STB_IMAGE_IMPLEMENTATION
21
+ #include "stb_image.h"
22
+ #endif
23
+ #include <assimp/Importer.hpp>
24
+ #include <assimp/scene.h>
25
+ #include <assimp/postprocess.h>
26
+ #include <assimp/GltfMaterial.h>
27
+ #include <nlohmann/json.hpp>
28
+
29
+ #include <vector>
30
+ #include <limits>
31
+ #include <algorithm>
32
+ #include <functional>
33
+ #include <string>
34
+ #include <map>
35
+ #include <chrono>
36
+ #include <cmath>
37
+ #include <cstring>
38
+ #include <cstdio>
39
+ #include <cstdint>
40
+ #include <fstream>
41
+ #include <iostream>
42
+
43
+ #define RL_TOOLS_RENDERING_RAYTRACING_LOG(message) do { std::cout << "\033[0;34m" << "#rl_tools::rendering::raytracing: " << message << "\033[0m" << std::endl; } while(false)
44
+ #define RL_TOOLS_RENDERING_RAYTRACING_LOG_ERR(message) do { std::cerr << "\033[0;31m" << "#rl_tools::rendering::raytracing: " << message << "\033[0m" << std::endl; } while(false)
45
+
46
+ #ifndef RL_TOOLS_RENDERING_RAYTRACING_DISABLE_PROBE_RAYS
47
+ #define RL_TOOLS_RENDERING_RAYTRACING_DISABLE_PROBE_RAYS 0
48
+ #endif
49
+
50
+ RL_TOOLS_NAMESPACE_WRAPPER_START
51
+ namespace rl_tools {
52
+ namespace rendering::raytracing::detail{
53
+ template <typename BACKEND>
54
+ void announce_backend(){
55
+ std::fprintf(
56
+ stderr,
57
+ "#rl_tools::rendering::raytracing: backend=%s\n",
58
+ rendering::raytracing::backends::name<BACKEND>()
59
+ );
60
+ std::fflush(stderr);
61
+ }
62
+
63
+ template <typename SPEC, typename BACKEND>
64
+ void announce_backend(const rendering::raytracing::Renderer<SPEC, BACKEND>&){
65
+ announce_backend<BACKEND>();
66
+ }
67
+ }
68
+
69
+ // =========================================================================
70
+ // Default cube geometry
71
+ // =========================================================================
72
+ namespace rendering::raytracing::constants{
73
+ const int NUM_VERTICES = 8;
74
+ const float default_vertices[8][3] = {
75
+ { -1.f,-1.f,-1.f },
76
+ { +1.f,-1.f,-1.f },
77
+ { -1.f,+1.f,-1.f },
78
+ { +1.f,+1.f,-1.f },
79
+ { -1.f,-1.f,+1.f },
80
+ { +1.f,-1.f,+1.f },
81
+ { -1.f,+1.f,+1.f },
82
+ { +1.f,+1.f,+1.f }
83
+ };
84
+ const int NUM_INDICES = 12;
85
+ const int default_indices[12][3] = {
86
+ { 0,1,3 }, { 2,3,0 },
87
+ { 5,7,6 }, { 5,6,4 },
88
+ { 0,4,5 }, { 0,5,1 },
89
+ { 2,3,7 }, { 2,7,6 },
90
+ { 1,5,7 }, { 1,7,3 },
91
+ { 4,0,2 }, { 4,2,6 }
92
+ };
93
+ }
94
+
95
+ namespace rendering::raytracing::vec3{
96
+ template <typename T>
97
+ RL_TOOLS_FUNCTION_PLACEMENT void sub(const T a[3], const T b[3], T out[3]){
98
+ out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2];
99
+ }
100
+ template <typename T>
101
+ RL_TOOLS_FUNCTION_PLACEMENT T dot(const T a[3], const T b[3]){
102
+ return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
103
+ }
104
+ template <typename T>
105
+ RL_TOOLS_FUNCTION_PLACEMENT void cross(const T a[3], const T b[3], T out[3]){
106
+ out[0] = a[1]*b[2] - a[2]*b[1];
107
+ out[1] = a[2]*b[0] - a[0]*b[2];
108
+ out[2] = a[0]*b[1] - a[1]*b[0];
109
+ }
110
+ template <typename T>
111
+ RL_TOOLS_FUNCTION_PLACEMENT T length(const T v[3]){
112
+ return sqrtf(dot(v, v));
113
+ }
114
+ template <typename T>
115
+ RL_TOOLS_FUNCTION_PLACEMENT void normalize(const T v[3], T out[3]){
116
+ T len = length(v);
117
+ out[0] = v[0]/len; out[1] = v[1]/len; out[2] = v[2]/len;
118
+ }
119
+ template <typename T>
120
+ RL_TOOLS_FUNCTION_PLACEMENT void scale(const T v[3], T s, T out[3]){
121
+ out[0] = v[0]*s; out[1] = v[1]*s; out[2] = v[2]*s;
122
+ }
123
+ template <typename T>
124
+ RL_TOOLS_FUNCTION_PLACEMENT void add(const T a[3], const T b[3], T out[3]){
125
+ out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2];
126
+ }
127
+ template <typename T>
128
+ RL_TOOLS_FUNCTION_PLACEMENT void cross_normalized(const T a[3], const T b[3], T out[3]){
129
+ T tmp[3];
130
+ cross(a, b, tmp);
131
+ normalize(tmp, out);
132
+ }
133
+ }
134
+
135
+ // =========================================================================
136
+ // Decode an embedded texture from assimp into RGBA8 pixels
137
+ // =========================================================================
138
+ namespace rendering::raytracing{
139
+ struct RepresentativeTextureColor {
140
+ float color[3] = {1.0f, 1.0f, 1.0f};
141
+ };
142
+
143
+ static inline float srgb_to_linear(unsigned char value) {
144
+ const float x = static_cast<float>(value) / 255.0f;
145
+ return x <= 0.04045f ? x / 12.92f : std::pow((x + 0.055f) / 1.055f, 2.4f);
146
+ }
147
+
148
+ static inline bool representative_texture_color(const std::vector<uint8_t>& pixels, int w, int h, RepresentativeTextureColor& out) {
149
+ if(w <= 0 || h <= 0 || pixels.size() < static_cast<size_t>(w) * static_cast<size_t>(h) * 4) {
150
+ return false;
151
+ }
152
+ double sum[3] = {0.0, 0.0, 0.0};
153
+ double weight_sum = 0.0;
154
+ for(int i = 0; i < w * h; i++) {
155
+ const double alpha = static_cast<double>(pixels[i * 4 + 3]) / 255.0;
156
+ sum[0] += static_cast<double>(srgb_to_linear(pixels[i * 4 + 0])) * alpha;
157
+ sum[1] += static_cast<double>(srgb_to_linear(pixels[i * 4 + 1])) * alpha;
158
+ sum[2] += static_cast<double>(srgb_to_linear(pixels[i * 4 + 2])) * alpha;
159
+ weight_sum += alpha;
160
+ }
161
+ if(weight_sum <= 0.0) {
162
+ for(int i = 0; i < w * h; i++) {
163
+ sum[0] += static_cast<double>(srgb_to_linear(pixels[i * 4 + 0]));
164
+ sum[1] += static_cast<double>(srgb_to_linear(pixels[i * 4 + 1]));
165
+ sum[2] += static_cast<double>(srgb_to_linear(pixels[i * 4 + 2]));
166
+ }
167
+ weight_sum = static_cast<double>(w) * static_cast<double>(h);
168
+ }
169
+ out.color[0] = static_cast<float>(sum[0] / weight_sum);
170
+ out.color[1] = static_cast<float>(sum[1] / weight_sum);
171
+ out.color[2] = static_cast<float>(sum[2] / weight_sum);
172
+ return true;
173
+ }
174
+
175
+ static inline bool decode_embedded_texture(const aiTexture* tex,
176
+ std::vector<uint8_t>& pixels,
177
+ int& w, int& h){
178
+ if(tex->mHeight != 0){
179
+ w = tex->mWidth;
180
+ h = tex->mHeight;
181
+ pixels.resize(w * h * 4);
182
+ for(int i = 0; i < w * h; i++){
183
+ pixels[i*4+0] = tex->pcData[i].r;
184
+ pixels[i*4+1] = tex->pcData[i].g;
185
+ pixels[i*4+2] = tex->pcData[i].b;
186
+ pixels[i*4+3] = tex->pcData[i].a;
187
+ }
188
+ return true;
189
+ } else {
190
+ int channels;
191
+ unsigned char* data = stbi_load_from_memory(
192
+ reinterpret_cast<const unsigned char*>(tex->pcData),
193
+ tex->mWidth, &w, &h, &channels, 4);
194
+ if(!data) return false;
195
+ pixels.assign(data, data + w * h * 4);
196
+ stbi_image_free(data);
197
+ return true;
198
+ }
199
+ }
200
+
201
+ static inline bool decode_image_bytes(const std::vector<uint8_t>& bytes,
202
+ std::vector<uint8_t>& pixels,
203
+ int& w, int& h){
204
+ int channels;
205
+ unsigned char* data = stbi_load_from_memory(bytes.data(), (int)bytes.size(), &w, &h, &channels, 4);
206
+ if(!data) return false;
207
+ pixels.assign(data, data + (size_t)w * h * 4);
208
+ stbi_image_free(data);
209
+ return true;
210
+ }
211
+
212
+ static inline bool load_representative_texture_color(const aiScene* scene,
213
+ const aiMaterial* mat,
214
+ aiTextureType texture_type,
215
+ std::map<std::string, RepresentativeTextureColor>& cache,
216
+ RepresentativeTextureColor& out,
217
+ size_t& decoded_count) {
218
+ if(mat == nullptr || mat->GetTextureCount(texture_type) == 0) {
219
+ return false;
220
+ }
221
+ aiString tex_path;
222
+ if(mat->GetTexture(texture_type, 0, &tex_path) != AI_SUCCESS) {
223
+ return false;
224
+ }
225
+ const std::string path_str(tex_path.C_Str());
226
+ if(path_str.empty()) {
227
+ return false;
228
+ }
229
+ const std::string cache_key = std::to_string(static_cast<int>(texture_type)) + ":" + path_str;
230
+ auto cached = cache.find(cache_key);
231
+ if(cached != cache.end()) {
232
+ out = cached->second;
233
+ return true;
234
+ }
235
+
236
+ int w = 0;
237
+ int h = 0;
238
+ std::vector<uint8_t> pixels;
239
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
240
+ if(emb_tex) {
241
+ if(!decode_embedded_texture(emb_tex, pixels, w, h)) {
242
+ return false;
243
+ }
244
+ }
245
+ else {
246
+ int channels = 0;
247
+ unsigned char* data = stbi_load(path_str.c_str(), &w, &h, &channels, 4);
248
+ if(!data) {
249
+ return false;
250
+ }
251
+ pixels.assign(data, data + static_cast<size_t>(w) * static_cast<size_t>(h) * 4);
252
+ stbi_image_free(data);
253
+ }
254
+
255
+ if(!representative_texture_color(pixels, w, h, out)) {
256
+ return false;
257
+ }
258
+ cache[cache_key] = out;
259
+ decoded_count++;
260
+ return true;
261
+ }
262
+ }
263
+
264
+ // Lights are parsed from the raw GLB JSON instead of using Assimp's aiScene::mLights: Assimp's
265
+ // KHR_lights_punctual import associates lights to nodes by name and mangles per-light
266
+ // intensity/attenuation (see commit 8278f9a9 "removing assimp loading because it fumbled the lights").
267
+ namespace rendering::raytracing::glb{
268
+ struct Material {
269
+ float metallic;
270
+ float roughness;
271
+ int metallic_roughness_image = -1; // glTF image index, -1 when the material has no MR texture
272
+ };
273
+ struct ParsedMetadata {
274
+ std::vector<rendering::raytracing::SceneLight> lights; // world frame (welded scene loads)
275
+ std::map<int, std::vector<rendering::raytracing::SceneLight>> root_lights; // by scene-root ordinal, in the root node's frame (assembly loads)
276
+ std::map<std::string, Material> materials; // by material name; glTF spec defaults when absent
277
+ std::map<int, std::vector<uint8_t>> images; // encoded bytes of referenced MR images, by glTF image index
278
+ };
279
+
280
+ // accumulates local transforms from the ancestors down to node_idx; stop_ancestor (when
281
+ // >= 0) is excluded, yielding the transform relative to that ancestor's frame
282
+ static inline void node_world_transform(const nlohmann::json& nodes, int node_idx, const std::vector<int>& parent_map, float out[16], int stop_ancestor = -1) {
283
+ float identity[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
284
+ std::memcpy(out, identity, sizeof(identity));
285
+
286
+ std::vector<int> chain;
287
+ for (int cur = node_idx; cur >= 0 && cur != stop_ancestor; cur = parent_map[cur]) chain.push_back(cur);
288
+
289
+ for (int i = (int)chain.size() - 1; i >= 0; i--) {
290
+ const auto& node = nodes[chain[i]];
291
+ float local[16];
292
+ if (node.contains("matrix")) {
293
+ auto& m = node["matrix"];
294
+ for (int j = 0; j < 16; j++) local[j] = m[j].get<float>();
295
+ } else {
296
+ float tx = 0, ty = 0, tz = 0;
297
+ float qx = 0, qy = 0, qz = 0, qw = 1;
298
+ float sx = 1, sy = 1, sz = 1;
299
+ if (node.contains("translation")) { auto& t = node["translation"]; tx = t[0]; ty = t[1]; tz = t[2]; }
300
+ if (node.contains("rotation")) { auto& r = node["rotation"]; qx = r[0]; qy = r[1]; qz = r[2]; qw = r[3]; }
301
+ if (node.contains("scale")) { auto& s = node["scale"]; sx = s[0]; sy = s[1]; sz = s[2]; }
302
+ float r00 = (1 - 2*(qy*qy + qz*qz)) * sx, r01 = 2*(qx*qy - qw*qz) * sy, r02 = 2*(qx*qz + qw*qy) * sz;
303
+ float r10 = 2*(qx*qy + qw*qz) * sx, r11 = (1 - 2*(qx*qx + qz*qz)) * sy, r12 = 2*(qy*qz - qw*qx) * sz;
304
+ float r20 = 2*(qx*qz - qw*qy) * sx, r21 = 2*(qy*qz + qw*qx) * sy, r22 = (1 - 2*(qx*qx + qy*qy)) * sz;
305
+ local[0]=r00; local[4]=r01; local[8]=r02; local[12]=tx;
306
+ local[1]=r10; local[5]=r11; local[9]=r12; local[13]=ty;
307
+ local[2]=r20; local[6]=r21; local[10]=r22; local[14]=tz;
308
+ local[3]=0; local[7]=0; local[11]=0; local[15]=1;
309
+ }
310
+ float tmp[16];
311
+ for (int r = 0; r < 4; r++)
312
+ for (int c = 0; c < 4; c++)
313
+ tmp[r + c*4] = out[r]*local[c*4] + out[r+4]*local[c*4+1] + out[r+8]*local[c*4+2] + out[r+12]*local[c*4+3];
314
+ std::memcpy(out, tmp, sizeof(tmp));
315
+ }
316
+ }
317
+
318
+ static inline void swizzle_gltf_direction_to_renderer(float dx, float dy, float dz, float out[3]) {
319
+ float len = sqrtf(dx*dx + dy*dy + dz*dz);
320
+ if (len <= 1e-6f) {
321
+ out[0] = 0.f;
322
+ out[1] = 0.f;
323
+ out[2] = 1.f;
324
+ return;
325
+ }
326
+ dx /= len;
327
+ dy /= len;
328
+ dz /= len;
329
+ out[0] = dx;
330
+ out[1] = -dz;
331
+ out[2] = dy;
332
+ }
333
+
334
+ static inline ParsedMetadata parse(const std::string& filename) {
335
+ ParsedMetadata result;
336
+ FILE* f = fopen(filename.c_str(), "rb");
337
+ if (!f) return result;
338
+
339
+ uint32_t header[3];
340
+ if (fread(header, 4, 3, f) != 3 || header[0] != 0x46546C67u) { fclose(f); return result; }
341
+
342
+ uint32_t chunk_header[2];
343
+ if (fread(chunk_header, 4, 2, f) != 2) { fclose(f); return result; }
344
+ uint32_t json_len = chunk_header[0];
345
+
346
+ std::string json_str(json_len, '\0');
347
+ if (fread(&json_str[0], 1, json_len, f) != json_len) { fclose(f); return result; }
348
+
349
+ // BIN chunk (glTF buffer 0) directly follows the JSON chunk; chunk lengths include padding
350
+ long bin_data_start = -1;
351
+ long bin_data_length = 0;
352
+ if (fread(chunk_header, 4, 2, f) == 2 && chunk_header[1] == 0x004E4942u) {
353
+ bin_data_start = 12 + 8 + (long)json_len + 8;
354
+ bin_data_length = (long)chunk_header[0];
355
+ }
356
+
357
+ nlohmann::json gltf = nlohmann::json::parse(json_str, nullptr, false);
358
+ if (gltf.is_discarded()) { fclose(f); return result; }
359
+
360
+ // Assimp's defaults for absent glTF pbrMetallicRoughness factors vary across versions;
361
+ // the GLB JSON is authoritative here so scene import is identical on every machine.
362
+ // Absent factors resolve to the glTF spec default 1: exporters omit values equal to
363
+ // the default, which is why intentionally non-metallic materials carry an explicit
364
+ // metallicFactor of 0 while chrome/steel/gold-style materials omit it entirely.
365
+ if (gltf.contains("materials")) {
366
+ for (auto& material : gltf["materials"]) {
367
+ if (!material.contains("name")) continue;
368
+ Material material_import{1.0f, 1.0f};
369
+ if (material.contains("pbrMetallicRoughness")) {
370
+ auto& pbr = material["pbrMetallicRoughness"];
371
+ if (pbr.contains("metallicFactor")) {
372
+ material_import.metallic = pbr["metallicFactor"].get<float>();
373
+ }
374
+ if (pbr.contains("roughnessFactor")) {
375
+ material_import.roughness = pbr["roughnessFactor"].get<float>();
376
+ }
377
+ if (pbr.contains("metallicRoughnessTexture") && pbr["metallicRoughnessTexture"].contains("index")) {
378
+ const int texture_index = pbr["metallicRoughnessTexture"]["index"].get<int>();
379
+ if (gltf.contains("textures") && texture_index >= 0 && texture_index < (int)gltf["textures"].size()
380
+ && gltf["textures"][texture_index].contains("source")) {
381
+ material_import.metallic_roughness_image = gltf["textures"][texture_index]["source"].get<int>();
382
+ }
383
+ }
384
+ }
385
+ result.materials[material["name"].get<std::string>()] = material_import;
386
+ }
387
+
388
+ if (bin_data_start >= 0 && gltf.contains("images") && gltf.contains("bufferViews")) {
389
+ for (auto& [material_name, material_import] : result.materials) {
390
+ const int image_index = material_import.metallic_roughness_image;
391
+ if (image_index < 0 || result.images.count(image_index) > 0) continue;
392
+ if (image_index >= (int)gltf["images"].size()) continue;
393
+ const auto& image = gltf["images"][image_index];
394
+ if (!image.contains("bufferView")) continue;
395
+ const int buffer_view_index = image["bufferView"].get<int>();
396
+ if (buffer_view_index < 0 || buffer_view_index >= (int)gltf["bufferViews"].size()) continue;
397
+ const auto& buffer_view = gltf["bufferViews"][buffer_view_index];
398
+ if (buffer_view.value("buffer", 0) != 0) continue;
399
+ const long byte_offset = (long)buffer_view.value("byteOffset", 0LL);
400
+ const long byte_length = (long)buffer_view.value("byteLength", 0LL);
401
+ if (byte_length <= 0 || byte_offset < 0 || byte_offset + byte_length > bin_data_length) continue;
402
+ if (fseek(f, bin_data_start + byte_offset, SEEK_SET) != 0) continue;
403
+ std::vector<uint8_t> bytes((size_t)byte_length);
404
+ if (fread(bytes.data(), 1, (size_t)byte_length, f) != (size_t)byte_length) continue;
405
+ result.images[image_index] = std::move(bytes);
406
+ }
407
+ }
408
+ }
409
+ fclose(f);
410
+
411
+ auto& nodes = gltf["nodes"];
412
+ std::vector<int> parent_map(nodes.size(), -1);
413
+ for (int i = 0; i < (int)nodes.size(); i++) {
414
+ if (nodes[i].contains("children")) {
415
+ for (auto& child : nodes[i]["children"]) parent_map[child.get<int>()] = i;
416
+ }
417
+ }
418
+
419
+ std::map<int, int> root_ordinal;
420
+ if (gltf.contains("scenes")) {
421
+ const int scene_index = gltf.value("scene", 0);
422
+ if (scene_index >= 0 && scene_index < (int)gltf["scenes"].size() && gltf["scenes"][scene_index].contains("nodes")) {
423
+ int ordinal = 0;
424
+ for (auto& root : gltf["scenes"][scene_index]["nodes"]) root_ordinal[root.get<int>()] = ordinal++;
425
+ }
426
+ }
427
+
428
+ if (gltf.contains("extensions") && gltf["extensions"].contains("KHR_lights_punctual")) {
429
+ auto& light_defs = gltf["extensions"]["KHR_lights_punctual"]["lights"];
430
+ const auto make_light = [](const nlohmann::json& ldef, const std::string& type_str, float intensity, float color_r, float color_g, float color_b, const float transform[16]) {
431
+ rendering::raytracing::SceneLight sl{};
432
+ if (type_str == "directional") sl.type = 0;
433
+ else if (type_str == "spot") sl.type = 2;
434
+ else sl.type = 1;
435
+
436
+ sl.position[0] = transform[12]; sl.position[1] = -transform[14]; sl.position[2] = transform[13];
437
+ sl.color[0] = color_r * intensity; sl.color[1] = color_g * intensity; sl.color[2] = color_b * intensity;
438
+ sl.attenuation_constant = 0.f; sl.attenuation_linear = 0.f; sl.attenuation_quadratic = 1.f;
439
+
440
+ if (type_str == "directional") {
441
+ swizzle_gltf_direction_to_renderer(transform[8], transform[9], transform[10], sl.direction);
442
+ } else if (type_str == "spot") {
443
+ float inner = 0.0f;
444
+ float outer = 0.7854f;
445
+ if (ldef.contains("spot")) {
446
+ inner = ldef["spot"].value("innerConeAngle", inner);
447
+ outer = ldef["spot"].value("outerConeAngle", outer);
448
+ }
449
+ sl.cos_inner_cone = cosf(inner);
450
+ sl.cos_outer_cone = cosf(outer);
451
+ swizzle_gltf_direction_to_renderer(-transform[8], -transform[9], -transform[10], sl.direction);
452
+ }
453
+ return sl;
454
+ };
455
+
456
+ for (int ni = 0; ni < (int)nodes.size(); ni++) {
457
+ auto& node = nodes[ni];
458
+ if (!node.contains("extensions") || !node["extensions"].contains("KHR_lights_punctual")) continue;
459
+ int light_idx = node["extensions"]["KHR_lights_punctual"]["light"].get<int>();
460
+ auto& ldef = light_defs[light_idx];
461
+
462
+ float intensity = ldef.value("intensity", 1.0f);
463
+ std::string type_str = ldef.value("type", "point");
464
+ float color_r = 1, color_g = 1, color_b = 1;
465
+ if (ldef.contains("color")) { color_r = ldef["color"][0]; color_g = ldef["color"][1]; color_b = ldef["color"][2]; }
466
+
467
+ float world[16];
468
+ node_world_transform(nodes, ni, parent_map, world);
469
+ result.lights.push_back(make_light(ldef, type_str, intensity, color_r, color_g, color_b, world));
470
+
471
+ int owning_root = ni;
472
+ while (parent_map[owning_root] >= 0) owning_root = parent_map[owning_root];
473
+ const auto ordinal = root_ordinal.find(owning_root);
474
+ if (ordinal != root_ordinal.end()) {
475
+ float relative[16];
476
+ node_world_transform(nodes, ni, parent_map, relative, owning_root);
477
+ result.root_lights[ordinal->second].push_back(make_light(ldef, type_str, intensity, color_r, color_g, color_b, relative));
478
+ }
479
+ }
480
+ }
481
+
482
+ return result;
483
+ }
484
+ }
485
+
486
+ // =========================================================================
487
+ // load: Assimp scene/object loading
488
+ // =========================================================================
489
+ namespace rendering::raytracing::detail{
490
+ struct DecodedTexture{
491
+ std::vector<uint8_t> pixels;
492
+ int width;
493
+ int height;
494
+ };
495
+ struct MeshConversionState{
496
+ std::map<std::string, size_t> tex_cache;
497
+ std::vector<DecodedTexture> decoded_textures;
498
+ std::map<std::string, rendering::raytracing::RepresentativeTextureColor> representative_texture_color_cache;
499
+ size_t representative_texture_color_meshes = 0;
500
+ size_t representative_texture_color_decoded = 0;
501
+ };
502
+
503
+ template <typename SHADING, bool HAS_RGB>
504
+ rendering::raytracing::Mesh convert_mesh(const aiScene* scene, const aiMesh* mesh, const aiMatrix4x4& global_transform, const rendering::raytracing::glb::ParsedMetadata& glb_metadata, MeshConversionState& state){
505
+ rendering::raytracing::Mesh md;
506
+ [[maybe_unused]] const aiMaterial* mat = nullptr;
507
+ if constexpr (HAS_RGB) {
508
+ if(mesh->mMaterialIndex < scene->mNumMaterials){
509
+ mat = scene->mMaterials[mesh->mMaterialIndex];
510
+ }
511
+ }
512
+
513
+ // vertices: apply node transform, then GLB (Y-up) → FLU (Z-up)
514
+ for(unsigned int v = 0; v < mesh->mNumVertices; v++){
515
+ aiVector3D pos = mesh->mVertices[v];
516
+ pos = global_transform * pos;
517
+ md.vertices.push_back(pos.x);
518
+ md.vertices.push_back(-pos.z);
519
+ md.vertices.push_back(pos.y);
520
+ }
521
+
522
+ if constexpr (HAS_RGB && SHADING::PBR_SHADING) {
523
+ if (mesh->mNormals) {
524
+ aiMatrix3x3 normal_matrix(global_transform);
525
+ for (unsigned int v = 0; v < mesh->mNumVertices; v++) {
526
+ aiVector3D n = normal_matrix * mesh->mNormals[v];
527
+ n.Normalize();
528
+ md.normals.push_back(n.x);
529
+ md.normals.push_back(-n.z);
530
+ md.normals.push_back(n.y);
531
+ }
532
+ }
533
+ }
534
+
535
+ // indices
536
+ for(unsigned int f = 0; f < mesh->mNumFaces; f++){
537
+ const aiFace& face = mesh->mFaces[f];
538
+ if(face.mNumIndices == 3){
539
+ md.indices.push_back(face.mIndices[0]);
540
+ md.indices.push_back(face.mIndices[1]);
541
+ md.indices.push_back(face.mIndices[2]);
542
+ }
543
+ }
544
+
545
+ if constexpr (HAS_RGB && SHADING::LOAD_TEXTURES) {
546
+ unsigned int uv_channel = 0;
547
+ if(mat != nullptr){
548
+ int uv_candidate = 0;
549
+ if(mat->Get(AI_MATKEY_UVWSRC(aiTextureType_BASE_COLOR, 0), uv_candidate) == AI_SUCCESS && uv_candidate >= 0){
550
+ uv_channel = (unsigned int)uv_candidate;
551
+ }
552
+ else if(mat->Get(AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0), uv_candidate) == AI_SUCCESS && uv_candidate >= 0){
553
+ uv_channel = (unsigned int)uv_candidate;
554
+ }
555
+ }
556
+ if(uv_channel >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !mesh->mTextureCoords[uv_channel]){
557
+ for(unsigned int channel_i = 0; channel_i < AI_MAX_NUMBER_OF_TEXTURECOORDS; channel_i++){
558
+ if(mesh->mTextureCoords[channel_i]){
559
+ uv_channel = channel_i;
560
+ break;
561
+ }
562
+ }
563
+ }
564
+ if(mesh->mTextureCoords[uv_channel]){
565
+ for(unsigned int v = 0; v < mesh->mNumVertices; v++){
566
+ const aiVector3D& tc = mesh->mTextureCoords[uv_channel][v];
567
+ md.tex_coords.push_back(tc.x);
568
+ if constexpr (SHADING::PBR_SHADING) {
569
+ md.tex_coords.push_back(1.0f - tc.y);
570
+ } else {
571
+ md.tex_coords.push_back(tc.y);
572
+ }
573
+ }
574
+ }
575
+ }
576
+
577
+ // material / texture
578
+ if constexpr (SHADING::PBR_SHADING) {
579
+ md.color[0] = 1.0f; md.color[1] = 1.0f; md.color[2] = 1.0f;
580
+ } else {
581
+ md.color[0] = 0.8f; md.color[1] = 0.8f; md.color[2] = 0.8f;
582
+ }
583
+ if constexpr (HAS_RGB) {
584
+ if(mat != nullptr){
585
+
586
+ if constexpr (SHADING::PBR_SHADING) {
587
+ aiColor4D base_color(1.0f, 1.0f, 1.0f, 1.0f);
588
+ if (aiGetMaterialColor(mat, AI_MATKEY_BASE_COLOR, &base_color) == AI_SUCCESS) {
589
+ md.color[0] = base_color.r; md.color[1] = base_color.g; md.color[2] = base_color.b;
590
+ } else {
591
+ aiColor4D diffuse;
592
+ if (aiGetMaterialColor(mat, AI_MATKEY_COLOR_DIFFUSE, &diffuse) == AI_SUCCESS) {
593
+ md.color[0] = diffuse.r; md.color[1] = diffuse.g; md.color[2] = diffuse.b;
594
+ }
595
+ }
596
+ } else {
597
+ aiColor4D diffuse;
598
+ if(aiGetMaterialColor(mat, AI_MATKEY_COLOR_DIFFUSE, &diffuse) == AI_SUCCESS){
599
+ md.color[0] = diffuse.r; md.color[1] = diffuse.g; md.color[2] = diffuse.b;
600
+ }
601
+ else if constexpr (!SHADING::LOAD_TEXTURES) {
602
+ aiColor4D base_color;
603
+ if (aiGetMaterialColor(mat, AI_MATKEY_BASE_COLOR, &base_color) == AI_SUCCESS) {
604
+ md.color[0] = base_color.r; md.color[1] = base_color.g; md.color[2] = base_color.b;
605
+ }
606
+ }
607
+ }
608
+
609
+ if constexpr (!SHADING::LOAD_TEXTURES) {
610
+ rendering::raytracing::RepresentativeTextureColor representative_color;
611
+ bool has_representative_color = rendering::raytracing::load_representative_texture_color(
612
+ scene, mat, aiTextureType_DIFFUSE, state.representative_texture_color_cache,
613
+ representative_color, state.representative_texture_color_decoded
614
+ );
615
+ if(!has_representative_color) {
616
+ has_representative_color = rendering::raytracing::load_representative_texture_color(
617
+ scene, mat, aiTextureType_BASE_COLOR, state.representative_texture_color_cache,
618
+ representative_color, state.representative_texture_color_decoded
619
+ );
620
+ }
621
+ if(has_representative_color) {
622
+ md.color[0] *= representative_color.color[0];
623
+ md.color[1] *= representative_color.color[1];
624
+ md.color[2] *= representative_color.color[2];
625
+ state.representative_texture_color_meshes++;
626
+ }
627
+ }
628
+
629
+ if constexpr (SHADING::LOAD_TEXTURES) {
630
+ if(mat->GetTextureCount(aiTextureType_DIFFUSE) > 0){
631
+ aiString tex_path;
632
+ if(mat->GetTexture(aiTextureType_DIFFUSE, 0, &tex_path) == AI_SUCCESS){
633
+ std::string path_str(tex_path.C_Str());
634
+
635
+ auto it = state.tex_cache.find(path_str);
636
+ if(it != state.tex_cache.end()){
637
+ auto& cached = state.decoded_textures[it->second];
638
+ md.texture.pixels = cached.pixels;
639
+ md.texture.width = cached.width;
640
+ md.texture.height = cached.height;
641
+ } else {
642
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
643
+ if(emb_tex){
644
+ int w, h;
645
+ std::vector<uint8_t> pixels;
646
+ if(rendering::raytracing::decode_embedded_texture(emb_tex, pixels, w, h)){
647
+ md.texture.pixels = pixels;
648
+ md.texture.width = w;
649
+ md.texture.height = h;
650
+ state.tex_cache[path_str] = state.decoded_textures.size();
651
+ state.decoded_textures.push_back({std::move(pixels), w, h});
652
+ }
653
+ } else if(!path_str.empty()){
654
+ int w, h, channels;
655
+ unsigned char* data = stbi_load(path_str.c_str(), &w, &h, &channels, 4);
656
+ if(data){
657
+ md.texture.pixels.assign(data, data + w * h * 4);
658
+ md.texture.width = w;
659
+ md.texture.height = h;
660
+ stbi_image_free(data);
661
+ state.tex_cache[path_str] = state.decoded_textures.size();
662
+ state.decoded_textures.push_back({md.texture.pixels, w, h});
663
+ }
664
+ }
665
+ }
666
+ }
667
+ }
668
+ }
669
+
670
+ if constexpr (SHADING::METALLIC_REFLECTIONS || SHADING::PBR_SHADING) {
671
+ float metallic_factor = 0.0f;
672
+ mat->Get(AI_MATKEY_METALLIC_FACTOR, metallic_factor);
673
+ md.metallic = metallic_factor;
674
+ }
675
+
676
+ if constexpr (SHADING::PBR_SHADING) {
677
+ float metallic_factor_pbr = 1.0f;
678
+ mat->Get(AI_MATKEY_METALLIC_FACTOR, metallic_factor_pbr);
679
+ md.metallic = metallic_factor_pbr;
680
+
681
+ float roughness_factor = 1.0f;
682
+ mat->Get(AI_MATKEY_ROUGHNESS_FACTOR, roughness_factor);
683
+ md.roughness = roughness_factor;
684
+
685
+ if constexpr (SHADING::LOAD_TEXTURES) {
686
+ if (mat->GetTextureCount(aiTextureType_NORMALS) > 0) {
687
+ aiString tex_path;
688
+ if (mat->GetTexture(aiTextureType_NORMALS, 0, &tex_path) == AI_SUCCESS) {
689
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
690
+ if (emb_tex) {
691
+ int w, h;
692
+ std::vector<uint8_t> pixels;
693
+ if (rendering::raytracing::decode_embedded_texture(emb_tex, pixels, w, h)) {
694
+ md.normal_map.pixels = std::move(pixels);
695
+ md.normal_map.width = w;
696
+ md.normal_map.height = h;
697
+ }
698
+ }
699
+ }
700
+ }
701
+
702
+ // the metallicRoughness texture is resolved from the GLB JSON, not through
703
+ // Assimp's texture-type taxonomy (which relabels it across versions and orders
704
+ // embedded textures differently from the glTF image array)
705
+ {
706
+ const auto glb_material = glb_metadata.materials.find(mat->GetName().C_Str());
707
+ if (glb_material != glb_metadata.materials.end() && glb_material->second.metallic_roughness_image >= 0) {
708
+ const auto image = glb_metadata.images.find(glb_material->second.metallic_roughness_image);
709
+ if (image != glb_metadata.images.end()) {
710
+ int w, h;
711
+ std::vector<uint8_t> pixels;
712
+ if (rendering::raytracing::decode_image_bytes(image->second, pixels, w, h)) {
713
+ md.metallic_roughness_map.pixels = std::move(pixels);
714
+ md.metallic_roughness_map.width = w;
715
+ md.metallic_roughness_map.height = h;
716
+ }
717
+ }
718
+ }
719
+ }
720
+ }
721
+
722
+ aiColor3D emissive_color(0.f, 0.f, 0.f);
723
+ mat->Get(AI_MATKEY_COLOR_EMISSIVE, emissive_color);
724
+ md.emissive[0] = emissive_color.r; md.emissive[1] = emissive_color.g; md.emissive[2] = emissive_color.b;
725
+
726
+ if constexpr (SHADING::LOAD_TEXTURES) {
727
+ if (mat->GetTextureCount(aiTextureType_EMISSIVE) > 0) {
728
+ aiString tex_path;
729
+ if (mat->GetTexture(aiTextureType_EMISSIVE, 0, &tex_path) == AI_SUCCESS) {
730
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
731
+ if (emb_tex) {
732
+ int w, h;
733
+ std::vector<uint8_t> pixels;
734
+ if (rendering::raytracing::decode_embedded_texture(emb_tex, pixels, w, h)) {
735
+ md.emissive_map.pixels = std::move(pixels);
736
+ md.emissive_map.width = w;
737
+ md.emissive_map.height = h;
738
+ }
739
+ }
740
+ }
741
+ }
742
+
743
+ if (mat->GetTextureCount(aiTextureType_AMBIENT_OCCLUSION) > 0) {
744
+ aiString tex_path;
745
+ if (mat->GetTexture(aiTextureType_AMBIENT_OCCLUSION, 0, &tex_path) == AI_SUCCESS) {
746
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
747
+ if (emb_tex) {
748
+ int w, h;
749
+ std::vector<uint8_t> pixels;
750
+ if (rendering::raytracing::decode_embedded_texture(emb_tex, pixels, w, h)) {
751
+ md.occlusion_map.pixels = std::move(pixels);
752
+ md.occlusion_map.width = w;
753
+ md.occlusion_map.height = h;
754
+ }
755
+ }
756
+ }
757
+ } else if (mat->GetTextureCount(aiTextureType_LIGHTMAP) > 0) {
758
+ aiString tex_path;
759
+ if (mat->GetTexture(aiTextureType_LIGHTMAP, 0, &tex_path) == AI_SUCCESS) {
760
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
761
+ if (emb_tex) {
762
+ int w, h;
763
+ std::vector<uint8_t> pixels;
764
+ if (rendering::raytracing::decode_embedded_texture(emb_tex, pixels, w, h)) {
765
+ md.occlusion_map.pixels = std::move(pixels);
766
+ md.occlusion_map.width = w;
767
+ md.occlusion_map.height = h;
768
+ }
769
+ }
770
+ }
771
+ }
772
+ }
773
+ float opacity_val = 1.0f;
774
+ mat->Get(AI_MATKEY_OPACITY, opacity_val);
775
+ aiColor4D opacity_base_color(1.0f, 1.0f, 1.0f, 1.0f);
776
+ if (aiGetMaterialColor(mat, AI_MATKEY_BASE_COLOR, &opacity_base_color) == AI_SUCCESS) {
777
+ opacity_val = fminf(opacity_val, opacity_base_color.a);
778
+ }
779
+ float transmission_factor = 0.0f;
780
+ mat->Get(AI_MATKEY_TRANSMISSION_FACTOR, transmission_factor);
781
+ if (transmission_factor > 0.0f) {
782
+ opacity_val = fminf(opacity_val, 1.0f - transmission_factor);
783
+ }
784
+ md.opacity = opacity_val;
785
+
786
+ aiString alpha_mode;
787
+ if (mat->Get(AI_MATKEY_GLTF_ALPHAMODE, alpha_mode) == AI_SUCCESS) {
788
+ std::string alpha_mode_str = alpha_mode.C_Str();
789
+ if (alpha_mode_str == "MASK") {
790
+ md.alpha_mode = 1;
791
+ } else if (alpha_mode_str == "BLEND") {
792
+ md.alpha_mode = 2;
793
+ } else {
794
+ md.alpha_mode = 0;
795
+ }
796
+ }
797
+ float alpha_cutoff = 0.5f;
798
+ if (mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, alpha_cutoff) == AI_SUCCESS) {
799
+ md.alpha_cutoff = alpha_cutoff;
800
+ }
801
+ }
802
+
803
+ if constexpr (SHADING::LOAD_TEXTURES) {
804
+ if(!md.texture.present() && mat->GetTextureCount(aiTextureType_BASE_COLOR) > 0){
805
+ aiString tex_path;
806
+ if(mat->GetTexture(aiTextureType_BASE_COLOR, 0, &tex_path) == AI_SUCCESS){
807
+ const aiTexture* emb_tex = scene->GetEmbeddedTexture(tex_path.C_Str());
808
+ if(emb_tex){
809
+ int w, h;
810
+ std::vector<uint8_t> pixels;
811
+ if(rendering::raytracing::decode_embedded_texture(emb_tex, pixels, w, h)){
812
+ md.texture.pixels = pixels;
813
+ md.texture.width = w;
814
+ md.texture.height = h;
815
+ }
816
+ }
817
+ }
818
+ }
819
+ }
820
+ }
821
+ }
822
+
823
+ if constexpr (HAS_RGB && (SHADING::METALLIC_REFLECTIONS || SHADING::PBR_SHADING)) {
824
+ if(mat != nullptr){
825
+ const auto glb_material = glb_metadata.materials.find(mat->GetName().C_Str());
826
+ if(glb_material != glb_metadata.materials.end()){
827
+ md.metallic = glb_material->second.metallic;
828
+ if constexpr (SHADING::PBR_SHADING) {
829
+ md.roughness = glb_material->second.roughness;
830
+ }
831
+ }
832
+ }
833
+ }
834
+
835
+ return md;
836
+ }
837
+
838
+ template <typename SHADING, bool HAS_RGB>
839
+ bool load_scene_data(std::vector<rendering::raytracing::Mesh>& out_meshes, std::vector<rendering::raytracing::SceneLight>& out_lights, const std::string& filename){
840
+ Assimp::Importer importer;
841
+ unsigned int import_flags = aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_ImproveCacheLocality;
842
+ if constexpr (HAS_RGB && SHADING::PBR_SHADING) {
843
+ import_flags |= aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace;
844
+ } else if constexpr (HAS_RGB && SHADING::NORMAL_SHADING) {
845
+ import_flags |= aiProcess_GenNormals;
846
+ }
847
+ const aiScene* scene = importer.ReadFile(filename, import_flags);
848
+
849
+ if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode){
850
+ RL_TOOLS_RENDERING_RAYTRACING_LOG_ERR("Assimp error: " << importer.GetErrorString());
851
+ return false;
852
+ }
853
+
854
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Loaded model with " << scene->mNumMeshes << " mesh(es)");
855
+
856
+ [[maybe_unused]] MeshConversionState conversion_state;
857
+
858
+ size_t total_verts = 0, total_tris = 0;
859
+
860
+ const size_t first_new_mesh = out_meshes.size();
861
+ const auto glb_metadata = rendering::raytracing::glb::parse(filename);
862
+
863
+ // Build mesh-index → global transform map by walking the node tree
864
+ std::vector<std::vector<aiMatrix4x4>> mesh_transforms(scene->mNumMeshes);
865
+ std::function<void(const aiNode*, const aiMatrix4x4&)> collect_transforms = [&](const aiNode* node, const aiMatrix4x4& parent_transform){
866
+ aiMatrix4x4 global_transform = parent_transform * node->mTransformation;
867
+ for(unsigned int i = 0; i < node->mNumMeshes; i++){
868
+ mesh_transforms[node->mMeshes[i]].push_back(global_transform);
869
+ }
870
+ for(unsigned int i = 0; i < node->mNumChildren; i++){
871
+ collect_transforms(node->mChildren[i], global_transform);
872
+ }
873
+ };
874
+ collect_transforms(scene->mRootNode, aiMatrix4x4());
875
+
876
+ for(unsigned int m = 0; m < scene->mNumMeshes; m++){
877
+ const aiMesh* mesh = scene->mMeshes[m];
878
+ auto& transforms = mesh_transforms[m];
879
+ if(transforms.empty()){
880
+ transforms.push_back(aiMatrix4x4());
881
+ }
882
+ for(const auto& global_transform : transforms){
883
+ rendering::raytracing::Mesh md = convert_mesh<SHADING, HAS_RGB>(scene, mesh, global_transform, glb_metadata, conversion_state);
884
+ total_verts += md.vertices.size() / 3;
885
+ total_tris += md.indices.size() / 3;
886
+ out_meshes.push_back(std::move(md));
887
+ } // end for global_transform
888
+ }
889
+
890
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Total vertices: " << total_verts << ", triangles: " << total_tris);
891
+
892
+ const size_t num_new_meshes = out_meshes.size() - first_new_mesh;
893
+ int textured_count = 0;
894
+ int metallic_count = 0;
895
+ for(size_t m = first_new_mesh; m < out_meshes.size(); m++){
896
+ if(out_meshes[m].texture.present()) textured_count++;
897
+ if(out_meshes[m].metallic > 0.f) metallic_count++;
898
+ }
899
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Meshes with textures: " << textured_count << "/" << num_new_meshes
900
+ << ", metallic: " << metallic_count << "/" << num_new_meshes);
901
+ if constexpr (HAS_RGB && !SHADING::LOAD_TEXTURES) {
902
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Representative texture colors: " << conversion_state.representative_texture_color_meshes
903
+ << "/" << num_new_meshes << " meshes, decoded "
904
+ << conversion_state.representative_texture_color_decoded << " texture(s)");
905
+ }
906
+
907
+ for (auto& sl : glb_metadata.lights) {
908
+ out_lights.push_back(sl);
909
+ }
910
+
911
+ return true;
912
+ }
913
+
914
+ inline bool transform_is_identity(const float transform[12]){
915
+ const float identity[12] = {1,0,0,0, 0,1,0,0, 0,0,1,0};
916
+ for(int element = 0; element < 12; element++){
917
+ if(transform[element] != identity[element]){
918
+ return false;
919
+ }
920
+ }
921
+ return true;
922
+ }
923
+
924
+ inline void transform_point(const float transform[12], const float point[3], float out[3]){
925
+ for(int row = 0; row < 3; row++){
926
+ out[row] = transform[row * 4 + 0] * point[0] + transform[row * 4 + 1] * point[1] + transform[row * 4 + 2] * point[2] + transform[row * 4 + 3];
927
+ }
928
+ }
929
+
930
+ inline void transform_vector(const float transform[12], const float vector[3], float out[3]){
931
+ for(int row = 0; row < 3; row++){
932
+ out[row] = transform[row * 4 + 0] * vector[0] + transform[row * 4 + 1] * vector[1] + transform[row * 4 + 2] * vector[2];
933
+ }
934
+ }
935
+
936
+ // conjugates an Assimp (glTF Y-up) node transform into the FLU frame: T_flu = S * T * S^-1,
937
+ // with S the same Y-up -> FLU swizzle that is applied to vertices
938
+ inline void flu_from_assimp(const aiMatrix4x4& transform, float out[12]){
939
+ out[0] = transform.a1; out[1] = -transform.a3; out[2] = transform.a2; out[3] = transform.a4;
940
+ out[4] = -transform.c1; out[5] = transform.c3; out[6] = -transform.c2; out[7] = -transform.c4;
941
+ out[8] = transform.b1; out[9] = -transform.b3; out[10] = transform.b2; out[11] = transform.b4;
942
+ }
943
+
944
+ template <typename SHADING, bool HAS_RGB>
945
+ bool load_assembly_data(rendering::raytracing::ObjectAssembly& assembly, const std::string& filename){
946
+ Assimp::Importer importer;
947
+ unsigned int import_flags = aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_ImproveCacheLocality;
948
+ if constexpr (HAS_RGB && SHADING::PBR_SHADING) {
949
+ import_flags |= aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace;
950
+ } else if constexpr (HAS_RGB && SHADING::NORMAL_SHADING) {
951
+ import_flags |= aiProcess_GenNormals;
952
+ }
953
+ const aiScene* scene = importer.ReadFile(filename, import_flags);
954
+ if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode){
955
+ RL_TOOLS_RENDERING_RAYTRACING_LOG_ERR("Assimp error: " << importer.GetErrorString());
956
+ return false;
957
+ }
958
+ const auto glb_metadata = rendering::raytracing::glb::parse(filename);
959
+ MeshConversionState conversion_state; // shared across parts: textures used by several parts decode once
960
+
961
+ const aiNode* file_root = scene->mRootNode;
962
+ const size_t first_new_part = assembly.parts.size();
963
+ for(unsigned int root_i = 0; root_i < file_root->mNumChildren; root_i++){
964
+ const aiNode* root = file_root->mChildren[root_i];
965
+ rendering::raytracing::Object object;
966
+ object.name = root->mName.C_Str();
967
+
968
+ // geometry lands in the root node's frame: the recursion starts below the root's own
969
+ // transform, which becomes the part placement instead
970
+ std::function<void(const aiNode*, const aiMatrix4x4&)> collect = [&](const aiNode* node, const aiMatrix4x4& parent_transform){
971
+ const aiMatrix4x4 relative_transform = parent_transform * node->mTransformation;
972
+ for(unsigned int mesh_i = 0; mesh_i < node->mNumMeshes; mesh_i++){
973
+ object.meshes.push_back(convert_mesh<SHADING, HAS_RGB>(scene, scene->mMeshes[node->mMeshes[mesh_i]], relative_transform, glb_metadata, conversion_state));
974
+ }
975
+ for(unsigned int child_i = 0; child_i < node->mNumChildren; child_i++){
976
+ collect(node->mChildren[child_i], relative_transform);
977
+ }
978
+ };
979
+ for(unsigned int mesh_i = 0; mesh_i < root->mNumMeshes; mesh_i++){
980
+ object.meshes.push_back(convert_mesh<SHADING, HAS_RGB>(scene, scene->mMeshes[root->mMeshes[mesh_i]], aiMatrix4x4(), glb_metadata, conversion_state));
981
+ }
982
+ for(unsigned int child_i = 0; child_i < root->mNumChildren; child_i++){
983
+ collect(root->mChildren[child_i], aiMatrix4x4());
984
+ }
985
+
986
+ const auto root_lights = glb_metadata.root_lights.find((int)root_i);
987
+ if(root_lights != glb_metadata.root_lights.end()){
988
+ object.lights = root_lights->second;
989
+ }
990
+
991
+ rendering::raytracing::ObjectAssembly::Part part;
992
+ part.object = assembly.objects.size();
993
+ flu_from_assimp(root->mTransformation, part.transform);
994
+ assembly.objects.push_back(std::move(object));
995
+ assembly.parts.push_back(part);
996
+ }
997
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Loaded assembly with " << (assembly.parts.size() - first_new_part) << " part(s)");
998
+ return true;
999
+ }
1000
+
1001
+ // compose_transforms and slerp_transform live in transforms_generic.h (shared with device
1002
+ // producers)
1003
+
1004
+ inline constexpr float IDENTITY_TRANSFORM[12] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0};
1005
+
1006
+ // stages host-verb writes (the per-slot transform_entry mirrors) into the transforms tensor;
1007
+ // backends whose tensor is host-resident call this at the top of update(). Device producers
1008
+ // write the tensor directly and are not staged — a dirty overlay row is owned by the host.
1009
+ template <typename SPEC, typename BACKEND>
1010
+ void flush_overlay_transforms(rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1011
+ using TI = typename SPEC::TI;
1012
+ float* transforms = data(renderer.transforms);
1013
+ for(TI overlay = 0; overlay < SPEC::NUM_OVERLAYS; overlay++){
1014
+ auto& overlay_state = renderer.overlays[overlay];
1015
+ if(!overlay_state.dirty) continue;
1016
+ for(TI slot = 0; slot < SPEC::MAX_OVERLAY_INSTANCES; slot++){
1017
+ std::memcpy(transforms + ((size_t)overlay * SPEC::MAX_OVERLAY_INSTANCES + slot) * 12, overlay_state.slots[slot].transform_entry, 12 * sizeof(float));
1018
+ }
1019
+ overlay_state.dirty = false;
1020
+ }
1021
+ }
1022
+
1023
+ // world = pose ∘ part_local ∘ articulation: the root slot's tensor entry carries the
1024
+ // placement pose, non-root entries articulate their part in the part frame. The
1025
+ // transforms_base overload lets the dynamic-motion-blur loop compose from a per-sample
1026
+ // slab of transforms_motion, which shares the transforms tensor layout.
1027
+ template <typename SPEC, typename BACKEND>
1028
+ void compose_overlay_slot_transform(const rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, const float* transforms_base, typename SPEC::TI overlay, typename SPEC::TI slot_index, float out[12]){
1029
+ const auto& slot = renderer.overlays[overlay].slots[slot_index];
1030
+ const float* row = transforms_base + (size_t)overlay * SPEC::MAX_OVERLAY_INSTANCES * 12;
1031
+ float composed[12];
1032
+ compose_transforms(row + (size_t)slot.pose_slot * 12, slot.part_local, composed);
1033
+ if(slot_index == slot.pose_slot){
1034
+ std::memcpy(out, composed, sizeof(composed));
1035
+ }
1036
+ else{
1037
+ compose_transforms(composed, row + (size_t)slot_index * 12, out);
1038
+ }
1039
+ }
1040
+
1041
+ template <typename SPEC, typename BACKEND>
1042
+ void compose_overlay_slot_transform(const rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, typename SPEC::TI overlay, typename SPEC::TI slot_index, float out[12]){
1043
+ compose_overlay_slot_transform(renderer, data(renderer.transforms), overlay, slot_index, out);
1044
+ }
1045
+
1046
+ inline void invert_transform(const float transform[12], float out[12]){
1047
+ const float a = transform[0], b = transform[1], c = transform[2];
1048
+ const float d = transform[4], e = transform[5], f = transform[6];
1049
+ const float g = transform[8], h = transform[9], i = transform[10];
1050
+ const float cofactor_a = e*i - f*h;
1051
+ const float cofactor_b = f*g - d*i;
1052
+ const float cofactor_c = d*h - e*g;
1053
+ const float inv_det = 1.0f / (a*cofactor_a + b*cofactor_b + c*cofactor_c);
1054
+ out[0] = cofactor_a * inv_det; out[1] = (c*h - b*i) * inv_det; out[2] = (b*f - c*e) * inv_det;
1055
+ out[4] = cofactor_b * inv_det; out[5] = (a*i - c*g) * inv_det; out[6] = (c*d - a*f) * inv_det;
1056
+ out[8] = cofactor_c * inv_det; out[9] = (b*g - a*h) * inv_det; out[10] = (a*e - b*d) * inv_det;
1057
+ out[3] = -(out[0]*transform[3] + out[1]*transform[7] + out[2] *transform[11]);
1058
+ out[7] = -(out[4]*transform[3] + out[5]*transform[7] + out[6] *transform[11]);
1059
+ out[11] = -(out[8]*transform[3] + out[9]*transform[7] + out[10]*transform[11]);
1060
+ }
1061
+
1062
+ // writes one entry into every motion sample of the staging mirror (constant across the
1063
+ // shutter = sharp); the single-pose verbs route through this so a dynamic-motion-blur spec
1064
+ // driven only by them renders identically to camera-only blur
1065
+ template <typename SPEC, typename BACKEND>
1066
+ void stage_motion_entry(rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, typename SPEC::TI overlay, typename SPEC::TI slot, const float entry[12]){
1067
+ if constexpr (SPEC::ENABLE_DYNAMIC_MOTION_BLUR){
1068
+ constexpr size_t SLAB = (size_t)SPEC::NUM_OVERLAYS * SPEC::MAX_OVERLAY_INSTANCES * 12;
1069
+ for(typename SPEC::TI sample = 0; sample < SPEC::MOTION_BLUR_SAMPLES; sample++){
1070
+ std::memcpy(renderer.transforms_motion_staging.data() + sample * SLAB + ((size_t)overlay * SPEC::MAX_OVERLAY_INSTANCES + slot) * 12, entry, 12 * sizeof(float));
1071
+ }
1072
+ renderer.transforms_motion_dirty[overlay] = true;
1073
+ }
1074
+ }
1075
+
1076
+ // CPU expansion of the transforms_pair tensor for backends whose tensors are host-resident
1077
+ // (generic/Vulkan); OptiX runs the same math on-device (overlay_accel_expand_motion).
1078
+ // Producer-style: writes the tensors directly with no dirty flags, so the host-verb flush
1079
+ // never clobbers it — per overlay, use either the set_transform* verbs or the pair path.
1080
+ template <typename SPEC, typename BACKEND>
1081
+ void expand_motion_transforms_host(rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1082
+ using TI = typename SPEC::TI;
1083
+ constexpr size_t SLOTS = (size_t)SPEC::NUM_OVERLAYS * SPEC::MAX_OVERLAY_INSTANCES;
1084
+ const float* pairs = data(renderer.transforms_pair);
1085
+ float* transforms_motion = data(renderer.transforms_motion);
1086
+ float* transforms = data(renderer.transforms);
1087
+ for(size_t slot = 0; slot < SLOTS; slot++){
1088
+ const float* open = pairs + slot * 12;
1089
+ const float* close = pairs + (SLOTS + slot) * 12;
1090
+ for(TI sample = 0; sample < SPEC::MOTION_BLUR_SAMPLES; sample++){
1091
+ const float shutter_t = ((float)sample + 0.5f) / (float)SPEC::MOTION_BLUR_SAMPLES;
1092
+ slerp_transform(open, close, shutter_t, transforms_motion + ((size_t)sample * SLOTS + slot) * 12);
1093
+ }
1094
+ std::memcpy(transforms + slot * 12, close, 12 * sizeof(float));
1095
+ }
1096
+ }
1097
+
1098
+ // stages host-verb writes into the transforms_motion tensor, mirroring
1099
+ // flush_overlay_transforms; backends with a host-resident tensor call it in update()
1100
+ template <typename SPEC, typename BACKEND>
1101
+ void flush_overlay_motion_transforms(rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1102
+ using TI = typename SPEC::TI;
1103
+ constexpr size_t SLAB = (size_t)SPEC::NUM_OVERLAYS * SPEC::MAX_OVERLAY_INSTANCES * 12;
1104
+ float* transforms_motion = data(renderer.transforms_motion);
1105
+ for(TI overlay = 0; overlay < SPEC::NUM_OVERLAYS; overlay++){
1106
+ if(!renderer.transforms_motion_dirty[overlay]) continue;
1107
+ for(TI sample = 0; sample < SPEC::MOTION_BLUR_SAMPLES; sample++){
1108
+ const size_t offset = sample * SLAB + (size_t)overlay * SPEC::MAX_OVERLAY_INSTANCES * 12;
1109
+ std::memcpy(transforms_motion + offset, renderer.transforms_motion_staging.data() + offset, (size_t)SPEC::MAX_OVERLAY_INSTANCES * 12 * sizeof(float));
1110
+ }
1111
+ renderer.transforms_motion_dirty[overlay] = false;
1112
+ }
1113
+ }
1114
+
1115
+ // flattens the asset pool for overlay spawns: appends pool objects to the combined object
1116
+ // list and records per-part global object indices + local transforms on the renderer
1117
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1118
+ void register_pool_assets(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, const rendering::raytracing::AssetPool& pool, std::vector<const rendering::raytracing::Object*>& all_objects){
1119
+ using TI = typename SPEC::TI;
1120
+ renderer.assets.clear();
1121
+ renderer.asset_part_objects.clear();
1122
+ renderer.asset_part_transforms.clear();
1123
+ for(const auto& assembly : pool.assemblies){
1124
+ typename rendering::raytracing::Renderer<SPEC, BACKEND>::AssetRecord record;
1125
+ record.first_part = (TI)renderer.asset_part_objects.size();
1126
+ record.num_parts = (TI)assembly.parts.size();
1127
+ utils::assert_exit(device, record.num_parts <= SPEC::MAX_OVERLAY_INSTANCES, "asset has more parts than the overlay capacity");
1128
+ const TI object_base = (TI)all_objects.size();
1129
+ for(const auto& object : assembly.objects){
1130
+ all_objects.push_back(&object);
1131
+ }
1132
+ for(const auto& part : assembly.parts){
1133
+ renderer.asset_part_objects.push_back(object_base + (TI)part.object);
1134
+ renderer.asset_part_transforms.insert(renderer.asset_part_transforms.end(), part.transform, part.transform + 12);
1135
+ }
1136
+ renderer.assets.push_back(record);
1137
+ }
1138
+ }
1139
+
1140
+ // Deterministic first-fit is a contract, not an implementation detail: the chosen slot defines
1141
+ // the global instance id (segmentation output), which must be reproducible across runs and
1142
+ // identical across backends. Do not replace with a free-list or best-fit strategy.
1143
+ template <typename SPEC, typename BACKEND>
1144
+ typename SPEC::TI first_fit_slot(const rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, size_t overlay, typename SPEC::TI num_parts){
1145
+ using TI = typename SPEC::TI;
1146
+ const auto& state = renderer.overlays[overlay];
1147
+ TI run = 0;
1148
+ for(TI slot = 0; slot < SPEC::MAX_OVERLAY_INSTANCES; slot++){
1149
+ run = state.slots[slot].active ? 0 : run + 1;
1150
+ if(run == num_parts){
1151
+ return slot + 1 - num_parts;
1152
+ }
1153
+ }
1154
+ return SPEC::MAX_OVERLAY_INSTANCES;
1155
+ }
1156
+
1157
+ template <typename SPEC, typename BACKEND>
1158
+ void reset_overlay_state(rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1159
+ using TI = typename SPEC::TI;
1160
+ for(auto& overlay_state : renderer.overlays){
1161
+ for(auto& slot : overlay_state.slots){
1162
+ slot.active = false;
1163
+ }
1164
+ overlay_state.dirty = true;
1165
+ }
1166
+ for(TI attachment_i = 0; attachment_i < SPEC::NUM_CAMERAS * SPEC::MAX_OVERLAYS_PER_CAMERA; attachment_i++){
1167
+ renderer.attachments[attachment_i] = rendering::raytracing::Renderer<SPEC, BACKEND>::INVALID_OVERLAY;
1168
+ }
1169
+ renderer.attachments_dirty = true;
1170
+ }
1171
+
1172
+ template <typename SPEC, typename BACKEND>
1173
+ void compute_scene_bounds(rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, const rendering::raytracing::Scene& scene){
1174
+ // resolved-configuration echo: makes a silently-defaulted (e.g. misspelled) fringe
1175
+ // config member visible on the first run
1176
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("config: " << SPEC::NUM_CAMERAS << " camera(s) " << SPEC::CAM_WIDTH << "x" << SPEC::CAM_HEIGHT
1177
+ << " outputs[rgb=" << SPEC::HAS_RGB << " depth=" << SPEC::HAS_DEPTH << " segmentation=" << SPEC::HAS_SEGMENTATION << (SPEC::SEMANTIC_SEGMENTATION ? " (semantic)" : "") << " normals=" << SPEC::HAS_NORMALS << "]"
1178
+ << " probes=" << SPEC::NUM_PROBES
1179
+ << " motion_blur_samples=" << (SPEC::ENABLE_MOTION_BLUR ? SPEC::MOTION_BLUR_SAMPLES : 0)
1180
+ << " anti_aliasing_grid=" << (SPEC::ENABLE_ANTI_ALIASING ? SPEC::ANTI_ALIASING_GRID_SIZE : 0)
1181
+ << " overlays=" << SPEC::NUM_OVERLAYS << "x" << SPEC::MAX_OVERLAY_INSTANCES << " overlays_per_camera=" << SPEC::MAX_OVERLAYS_PER_CAMERA);
1182
+ float bbox_min[3] = {std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()};
1183
+ float bbox_max[3] = {std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest()};
1184
+ for(const auto& instance : scene.instances){
1185
+ for(const auto& mesh : scene.objects[instance.object].meshes){
1186
+ for(size_t vertex_i = 0; vertex_i + 2 < mesh.vertices.size(); vertex_i += 3){
1187
+ float world[3] = {mesh.vertices[vertex_i], mesh.vertices[vertex_i + 1], mesh.vertices[vertex_i + 2]};
1188
+ if(!instance.identity){
1189
+ const float local[3] = {world[0], world[1], world[2]};
1190
+ transform_point(instance.transform, local, world);
1191
+ }
1192
+ for(int d = 0; d < 3; d++){
1193
+ bbox_min[d] = std::min(bbox_min[d], world[d]);
1194
+ bbox_max[d] = std::max(bbox_max[d], world[d]);
1195
+ }
1196
+ }
1197
+ }
1198
+ }
1199
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Bounding box: [" << bbox_min[0] << "," << bbox_min[1] << "," << bbox_min[2] << "] - ["
1200
+ << bbox_max[0] << "," << bbox_max[1] << "," << bbox_max[2] << "]");
1201
+
1202
+ float center[3], size[3];
1203
+ for(int d = 0; d < 3; d++){
1204
+ center[d] = 0.5f * (bbox_min[d] + bbox_max[d]);
1205
+ size[d] = bbox_max[d] - bbox_min[d];
1206
+ }
1207
+ float max_dim = std::max({size[0], size[1], size[2]});
1208
+ float look_from[3] = {center[0] + max_dim * 1.5f, center[1] + max_dim * 1.5f, center[2] + max_dim * 0.8f};
1209
+ renderer.scene_center[0] = center[0];
1210
+ renderer.scene_center[1] = center[1];
1211
+ renderer.scene_center[2] = center[2];
1212
+ renderer.scene_half_extent[0] = size[0] * 0.5f;
1213
+ renderer.scene_half_extent[1] = size[1] * 0.5f;
1214
+ renderer.scene_half_extent[2] = size[2] * 0.5f;
1215
+ float look_offset[3];
1216
+ rendering::raytracing::vec3::sub(look_from, center, look_offset);
1217
+ renderer.camera_radius = rendering::raytracing::vec3::length(look_offset);
1218
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Camera positioned at [" << look_from[0] << "," << look_from[1] << "," << look_from[2] << "]");
1219
+ }
1220
+
1221
+ // Lights as uploaded to the device: only the PBR tiers consume punctual lights. Object lights
1222
+ // are authored in the object's local frame and follow the instance placing it.
1223
+ template <bool APPLY>
1224
+ std::vector<rendering::raytracing::SceneLight> effective_scene_lights(const rendering::raytracing::Scene& scene){
1225
+ std::vector<rendering::raytracing::SceneLight> lights;
1226
+ if constexpr (APPLY) {
1227
+ lights = scene.lights;
1228
+ for(const auto& instance : scene.instances){
1229
+ for(const auto& object_light : scene.objects[instance.object].lights){
1230
+ rendering::raytracing::SceneLight light = object_light;
1231
+ if(!instance.identity){
1232
+ transform_point(instance.transform, object_light.position, light.position);
1233
+ transform_vector(instance.transform, object_light.direction, light.direction);
1234
+ const float length = sqrtf(light.direction[0]*light.direction[0] + light.direction[1]*light.direction[1] + light.direction[2]*light.direction[2]);
1235
+ if(length > 0){
1236
+ light.direction[0] /= length;
1237
+ light.direction[1] /= length;
1238
+ light.direction[2] /= length;
1239
+ }
1240
+ }
1241
+ lights.push_back(light);
1242
+ }
1243
+ }
1244
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Scene lights: " << lights.size());
1245
+ for (size_t li = 0; li < lights.size(); li++) {
1246
+ auto& sl = lights[li];
1247
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" light " << li << ": pos=(" << sl.position[0] << "," << sl.position[1] << "," << sl.position[2]
1248
+ << ") dir=(" << sl.direction[0] << "," << sl.direction[1] << "," << sl.direction[2]
1249
+ << ") color=(" << sl.color[0] << "," << sl.color[1] << "," << sl.color[2] << ")");
1250
+ }
1251
+ }
1252
+ return lights;
1253
+ }
1254
+ } // namespace rendering::raytracing::detail
1255
+
1256
+ template <typename SHADING = rendering::raytracing::VeryHigh, bool HAS_RGB = true, typename DEVICE>
1257
+ bool load(DEVICE& device, rendering::raytracing::Object& object, const std::string& filename){
1258
+ return rendering::raytracing::detail::load_scene_data<SHADING, HAS_RGB>(object.meshes, object.lights, filename);
1259
+ }
1260
+
1261
+ namespace rendering::raytracing::detail{
1262
+ // FNV-1a over the file bytes: deterministic scene-content identity for library dedup
1263
+ inline bool hash_scene_file(const char* path, uint64_t& hash_out){
1264
+ std::ifstream file(path, std::ios::binary);
1265
+ if(!file){
1266
+ return false;
1267
+ }
1268
+ uint64_t hash = 1469598103934665603ull;
1269
+ char buffer[1 << 16];
1270
+ while(file.read(buffer, sizeof(buffer)) || file.gcount() > 0){
1271
+ const std::streamsize count = file.gcount();
1272
+ for(std::streamsize byte_i = 0; byte_i < count; byte_i++){
1273
+ hash = (hash ^ (uint64_t)(unsigned char)buffer[byte_i]) * 1099511628211ull;
1274
+ }
1275
+ if(count < (std::streamsize)sizeof(buffer)){
1276
+ break;
1277
+ }
1278
+ }
1279
+ hash_out = hash;
1280
+ return true;
1281
+ }
1282
+ }
1283
+
1284
+ // Appends the scene file as one welded static object placed at identity: explicit
1285
+ // composition, the append twin of load below.
1286
+ template <typename SHADING = rendering::raytracing::VeryHigh, bool HAS_RGB = true, typename DEVICE>
1287
+ bool add(DEVICE& device, rendering::raytracing::Scene& scene, const std::string& filename){
1288
+ rendering::raytracing::Object object;
1289
+ if(!rendering::raytracing::detail::load_scene_data<SHADING, HAS_RGB>(object.meshes, scene.lights, filename)){
1290
+ return false;
1291
+ }
1292
+ scene.objects.push_back(std::move(object));
1293
+ scene.instances.push_back({scene.objects.size() - 1, {1,0,0,0, 0,1,0,0, 0,0,1,0}, true});
1294
+ return true;
1295
+ }
1296
+
1297
+ // Scene-level load: the scene file becomes one welded static object placed at identity. The
1298
+ // scene must be empty — reusing a scene across loads silently accumulates geometry (every
1299
+ // renderer re-uploads every previously loaded scene) and no rendering test can see it, so it
1300
+ // is a hard failure; composition is the explicit add(device, scene, filename). A scene file
1301
+ // without any punctual lights gets a neutral 3-directional fill so PBR-shaded content is not
1302
+ // lit by ambient only. Object/asset loads deliberately do not: fill lighting is a scene
1303
+ // decision, not an asset property.
1304
+ template <typename SHADING = rendering::raytracing::VeryHigh, bool HAS_RGB = true, typename DEVICE>
1305
+ bool load(DEVICE& device, rendering::raytracing::Scene& scene, const std::string& filename){
1306
+ utils::assert_exit(device, scene.objects.empty() && scene.instances.empty() && scene.lights.empty(), "load: scene is not empty — use add(device, scene, filename) to compose");
1307
+ if(!add<SHADING, HAS_RGB>(device, scene, filename)){
1308
+ return false;
1309
+ }
1310
+ if(scene.lights.empty()){
1311
+ float inv_sqrt2 = 0.70710678f;
1312
+ scene.lights.push_back({0, {0,0,0}, {-inv_sqrt2, 0.f, inv_sqrt2}, {0.4f, 0.4f, 0.4f}, 0,0,0, 0,0});
1313
+ scene.lights.push_back({0, {0,0,0}, {0.f, -inv_sqrt2, inv_sqrt2}, {0.3f, 0.3f, 0.3f}, 0,0,0, 0,0});
1314
+ scene.lights.push_back({0, {0,0,0}, {0.f, inv_sqrt2, inv_sqrt2}, {0.2f, 0.2f, 0.2f}, 0,0,0, 0,0});
1315
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Scene file has no lights: adding 3 directional fill lights");
1316
+ }
1317
+ return true;
1318
+ }
1319
+
1320
+ namespace rendering::raytracing::detail{
1321
+ // content-hash lookup into the library's owned scenes; loads the file into a fresh
1322
+ // library-owned scene on a miss. Callers key their per-scene data off the returned index.
1323
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1324
+ typename SPEC::TI library_lookup_or_load(DEVICE& device, rendering::raytracing::AssetLibrary<SPEC, BACKEND>& library, const char* scene_path, bool& is_new){
1325
+ using TI = typename SPEC::TI;
1326
+ uint64_t hash = 0;
1327
+ utils::assert_exit(device, hash_scene_file(scene_path, hash), "library: failed to read scene file");
1328
+ for(TI scene_i = 0; scene_i < (TI)library.hashes.size(); scene_i++){
1329
+ if(library.hashes[scene_i] == hash){
1330
+ is_new = false;
1331
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("library: scene " << scene_path << " shares build " << scene_i << " (content hash match)");
1332
+ return scene_i;
1333
+ }
1334
+ }
1335
+ is_new = true;
1336
+ library.hashes.push_back(hash);
1337
+ library.scenes.emplace_back();
1338
+ library.assets.push_back(nullptr);
1339
+ const bool loaded = load<typename SPEC::SHADING, SPEC::HAS_RGB>(device, library.scenes.back(), std::string(scene_path));
1340
+ utils::assert_exit(device, loaded, "library: failed to load scene");
1341
+ return (TI)(library.scenes.size() - 1);
1342
+ }
1343
+ }
1344
+
1345
+ template <typename DEVICE>
1346
+ size_t add(DEVICE& device, rendering::raytracing::Scene& scene, const rendering::raytracing::Object& object, const float transform[12]){
1347
+ scene.objects.push_back(object);
1348
+ scene.instances.push_back({scene.objects.size() - 1, {}, rendering::raytracing::detail::transform_is_identity(transform)});
1349
+ std::memcpy(scene.instances.back().transform, transform, 12 * sizeof(float));
1350
+ return scene.instances.size() - 1;
1351
+ }
1352
+
1353
+ template <typename DEVICE>
1354
+ size_t add(DEVICE& device, rendering::raytracing::Scene& scene, const rendering::raytracing::Object& object){
1355
+ const float identity[12] = {1,0,0,0, 0,1,0,0, 0,0,1,0};
1356
+ return add(device, scene, object, identity);
1357
+ }
1358
+
1359
+ template <typename DEVICE>
1360
+ size_t add(DEVICE& device, rendering::raytracing::Scene& scene, const rendering::raytracing::Mesh& mesh){
1361
+ rendering::raytracing::Object object;
1362
+ object.meshes.push_back(mesh);
1363
+ return add(device, scene, object);
1364
+ }
1365
+
1366
+ template <typename SHADING = rendering::raytracing::VeryHigh, bool HAS_RGB = true, typename DEVICE>
1367
+ bool load(DEVICE& device, rendering::raytracing::ObjectAssembly& assembly, const std::string& filename){
1368
+ return rendering::raytracing::detail::load_assembly_data<SHADING, HAS_RGB>(assembly, filename);
1369
+ }
1370
+
1371
+ template <typename DEVICE>
1372
+ rendering::raytracing::Placement add(DEVICE& device, rendering::raytracing::Scene& scene, const rendering::raytracing::ObjectAssembly& assembly, const float transform[12]){
1373
+ rendering::raytracing::Placement placement{scene.instances.size(), assembly.parts.size()};
1374
+ const size_t object_base = scene.objects.size();
1375
+ scene.objects.insert(scene.objects.end(), assembly.objects.begin(), assembly.objects.end());
1376
+ for(const auto& part : assembly.parts){
1377
+ float composed[12];
1378
+ rendering::raytracing::detail::compose_transforms(transform, part.transform, composed);
1379
+ scene.instances.push_back({object_base + part.object, {}, rendering::raytracing::detail::transform_is_identity(composed)});
1380
+ std::memcpy(scene.instances.back().transform, composed, sizeof(composed));
1381
+ }
1382
+ return placement;
1383
+ }
1384
+
1385
+ template <typename DEVICE>
1386
+ rendering::raytracing::Placement add(DEVICE& device, rendering::raytracing::Scene& scene, const rendering::raytracing::ObjectAssembly& assembly){
1387
+ const float identity[12] = {1,0,0,0, 0,1,0,0, 0,0,1,0};
1388
+ return add(device, scene, assembly, identity);
1389
+ }
1390
+
1391
+ template <typename DEVICE>
1392
+ rendering::raytracing::AssetHandle add(DEVICE& device, rendering::raytracing::AssetPool& pool, const rendering::raytracing::ObjectAssembly& assembly){
1393
+ pool.assemblies.push_back(assembly);
1394
+ return {pool.assemblies.size() - 1};
1395
+ }
1396
+
1397
+ template <typename DEVICE>
1398
+ rendering::raytracing::AssetHandle add(DEVICE& device, rendering::raytracing::AssetPool& pool, const rendering::raytracing::Object& object){
1399
+ rendering::raytracing::ObjectAssembly assembly;
1400
+ assembly.objects.push_back(object);
1401
+ assembly.parts.push_back({0, {1,0,0,0, 0,1,0,0, 0,0,1,0}});
1402
+ return add(device, pool, assembly);
1403
+ }
1404
+
1405
+ template <typename DEVICE>
1406
+ rendering::raytracing::AssetHandle add(DEVICE& device, rendering::raytracing::AssetPool& pool, const rendering::raytracing::Mesh& mesh){
1407
+ rendering::raytracing::Object object;
1408
+ object.meshes.push_back(mesh);
1409
+ return add(device, pool, object);
1410
+ }
1411
+
1412
+ // Validation predicates for boundaries (language bindings, C interface) that must not trip
1413
+ // the fail-fast asserts inside the verbs: check first, then call.
1414
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1415
+ bool can_attach(DEVICE& device, const rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, typename SPEC::TI camera, rendering::raytracing::OverlayIndex overlay){
1416
+ static_assert(SPEC::ENABLE_OVERLAYS, "can_attach requires an overlay-enabled renderer specification");
1417
+ using TI = typename SPEC::TI;
1418
+ if(camera >= SPEC::NUM_CAMERAS || overlay.index >= SPEC::NUM_OVERLAYS){
1419
+ return false;
1420
+ }
1421
+ const TI* row = &renderer.attachments[camera * SPEC::MAX_OVERLAYS_PER_CAMERA];
1422
+ for(TI slot = 0; slot < SPEC::MAX_OVERLAYS_PER_CAMERA; slot++){
1423
+ if(row[slot] == (TI)overlay.index || row[slot] == rendering::raytracing::Renderer<SPEC, BACKEND>::INVALID_OVERLAY){
1424
+ return true;
1425
+ }
1426
+ }
1427
+ return false;
1428
+ }
1429
+
1430
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1431
+ bool can_spawn(DEVICE& device, const rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, rendering::raytracing::AssetHandle asset){
1432
+ static_assert(SPEC::ENABLE_OVERLAYS, "can_spawn requires an overlay-enabled renderer specification");
1433
+ if(overlay.index >= SPEC::NUM_OVERLAYS || asset.index >= renderer.assets.size()){
1434
+ return false;
1435
+ }
1436
+ return rendering::raytracing::detail::first_fit_slot<SPEC>(renderer, overlay.index, renderer.assets[asset.index].num_parts) < SPEC::MAX_OVERLAY_INSTANCES;
1437
+ }
1438
+
1439
+ // Overlay verbs mutate host-side truth on the renderer and mark it dirty; update(device,
1440
+ // renderer) is the single point where the backend consumes it. All bookkeeping is
1441
+ // deterministic: slot allocation is a first-fit scan, so identical call sequences yield
1442
+ // identical slots (and therefore identical global instance ids).
1443
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1444
+ void attach(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, typename SPEC::TI camera, rendering::raytracing::OverlayIndex overlay){
1445
+ static_assert(SPEC::ENABLE_OVERLAYS, "attach requires an overlay-enabled renderer specification");
1446
+ using TI = typename SPEC::TI;
1447
+ utils::assert_exit(device, overlay.index < SPEC::NUM_OVERLAYS, "attach: overlay index out of range");
1448
+ constexpr TI INVALID = rendering::raytracing::Renderer<SPEC, BACKEND>::INVALID_OVERLAY;
1449
+ TI* row = &renderer.attachments[camera * SPEC::MAX_OVERLAYS_PER_CAMERA];
1450
+ TI free_slot = SPEC::MAX_OVERLAYS_PER_CAMERA;
1451
+ for(TI slot = 0; slot < SPEC::MAX_OVERLAYS_PER_CAMERA; slot++){
1452
+ if(row[slot] == (TI)overlay.index){
1453
+ return; // a camera's attachments form a set: attach is idempotent
1454
+ }
1455
+ if(row[slot] == INVALID && free_slot == SPEC::MAX_OVERLAYS_PER_CAMERA){
1456
+ free_slot = slot;
1457
+ }
1458
+ }
1459
+ utils::assert_exit(device, free_slot < SPEC::MAX_OVERLAYS_PER_CAMERA, "attach: camera already holds MAX_OVERLAYS_PER_CAMERA overlays");
1460
+ row[free_slot] = (TI)overlay.index;
1461
+ renderer.attachments_dirty = true;
1462
+ }
1463
+
1464
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1465
+ void detach(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, typename SPEC::TI camera, rendering::raytracing::OverlayIndex overlay){
1466
+ static_assert(SPEC::ENABLE_OVERLAYS, "detach requires an overlay-enabled renderer specification");
1467
+ using TI = typename SPEC::TI;
1468
+ TI* row = &renderer.attachments[camera * SPEC::MAX_OVERLAYS_PER_CAMERA];
1469
+ for(TI slot = 0; slot < SPEC::MAX_OVERLAYS_PER_CAMERA; slot++){
1470
+ if(row[slot] == (TI)overlay.index){
1471
+ row[slot] = rendering::raytracing::Renderer<SPEC, BACKEND>::INVALID_OVERLAY;
1472
+ renderer.attachments_dirty = true;
1473
+ return;
1474
+ }
1475
+ }
1476
+ }
1477
+
1478
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1479
+ rendering::raytracing::OverlayPlacement spawn(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, rendering::raytracing::AssetHandle asset, const float transform[12]){
1480
+ static_assert(SPEC::ENABLE_OVERLAYS, "spawn requires an overlay-enabled renderer specification");
1481
+ using TI = typename SPEC::TI;
1482
+ if(overlay.index >= SPEC::NUM_OVERLAYS){
1483
+ utils::assert_exit(device, false, "spawn: overlay index out of range");
1484
+ return {0, 0, 0};
1485
+ }
1486
+ if(asset.index >= renderer.assets.size()){
1487
+ utils::assert_exit(device, false, "spawn: asset handle out of range");
1488
+ return {0, 0, 0};
1489
+ }
1490
+ auto& state = renderer.overlays[overlay.index];
1491
+ const auto& record = renderer.assets[asset.index];
1492
+
1493
+ const TI first_slot = rendering::raytracing::detail::first_fit_slot<SPEC>(renderer, overlay.index, record.num_parts);
1494
+ if(first_slot >= SPEC::MAX_OVERLAY_INSTANCES){
1495
+ utils::assert_exit(device, false, "spawn: overlay capacity exceeded");
1496
+ return {0, 0, 0};
1497
+ }
1498
+
1499
+ for(TI part = 0; part < record.num_parts && first_slot + part < SPEC::MAX_OVERLAY_INSTANCES; part++){
1500
+ auto& slot = state.slots[first_slot + part];
1501
+ slot.object = renderer.asset_part_objects[record.first_part + part];
1502
+ slot.pose_slot = first_slot;
1503
+ std::memcpy(slot.part_local, &renderer.asset_part_transforms[(record.first_part + part) * 12], sizeof(slot.part_local));
1504
+ std::memcpy(slot.transform_entry, part == 0 ? transform : rendering::raytracing::detail::IDENTITY_TRANSFORM, sizeof(slot.transform_entry));
1505
+ slot.active = true;
1506
+ rendering::raytracing::detail::stage_motion_entry(renderer, (TI)overlay.index, first_slot + part, slot.transform_entry);
1507
+ }
1508
+ state.dirty = true;
1509
+ return {(size_t)first_slot, (size_t)record.num_parts, (size_t)record.first_part};
1510
+ }
1511
+
1512
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1513
+ void despawn(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, const rendering::raytracing::OverlayPlacement& placement){
1514
+ static_assert(SPEC::ENABLE_OVERLAYS, "despawn requires an overlay-enabled renderer specification");
1515
+ auto& state = renderer.overlays[overlay.index];
1516
+ for(size_t part = 0; part < placement.num_parts; part++){
1517
+ state.slots[placement.first_slot + part].active = false;
1518
+ }
1519
+ state.dirty = true;
1520
+ }
1521
+
1522
+ // per-part: part 0 sets the placement pose, other parts articulate in their part frame
1523
+ // (world = pose ∘ part_local ∘ articulation)
1524
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1525
+ void set_transform(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, const rendering::raytracing::OverlayPlacement& placement, typename SPEC::TI part, const float transform[12]){
1526
+ static_assert(SPEC::ENABLE_OVERLAYS, "set_transform requires an overlay-enabled renderer specification");
1527
+ using TI = typename SPEC::TI;
1528
+ auto& state = renderer.overlays[overlay.index];
1529
+ std::memcpy(state.slots[placement.first_slot + part].transform_entry, transform, 12 * sizeof(float));
1530
+ state.dirty = true;
1531
+ rendering::raytracing::detail::stage_motion_entry(renderer, (TI)overlay.index, (TI)(placement.first_slot + part), transform);
1532
+ }
1533
+
1534
+ // rigid move: sets the placement pose and resets per-part articulation state
1535
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1536
+ void set_transform(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, const rendering::raytracing::OverlayPlacement& placement, const float transform[12]){
1537
+ static_assert(SPEC::ENABLE_OVERLAYS, "set_transform requires an overlay-enabled renderer specification");
1538
+ using TI = typename SPEC::TI;
1539
+ auto& state = renderer.overlays[overlay.index];
1540
+ std::memcpy(state.slots[placement.first_slot].transform_entry, transform, 12 * sizeof(float));
1541
+ rendering::raytracing::detail::stage_motion_entry(renderer, (TI)overlay.index, (TI)placement.first_slot, transform);
1542
+ for(size_t part = 1; part < placement.num_parts; part++){
1543
+ std::memcpy(state.slots[placement.first_slot + part].transform_entry, rendering::raytracing::detail::IDENTITY_TRANSFORM, 12 * sizeof(float));
1544
+ rendering::raytracing::detail::stage_motion_entry(renderer, (TI)overlay.index, (TI)(placement.first_slot + part), rendering::raytracing::detail::IDENTITY_TRANSFORM);
1545
+ }
1546
+ state.dirty = true;
1547
+ }
1548
+
1549
+ // dynamic motion blur: per-part shutter-open/close entries, slerped into every motion sample
1550
+ // at the same midpoint shutter times the camera lerp uses; the close entry also becomes the
1551
+ // steady-state transform (segmentation, probes, and the next frame render at shutter close)
1552
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1553
+ void set_transform_pair(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, const rendering::raytracing::OverlayPlacement& placement, typename SPEC::TI part, const float open[12], const float close[12]){
1554
+ static_assert(SPEC::ENABLE_DYNAMIC_MOTION_BLUR, "set_transform_pair requires a dynamic-motion-blur renderer specification");
1555
+ using TI = typename SPEC::TI;
1556
+ auto& state = renderer.overlays[overlay.index];
1557
+ std::memcpy(state.slots[placement.first_slot + part].transform_entry, close, 12 * sizeof(float));
1558
+ state.dirty = true;
1559
+ constexpr size_t SLAB = (size_t)SPEC::NUM_OVERLAYS * SPEC::MAX_OVERLAY_INSTANCES * 12;
1560
+ for(TI sample = 0; sample < SPEC::MOTION_BLUR_SAMPLES; sample++){
1561
+ const float shutter_t = ((float)sample + 0.5f) / (float)SPEC::MOTION_BLUR_SAMPLES;
1562
+ float entry[12];
1563
+ rendering::raytracing::detail::slerp_transform(open, close, shutter_t, entry);
1564
+ std::memcpy(renderer.transforms_motion_staging.data() + sample * SLAB + ((size_t)overlay.index * SPEC::MAX_OVERLAY_INSTANCES + placement.first_slot + part) * 12, entry, 12 * sizeof(float));
1565
+ }
1566
+ renderer.transforms_motion_dirty[overlay.index] = true;
1567
+ }
1568
+
1569
+ // rigid move with shutter-open/close poses: resets articulation in every sample
1570
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1571
+ void set_transform_pair(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, rendering::raytracing::OverlayIndex overlay, const rendering::raytracing::OverlayPlacement& placement, const float open[12], const float close[12]){
1572
+ static_assert(SPEC::ENABLE_DYNAMIC_MOTION_BLUR, "set_transform_pair requires a dynamic-motion-blur renderer specification");
1573
+ using TI = typename SPEC::TI;
1574
+ set_transform_pair(device, renderer, overlay, placement, (TI)0, open, close);
1575
+ auto& state = renderer.overlays[overlay.index];
1576
+ for(size_t part = 1; part < placement.num_parts; part++){
1577
+ std::memcpy(state.slots[placement.first_slot + part].transform_entry, rendering::raytracing::detail::IDENTITY_TRANSFORM, 12 * sizeof(float));
1578
+ rendering::raytracing::detail::stage_motion_entry(renderer, (TI)overlay.index, (TI)(placement.first_slot + part), rendering::raytracing::detail::IDENTITY_TRANSFORM);
1579
+ }
1580
+ state.dirty = true;
1581
+ }
1582
+
1583
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1584
+ auto& transforms(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1585
+ static_assert(SPEC::ENABLE_OVERLAYS, "transforms requires an overlay-enabled renderer specification");
1586
+ return renderer.transforms;
1587
+ }
1588
+
1589
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1590
+ auto& transforms_motion(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1591
+ static_assert(SPEC::ENABLE_DYNAMIC_MOTION_BLUR, "transforms_motion requires a dynamic-motion-blur renderer specification");
1592
+ return renderer.transforms_motion;
1593
+ }
1594
+
1595
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1596
+ auto& transforms_pair(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1597
+ static_assert(SPEC::ENABLE_DYNAMIC_MOTION_BLUR, "transforms_pair requires a dynamic-motion-blur renderer specification");
1598
+ return renderer.transforms_pair;
1599
+ }
1600
+
1601
+ // camera input tensors, backend-native residency like transforms: device memory on OptiX,
1602
+ // host on generic, shared/mapped on Metal/Vulkan. Producers write them via rlt::copy or
1603
+ // kernels; the launch verbs consume them directly. Under motion blur the pair is
1604
+ // cameras_open (shutter open) and cameras_close (shutter close, aliasing cameras) — both
1605
+ // must be written each step (identical values for a blur-free frame).
1606
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1607
+ auto& cameras(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1608
+ return renderer.cameras;
1609
+ }
1610
+
1611
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1612
+ auto& cameras_open(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1613
+ static_assert(SPEC::ENABLE_MOTION_BLUR, "cameras_open requires a motion-blur renderer specification");
1614
+ return renderer.cameras_open;
1615
+ }
1616
+
1617
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1618
+ auto& cameras_close(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1619
+ static_assert(SPEC::ENABLE_MOTION_BLUR, "cameras_close requires a motion-blur renderer specification");
1620
+ return renderer.cameras;
1621
+ }
1622
+
1623
+ // output tensors, same backend-native residency as the inputs: consumers on the device read
1624
+ // them in place (zero-copy); host readers stage through an explicit copy at readback
1625
+ // boundaries (after a _sync)
1626
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1627
+ auto& frame_buffer(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1628
+ static_assert(SPEC::HAS_RGB, "frame_buffer requires an RGB-capable renderer specification");
1629
+ return renderer.frame_buffer;
1630
+ }
1631
+
1632
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1633
+ auto& depth_buffer(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1634
+ static_assert(SPEC::HAS_DEPTH, "depth_buffer requires a depth-capable renderer specification");
1635
+ return renderer.depth_buffer;
1636
+ }
1637
+
1638
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1639
+ auto& segmentation_buffer(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1640
+ static_assert(SPEC::HAS_SEGMENTATION, "segmentation_buffer requires a segmentation-capable renderer specification");
1641
+ return renderer.segmentation_buffer;
1642
+ }
1643
+
1644
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1645
+ auto& normals_buffer(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1646
+ static_assert(SPEC::HAS_NORMALS, "normals_buffer requires a normals-capable renderer specification");
1647
+ return renderer.normals_buffer;
1648
+ }
1649
+
1650
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1651
+ auto& collision_results(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1652
+ return renderer.collision_results;
1653
+ }
1654
+
1655
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1656
+ auto& observation(DEVICE& device, rendering::raytracing::Renderer<SPEC, BACKEND>& renderer){
1657
+ static_assert(SPEC::HAS_OBSERVATION, "observation requires OUTPUT_OBSERVATION in the renderer specification");
1658
+ return renderer.observation;
1659
+ }
1660
+
1661
+ // decodes a rendered segmentation id back to the object it references. Single owner of the
1662
+ // global id layout: scene instances occupy [0, S); overlay o's slot s sits at S + o*CAP + s;
1663
+ // object indices count scene objects first, then each pool assembly's objects in
1664
+ // registration order. Returns nullptr for the miss sentinel and out-of-range ids.
1665
+ // This layout is cross-backend API surface: the generic flat instance array, Metal's user-ID
1666
+ // descriptors, and OptiX's user instance ids all realize it identically, and segmentation
1667
+ // consumers depend on that equivalence — treat any change to it as breaking.
1668
+ template <typename DEVICE, typename SPEC, typename BACKEND>
1669
+ const rendering::raytracing::Object* segmentation_object(DEVICE& device, const rendering::raytracing::Scene& scene, const rendering::raytracing::AssetPool& pool, const rendering::raytracing::Renderer<SPEC, BACKEND>& renderer, uint32_t id){
1670
+ if(id == 0xFFFFFFFFu){
1671
+ return nullptr;
1672
+ }
1673
+ if(id < scene.instances.size()){
1674
+ return &scene.objects[scene.instances[id].object];
1675
+ }
1676
+ if constexpr (SPEC::ENABLE_OVERLAYS){
1677
+ const size_t relative = id - scene.instances.size();
1678
+ const size_t overlay = relative / SPEC::MAX_OVERLAY_INSTANCES;
1679
+ const size_t slot = relative % SPEC::MAX_OVERLAY_INSTANCES;
1680
+ if(overlay >= SPEC::NUM_OVERLAYS){
1681
+ return nullptr;
1682
+ }
1683
+ size_t object = renderer.overlays[overlay].slots[slot].object;
1684
+ if(object < scene.objects.size()){
1685
+ return &scene.objects[object];
1686
+ }
1687
+ object -= scene.objects.size();
1688
+ for(const auto& assembly : pool.assemblies){
1689
+ if(object < assembly.objects.size()){
1690
+ return &assembly.objects[object];
1691
+ }
1692
+ object -= assembly.objects.size();
1693
+ }
1694
+ }
1695
+ return nullptr;
1696
+ }
1697
+
1698
+ inline void make_transform(const float position[3], const float orientation_wxyz[4], float out[12]){
1699
+ const float w = orientation_wxyz[0], x = orientation_wxyz[1], y = orientation_wxyz[2], z = orientation_wxyz[3];
1700
+ out[0] = 1 - 2*(y*y + z*z); out[1] = 2*(x*y - w*z); out[2] = 2*(x*z + w*y); out[3] = position[0];
1701
+ out[4] = 2*(x*y + w*z); out[5] = 1 - 2*(x*x + z*z); out[6] = 2*(y*z - w*x); out[7] = position[1];
1702
+ out[8] = 2*(x*z - w*y); out[9] = 2*(y*z + w*x); out[10] = 1 - 2*(x*x + y*y); out[11] = position[2];
1703
+ }
1704
+
1705
+ inline void compose_transforms(const float a[12], const float b[12], float out[12]){
1706
+ rendering::raytracing::detail::compose_transforms(a, b, out);
1707
+ }
1708
+
1709
+ template <typename T>
1710
+ RL_TOOLS_FUNCTION_PLACEMENT rendering::raytracing::Camera<T> make_camera_data(const T position[3], const T look_at[3], const T up[3], T fov, T aspect){
1711
+ namespace v3 = rendering::raytracing::vec3;
1712
+ T raw_dir[3], dir[3];
1713
+ v3::sub(look_at, position, raw_dir);
1714
+ v3::normalize(raw_dir, dir);
1715
+
1716
+ T image_plane_scale = T{2} * tanf(fov / T{2});
1717
+
1718
+ T du_dir[3], du[3];
1719
+ v3::cross_normalized(dir, up, du_dir);
1720
+ v3::scale(du_dir, image_plane_scale, du);
1721
+
1722
+ T dv_dir[3], dv[3];
1723
+ v3::cross_normalized(du, dir, dv_dir);
1724
+ v3::scale(dv_dir, image_plane_scale / aspect, dv);
1725
+
1726
+ T half_du[3], half_dv[3], tmp[3];
1727
+ v3::scale(du, T{-0.5}, half_du);
1728
+ v3::scale(dv, T{0.5}, half_dv);
1729
+ v3::add(dir, half_du, tmp);
1730
+ rendering::raytracing::Camera<T> cam;
1731
+ v3::add(tmp, half_dv, cam.dir_00);
1732
+ cam.pos[0] = position[0]; cam.pos[1] = position[1]; cam.pos[2] = position[2];
1733
+ cam.dir_du[0] = du[0]; cam.dir_du[1] = du[1]; cam.dir_du[2] = du[2];
1734
+ v3::scale(dv, T{-1}, cam.dir_dv);
1735
+ return cam;
1736
+ }
1737
+
1738
+ namespace rendering::raytracing::detail{
1739
+ // fills a host staging buffer; the backend-specific generate_cameras writes it into the
1740
+ // backend-native camera tensors
1741
+ template <typename SPEC, typename DEVICE>
1742
+ void generate_camera_poses(DEVICE& device, rendering::raytracing::Camera<typename SPEC::T>* cameras_out,
1743
+ const typename SPEC::T center[3], typename SPEC::T radius,
1744
+ const typename SPEC::T up[3], typename SPEC::T fov){
1745
+ using T = typename SPEC::T;
1746
+ using TI = typename SPEC::TI;
1747
+
1748
+ const T golden_ratio = (T{1} + sqrtf(T{5})) / T{2};
1749
+ const T aspect = (T)SPEC::CAM_WIDTH / (T)SPEC::CAM_HEIGHT;
1750
+
1751
+ for(TI i = 0; i < SPEC::NUM_CAMERAS; i++){
1752
+ T theta = T{2} * (T)M_PI * i / golden_ratio;
1753
+ T cos_inc = T{1} - T{2} * (i + T{0.5}) / SPEC::NUM_CAMERAS;
1754
+ cos_inc = cos_inc * T{0.85};
1755
+ T sin_inc = sqrtf(T{1} - cos_inc * cos_inc);
1756
+
1757
+ T cam_pos[3] = {
1758
+ center[0] + radius * sin_inc * cosf(theta),
1759
+ center[1] + radius * sin_inc * sinf(theta),
1760
+ center[2] + radius * cos_inc
1761
+ };
1762
+
1763
+ if(cam_pos[2] < center[2] - radius * T{0.1})
1764
+ cam_pos[2] = center[2] + radius * T{0.3};
1765
+
1766
+ cameras_out[i] = make_camera_data(cam_pos, center, up, fov, aspect);
1767
+ }
1768
+
1769
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Generated " << SPEC::NUM_CAMERAS << " camera positions");
1770
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Per-camera resolution: " << SPEC::CAM_WIDTH << "x" << SPEC::CAM_HEIGHT);
1771
+ }
1772
+
1773
+ template <typename SPEC>
1774
+ std::vector<float> generate_probe_direction_vectors(){
1775
+ std::vector<float> dirs;
1776
+ dirs.reserve(SPEC::NUM_PROBES * 3);
1777
+
1778
+ const float golden_ratio = (1.0f + sqrtf(5.0f)) / 2.0f;
1779
+
1780
+ for(int i = 0; i < (int)SPEC::NUM_PROBES; i++){
1781
+ float theta = 2.0f * (float)M_PI * i / golden_ratio;
1782
+ float cos_inc = 1.0f - 2.0f * (i + 0.5f) / SPEC::NUM_PROBES;
1783
+ float sin_inc = sqrtf(1.0f - cos_inc * cos_inc);
1784
+
1785
+ const float dir[3] = {sin_inc * cosf(theta), sin_inc * sinf(theta), cos_inc};
1786
+ const float inv_len = 1.0f / sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
1787
+ dirs.push_back(dir[0] * inv_len);
1788
+ dirs.push_back(dir[1] * inv_len);
1789
+ dirs.push_back(dir[2] * inv_len);
1790
+ }
1791
+
1792
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Generated " << SPEC::NUM_PROBES << " probe directions per camera");
1793
+ return dirs;
1794
+ }
1795
+
1796
+ template <typename SPEC>
1797
+ void write_grid_png(const uint32_t* fb, const char* filename){
1798
+ using TI = typename SPEC::TI;
1799
+ constexpr TI cam_pixels = SPEC::CAM_PIXELS;
1800
+ constexpr int grid_width = SPEC::GRID_COLS * SPEC::CAM_WIDTH;
1801
+ constexpr int grid_height = SPEC::GRID_ROWS * SPEC::CAM_HEIGHT;
1802
+ std::vector<uint32_t> grid_image(grid_width * grid_height, 0);
1803
+
1804
+ for(int i = 0; i < (int)SPEC::NUM_CAMERAS; i++){
1805
+ int col = i % SPEC::GRID_COLS;
1806
+ int row = i / SPEC::GRID_COLS;
1807
+ int offset_x = col * SPEC::CAM_WIDTH;
1808
+ int offset_y = row * SPEC::CAM_HEIGHT;
1809
+
1810
+ for(int y = 0; y < (int)SPEC::CAM_HEIGHT; y++){
1811
+ memcpy(&grid_image[(offset_y + y) * grid_width + offset_x],
1812
+ &fb[i * cam_pixels + y * SPEC::CAM_WIDTH],
1813
+ SPEC::CAM_WIDTH * sizeof(uint32_t));
1814
+ }
1815
+ }
1816
+
1817
+ stbi_write_png(filename, grid_width, grid_height, 4,
1818
+ grid_image.data(), grid_width * sizeof(uint32_t));
1819
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Written grid image (" << SPEC::GRID_COLS << "x" << SPEC::GRID_ROWS
1820
+ << " cameras, " << grid_width << "x" << grid_height << " px) to " << filename);
1821
+ }
1822
+
1823
+ // one distinct color per instance id (golden-ratio hue hash); miss sentinel renders black
1824
+ inline uint32_t segmentation_id_to_rgba(uint32_t id){
1825
+ if(id == 0xFFFFFFFFu){
1826
+ return 0xFF000000u;
1827
+ }
1828
+ const float hue = std::fmod((float)id * 0.61803398875f, 1.0f) * 6.0f;
1829
+ const float descending = 1.0f - std::fabs(std::fmod(hue, 2.0f) - 1.0f);
1830
+ float r = 0, g = 0, b = 0;
1831
+ switch((int)hue){
1832
+ case 0: r = 1; g = descending; break;
1833
+ case 1: r = descending; g = 1; break;
1834
+ case 2: g = 1; b = descending; break;
1835
+ case 3: g = descending; b = 1; break;
1836
+ case 4: r = descending; b = 1; break;
1837
+ default: r = 1; b = descending; break;
1838
+ }
1839
+ return 0xFF000000u | ((uint32_t)(b * 255) << 16) | ((uint32_t)(g * 255) << 8) | (uint32_t)(r * 255);
1840
+ }
1841
+ template <typename SPEC>
1842
+ void write_segmentation_grid_png(const uint32_t* segmentation, const char* filename){
1843
+ constexpr typename SPEC::TI num_pixels = SPEC::NUM_CAMERAS * SPEC::CAM_PIXELS;
1844
+ std::vector<uint32_t> colored(num_pixels);
1845
+ for(size_t pixel_i = 0; pixel_i < (size_t)num_pixels; pixel_i++){
1846
+ colored[pixel_i] = segmentation_id_to_rgba(segmentation[pixel_i]);
1847
+ }
1848
+ write_grid_png<SPEC>(colored.data(), filename);
1849
+ }
1850
+
1851
+ // pinned normals encoding, the single owner shared by save verbs and the golden corpus:
1852
+ // each component maps through round((clamp(n, -1, 1) * 0.5 + 0.5) * 255). The miss value
1853
+ // (0,0,0) encodes to (128,128,128), which no unit normal can reach (a unit vector has a
1854
+ // component of magnitude >= 1/sqrt(3)).
1855
+ inline uint32_t normal_to_rgba(const float normal[3]){
1856
+ uint32_t rgba = 0xFF000000u;
1857
+ for(int component = 0; component < 3; component++){
1858
+ const float clamped = fminf(fmaxf(normal[component], -1.f), 1.f);
1859
+ const uint32_t value = (uint32_t)lroundf((clamped * 0.5f + 0.5f) * 255.f);
1860
+ rgba |= value << (8 * component);
1861
+ }
1862
+ return rgba;
1863
+ }
1864
+ template <typename SPEC>
1865
+ void write_normals_grid_png(const float* normals_host, const char* filename){
1866
+ constexpr typename SPEC::TI num_pixels = SPEC::NUM_CAMERAS * SPEC::CAM_PIXELS;
1867
+ std::vector<uint32_t> colored(num_pixels);
1868
+ for(size_t pixel_i = 0; pixel_i < (size_t)num_pixels; pixel_i++){
1869
+ colored[pixel_i] = normal_to_rgba(&normals_host[pixel_i * 3]);
1870
+ }
1871
+ write_grid_png<SPEC>(colored.data(), filename);
1872
+ }
1873
+
1874
+ template <typename SPEC>
1875
+ void write_depth_grid_png(const float* depth_host, float camera_radius, const char* filename){
1876
+ using TI = typename SPEC::TI;
1877
+ constexpr TI cam_pixels = SPEC::CAM_PIXELS;
1878
+ constexpr int grid_width = SPEC::GRID_COLS * SPEC::CAM_WIDTH;
1879
+ constexpr int grid_height = SPEC::GRID_ROWS * SPEC::CAM_HEIGHT;
1880
+ std::vector<uint32_t> grid_image(grid_width * grid_height, 0);
1881
+ constexpr size_t depth_count = (size_t)SPEC::NUM_CAMERAS * SPEC::CAM_PIXELS;
1882
+ const float max_depth = camera_radius > 0 ? camera_radius * 2.0f : 1e30f;
1883
+ const float valid_max_depth = max_depth * 0.999f;
1884
+ float min_valid_depth = std::numeric_limits<float>::max();
1885
+ float max_valid_depth = std::numeric_limits<float>::lowest();
1886
+ for(size_t depth_i = 0; depth_i < depth_count; depth_i++){
1887
+ const float depth = depth_host[depth_i];
1888
+ // no std::isfinite: unreliable under -ffast-math; the range check excludes inf/NaN
1889
+ if(depth > 0.f && depth < valid_max_depth){
1890
+ min_valid_depth = std::min(min_valid_depth, depth);
1891
+ max_valid_depth = std::max(max_valid_depth, depth);
1892
+ }
1893
+ }
1894
+ const bool has_valid_depth = min_valid_depth <= max_valid_depth;
1895
+ const float valid_depth_range = has_valid_depth ? max_valid_depth - min_valid_depth : 0.f;
1896
+
1897
+ for(int i = 0; i < (int)SPEC::NUM_CAMERAS; i++){
1898
+ int col = i % SPEC::GRID_COLS;
1899
+ int row = i / SPEC::GRID_COLS;
1900
+ int offset_x = col * SPEC::CAM_WIDTH;
1901
+ int offset_y = row * SPEC::CAM_HEIGHT;
1902
+
1903
+ for(int y = 0; y < (int)SPEC::CAM_HEIGHT; y++){
1904
+ for(int x = 0; x < (int)SPEC::CAM_WIDTH; x++){
1905
+ const float depth = depth_host[i * cam_pixels + y * SPEC::CAM_WIDTH + x];
1906
+ uint8_t value = 0;
1907
+ if(has_valid_depth && depth > 0.f && depth < valid_max_depth){
1908
+ const float normalized = fminf(fmaxf((depth - min_valid_depth) / (valid_depth_range + 1e-6f), 0.f), 1.f);
1909
+ value = static_cast<uint8_t>(normalized * 255.f);
1910
+ }
1911
+ grid_image[(offset_y + y) * grid_width + offset_x + x] =
1912
+ (0xFFu << 24) | (uint32_t(value) << 16) | (uint32_t(value) << 8) | uint32_t(value);
1913
+ }
1914
+ }
1915
+ }
1916
+
1917
+ stbi_write_png(filename, grid_width, grid_height, 4,
1918
+ grid_image.data(), grid_width * sizeof(uint32_t));
1919
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Written depth image (" << SPEC::GRID_COLS << "x" << SPEC::GRID_ROWS
1920
+ << " cameras, " << grid_width << "x" << grid_height << " px) to " << filename);
1921
+ }
1922
+
1923
+ template <typename SPEC>
1924
+ void write_depth_bin(const float* depth_host, const char* filename){
1925
+ constexpr size_t depth_count = (size_t)SPEC::NUM_CAMERAS * SPEC::CAM_PIXELS;
1926
+ FILE* f = fopen(filename, "wb");
1927
+ if(f){
1928
+ int nc = SPEC::NUM_CAMERAS;
1929
+ int h = SPEC::CAM_HEIGHT;
1930
+ int w = SPEC::CAM_WIDTH;
1931
+ fwrite(&nc, sizeof(int), 1, f);
1932
+ fwrite(&h, sizeof(int), 1, f);
1933
+ fwrite(&w, sizeof(int), 1, f);
1934
+ fwrite(depth_host, sizeof(float), depth_count, f);
1935
+ fclose(f);
1936
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Written depth data (" << depth_count << " values) to " << filename);
1937
+ }
1938
+ }
1939
+
1940
+ template <typename SPEC>
1941
+ void write_probes_bin_and_log(const CollisionResult* probe_results, const char* filename){
1942
+ int total_hits = 0;
1943
+ float min_hit_dist = 1e30f, max_hit_dist = 0.f;
1944
+ double sum_hit_dist = 0.0;
1945
+ for(int i = 0; i < (int)(SPEC::NUM_CAMERAS * SPEC::NUM_PROBES); i++){
1946
+ if(probe_results[i].hit){
1947
+ total_hits++;
1948
+ sum_hit_dist += probe_results[i].distance;
1949
+ if(probe_results[i].distance < min_hit_dist)
1950
+ min_hit_dist = probe_results[i].distance;
1951
+ if(probe_results[i].distance > max_hit_dist)
1952
+ max_hit_dist = probe_results[i].distance;
1953
+ }
1954
+ }
1955
+
1956
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("=== COLLISION PROBE RESULTS ===");
1957
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" Total probes: " << SPEC::NUM_CAMERAS * SPEC::NUM_PROBES);
1958
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" Hits: " << total_hits
1959
+ << " (" << (100.0 * total_hits / (SPEC::NUM_CAMERAS * SPEC::NUM_PROBES)) << "%)");
1960
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" Misses: " << (SPEC::NUM_CAMERAS * SPEC::NUM_PROBES - total_hits));
1961
+ if(total_hits > 0){
1962
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" Min hit dist: " << min_hit_dist);
1963
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" Max hit dist: " << max_hit_dist);
1964
+ RL_TOOLS_RENDERING_RAYTRACING_LOG(" Avg hit dist: " << (sum_hit_dist / total_hits));
1965
+ }
1966
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("===============================");
1967
+
1968
+ {
1969
+ FILE* f = fopen(filename, "wb");
1970
+ if(f){
1971
+ int nc = SPEC::NUM_CAMERAS, np = SPEC::NUM_PROBES;
1972
+ fwrite(&nc, sizeof(int), 1, f);
1973
+ fwrite(&np, sizeof(int), 1, f);
1974
+ fwrite(probe_results, sizeof(CollisionResult),
1975
+ (size_t)SPEC::NUM_CAMERAS * SPEC::NUM_PROBES, f);
1976
+ fclose(f);
1977
+ RL_TOOLS_RENDERING_RAYTRACING_LOG("Written probe data (" << SPEC::NUM_CAMERAS * SPEC::NUM_PROBES
1978
+ << " results) to " << filename);
1979
+ }
1980
+ }
1981
+ }
1982
+ }
1983
+ }
1984
+ RL_TOOLS_NAMESPACE_WRAPPER_END
1985
+
1986
+ #endif