ernie-renderer 0.2.0.dev21__tar.gz → 0.2.0.dev30__tar.gz

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

Potentially problematic release.


This version of ernie-renderer might be problematic. Click here for more details.

Files changed (259) hide show
  1. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/CMakeLists.txt +1 -1
  2. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/PKG-INFO +1 -1
  3. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/benchmarks/CMakeLists.txt +1 -1
  4. ernie_renderer-0.2.0.dev30/benchmarks/scene/extents.cpp +40 -0
  5. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/nanovdb.cpp +25 -9
  6. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/nanovdb.h +8 -0
  7. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/CMakeLists.txt +8 -0
  8. ernie_renderer-0.2.0.dev30/ernie/scene/extent_cache.cpp +89 -0
  9. ernie_renderer-0.2.0.dev30/ernie/scene/extent_cache.h +43 -0
  10. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/scene.cpp +124 -29
  11. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/scene.h +43 -5
  12. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/schema.cpp +74 -4
  13. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/schema.h +56 -2
  14. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/camera.cpp +11 -0
  15. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/camera.h +63 -0
  16. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/collection.cpp +11 -0
  17. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/collection.h +46 -0
  18. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/geom.cpp +1 -1
  19. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/schemas/geom.h +9 -0
  20. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/instancer.cpp +93 -0
  21. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/instancer.h +63 -0
  22. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/lux.cpp +72 -0
  23. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/lux.h +186 -0
  24. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/mesh.cpp +67 -0
  25. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/mesh.h +87 -0
  26. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/registry.cpp +57 -0
  27. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/shade.cpp +12 -0
  28. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/shade.h +27 -0
  29. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/vol.cpp +126 -0
  30. ernie_renderer-0.2.0.dev30/ernie/scene/schemas/vol.h +95 -0
  31. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/storage.cpp +25 -6
  32. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/storage.h +6 -0
  33. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/tokens.h +9 -0
  34. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/view.cpp +21 -5
  35. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/view.h +77 -14
  36. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/bytes.h +26 -0
  37. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/CMakeLists.txt +6 -0
  38. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/common.h +21 -1
  39. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/io/nanovdb_test.cpp +9 -0
  40. ernie_renderer-0.2.0.dev30/tests/scene/api_test.cpp +91 -0
  41. ernie_renderer-0.2.0.dev30/tests/scene/extent_cache_test.cpp +81 -0
  42. ernie_renderer-0.2.0.dev30/tests/scene/instancer_test.cpp +69 -0
  43. ernie_renderer-0.2.0.dev30/tests/scene/lux_test.cpp +75 -0
  44. ernie_renderer-0.2.0.dev30/tests/scene/mesh_test.cpp +75 -0
  45. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/scene/scene_test.cpp +19 -0
  46. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/scene/schema_test.cpp +3 -4
  47. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/scene/storage_test.cpp +20 -0
  48. ernie_renderer-0.2.0.dev30/tests/scene/vol_test.cpp +83 -0
  49. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/bytes_test.cpp +17 -0
  50. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/worker_pool_test.cpp +10 -1
  51. ernie_renderer-0.2.0.dev21/ernie/scene/schemas/registry.cpp +0 -18
  52. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.clang-format +0 -0
  53. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.clang-tidy +0 -0
  54. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.dockerignore +0 -0
  55. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.gersemirc +0 -0
  56. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.gitattributes +0 -0
  57. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.github/scripts/coverage_badge.py +0 -0
  58. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.github/scripts/install-lavapipe-windows.sh +0 -0
  59. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.github/workflows/ci.yml +0 -0
  60. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.gitignore +0 -0
  61. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/.pre-commit-config.yaml +0 -0
  62. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/CMakePresets.json +0 -0
  63. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/Dockerfile +0 -0
  64. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/LICENSE +0 -0
  65. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/README.md +0 -0
  66. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/benchmarks/bench.h +0 -0
  67. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/benchmarks/main.cpp +0 -0
  68. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/benchmarks/scene/storage.cpp +0 -0
  69. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/ErnieConfig.cmake.in +0 -0
  70. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/ErnieFetch.cmake +0 -0
  71. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/ErnieInstall.cmake +0 -0
  72. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/ErniePackaging.cmake +0 -0
  73. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/ErnieTesting.cmake +0 -0
  74. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/ernie.pc.in +0 -0
  75. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/bc7enc.cmake +0 -0
  76. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/dlpack.cmake +0 -0
  77. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/glm.cmake +0 -0
  78. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/googletest.cmake +0 -0
  79. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/json.cmake +0 -0
  80. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/nanobind.cmake +0 -0
  81. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/openexr.cmake +0 -0
  82. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/stb.cmake +0 -0
  83. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/tracy.cmake +0 -0
  84. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/volk.cmake +0 -0
  85. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/cmake/third_party/vulkan_headers.cmake +0 -0
  86. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/docs/README.md +0 -0
  87. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/docs/index.md +0 -0
  88. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/docs/requirements.txt +0 -0
  89. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/CMakeLists.txt +0 -0
  90. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/app/CMakeLists.txt +0 -0
  91. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/app/main.cpp +0 -0
  92. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/device/CMakeLists.txt +0 -0
  93. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/device/vulkan_devices.cpp +0 -0
  94. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/device/vulkan_devices.h +0 -0
  95. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/geometry/CMakeLists.txt +0 -0
  96. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/geometry/bounds.h +0 -0
  97. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/graph/CMakeLists.txt +0 -0
  98. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/CMakeLists.txt +0 -0
  99. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/ies.cpp +0 -0
  100. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/ies.h +0 -0
  101. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/image.cpp +0 -0
  102. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/image.h +0 -0
  103. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/raster.cpp +0 -0
  104. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/raster.h +0 -0
  105. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/texture.cpp +0 -0
  106. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/io/texture.h +0 -0
  107. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/CMakeLists.txt +0 -0
  108. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/astronomy.cpp +0 -0
  109. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/astronomy.h +0 -0
  110. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/atmosphere.cpp +0 -0
  111. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/atmosphere.h +0 -0
  112. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/cloud.cpp +0 -0
  113. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/cloud.h +0 -0
  114. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/constants.h +0 -0
  115. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_library.cpp +0 -0
  116. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_library.h +0 -0
  117. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/reflectance_table.h +0 -0
  118. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/regolith.cpp +0 -0
  119. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/regolith.h +0 -0
  120. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/scattering.cpp +0 -0
  121. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/scattering.h +0 -0
  122. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar.cpp +0 -0
  123. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar.h +0 -0
  124. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/solar_table.h +0 -0
  125. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/spectrum.cpp +0 -0
  126. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/physics/spectrum.h +0 -0
  127. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/python/CMakeLists.txt +0 -0
  128. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/python/ernie/__init__.py +0 -0
  129. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/python/module.cpp +0 -0
  130. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/render/CMakeLists.txt +0 -0
  131. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/convert.h +0 -0
  132. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/path.cpp +0 -0
  133. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/path.h +0 -0
  134. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/value.h +0 -0
  135. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/xform.cpp +0 -0
  136. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/scene/xform.h +0 -0
  137. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/CMakeLists.txt +0 -0
  138. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/algorithm.h +0 -0
  139. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/disk_cache.cpp +0 -0
  140. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/disk_cache.h +0 -0
  141. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/file.cpp +0 -0
  142. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/file.h +0 -0
  143. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/glm.h +0 -0
  144. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/hash_index.h +0 -0
  145. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/linear_algebra.h +0 -0
  146. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/log.cpp +0 -0
  147. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/log.h +0 -0
  148. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/math.h +0 -0
  149. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/noise.cpp +0 -0
  150. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/noise.h +0 -0
  151. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/numbers.h +0 -0
  152. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/parallel.h +0 -0
  153. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/profiler.cpp +0 -0
  154. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/profiler.h +0 -0
  155. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/random.h +0 -0
  156. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/tensor.cpp +0 -0
  157. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/tensor.h +0 -0
  158. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/text.h +0 -0
  159. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/version.cpp +0 -0
  160. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/version.h +0 -0
  161. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/ernie/util/worker_pool.h +0 -0
  162. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/mkdocs.yml +0 -0
  163. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/pyproject.toml +0 -0
  164. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/consumer/CMakeLists.txt +0 -0
  165. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/consumer/main.cpp +0 -0
  166. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/device/vulkan_devices_test.cpp +0 -0
  167. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/README.md +0 -0
  168. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/make_exr.py +0 -0
  169. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
  170. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/rgba_half_window.exr +0 -0
  171. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/exr/y_half_zips.exr +0 -0
  172. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/README.md +0 -0
  173. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
  174. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
  175. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ies/lamp.tilt +0 -0
  176. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/images/grey16.png +0 -0
  177. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/README.md +0 -0
  178. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
  179. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
  180. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
  181. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
  182. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/README.md +0 -0
  183. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
  184. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/float_raw.tif +0 -0
  185. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
  186. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
  187. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
  188. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
  189. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
  190. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/volumes/cube.nvdb +0 -0
  191. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/fixtures/volumes/make_nvdb.py +0 -0
  192. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/geometry/bounds_test.cpp +0 -0
  193. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/io/ies_test.cpp +0 -0
  194. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/io/image_test.cpp +0 -0
  195. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/io/raster_test.cpp +0 -0
  196. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/io/texture_test.cpp +0 -0
  197. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/astronomy_test.cpp +0 -0
  198. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/atmosphere_test.cpp +0 -0
  199. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/cloud_test.cpp +0 -0
  200. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/reflectance_library_test.cpp +0 -0
  201. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/regolith_test.cpp +0 -0
  202. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/scattering_test.cpp +0 -0
  203. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/solar_test.cpp +0 -0
  204. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/physics/spectrum_test.cpp +0 -0
  205. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/python/test_package.py +0 -0
  206. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/scene/path_test.cpp +0 -0
  207. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/scene/xform_test.cpp +0 -0
  208. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/algorithm_test.cpp +0 -0
  209. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/disk_cache_test.cpp +0 -0
  210. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/file_test.cpp +0 -0
  211. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/hash_index_test.cpp +0 -0
  212. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/linear_algebra_test.cpp +0 -0
  213. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/log_test.cpp +0 -0
  214. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/math_test.cpp +0 -0
  215. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/noise_test.cpp +0 -0
  216. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/parallel_test.cpp +0 -0
  217. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/profiler_test.cpp +0 -0
  218. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/random_test.cpp +0 -0
  219. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/tensor_test.cpp +0 -0
  220. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/text_test.cpp +0 -0
  221. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/tests/util/version_test.cpp +0 -0
  222. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/CMakeLists.txt +0 -0
  223. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSE +0 -0
  224. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
  225. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
  226. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/LICENSES/MIT.txt +0 -0
  227. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/NOTICE +0 -0
  228. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/README.md +0 -0
  229. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu.h +0 -0
  230. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
  231. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
  232. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
  233. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_containers.h +0 -0
  234. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
  235. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
  236. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
  237. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
  238. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_idct.h +0 -0
  239. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
  240. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
  241. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
  242. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
  243. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
  244. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
  245. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
  246. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
  247. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
  248. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
  249. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
  250. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
  251. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
  252. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
  253. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
  254. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
  255. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/LICENSE +0 -0
  256. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/zstd.h +0 -0
  257. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/basisu/zstd/zstd_errors.h +0 -0
  258. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/nanovdb/LICENSE +0 -0
  259. {ernie_renderer-0.2.0.dev21 → ernie_renderer-0.2.0.dev30}/third_party/nanovdb/PNanoVDB.h +0 -0
@@ -15,7 +15,7 @@ project(
15
15
  )
16
16
 
17
17
  # Pre-release suffix such as .dev12, written by CI.
18
- set(ERNIE_VERSION_SUFFIX ".dev21" CACHE STRING "Pre-release suffix of Ernie's version")
18
+ set(ERNIE_VERSION_SUFFIX ".dev30" CACHE STRING "Pre-release suffix of Ernie's version")
19
19
  set(ERNIE_VERSION "${PROJECT_VERSION}${ERNIE_VERSION_SUFFIX}")
20
20
 
21
21
  option(ERNIE_BUILD_TESTS "Build Ernie's tests" OFF)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ernie-renderer
3
- Version: 0.2.0.dev21
3
+ Version: 0.2.0.dev30
4
4
  Summary: Efficient Renderer for Natural and Interplanetary Environments: a physically based, spectral Vulkan ray tracer
5
5
  Author: Alex Maietta
6
6
  License-Expression: BSD-3-Clause
@@ -1,3 +1,3 @@
1
1
  # SPDX-License-Identifier: BSD-3-Clause
2
- add_executable(ernie_benchmarks main.cpp scene/storage.cpp)
2
+ add_executable(ernie_benchmarks main.cpp scene/extents.cpp scene/storage.cpp)
3
3
  target_link_libraries(ernie_benchmarks PRIVATE ernie_static ernie_build_options)
@@ -0,0 +1,40 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ /// @file extents.cpp
3
+ /// @brief Cached extents at 100,000 prims: the first update, and one edit's.
4
+ #include "benchmarks/bench.h"
5
+ #include "ernie/scene/schemas/geom.h"
6
+
7
+ #include <memory>
8
+ #include <string>
9
+ #include <vector>
10
+
11
+ namespace ernie::bench {
12
+ namespace {
13
+
14
+ constexpr int kSpheres = 100'000;
15
+
16
+ std::unique_ptr<Scene> MakeSpheres() {
17
+ auto scene = std::make_unique<Scene>();
18
+ for (int i = 0; i < kSpheres; ++i) {
19
+ scene->Define("/World/Ball_" + std::to_string(i), "Sphere");
20
+ }
21
+ return scene;
22
+ }
23
+
24
+ const bool kFirstUpdate = Register("scene.extents.first_update_100k", [] {
25
+ std::unique_ptr<Scene> scene;
26
+ return Timing{Fastest([&] { scene = MakeSpheres(); }, [&] { scene->UpdateExtents(); }), 10.0};
27
+ });
28
+
29
+ const bool kOneEdit = Register("scene.extents.update_after_one_edit_of_100k", [] {
30
+ std::unique_ptr<Scene> scene = MakeSpheres();
31
+ scene->UpdateExtents();
32
+ const PrimId ball = *scene->Find("/World/Ball_54321");
33
+ double radius = 1.0;
34
+ const double ms = Fastest([&] { scene->Set(ball, Sphere::kRadius, radius += 1.0); },
35
+ [&] { scene->UpdateExtents(); });
36
+ return Timing{ms, 1.0};
37
+ });
38
+
39
+ } // namespace
40
+ } // namespace ernie::bench
@@ -173,9 +173,8 @@ NanoVdbGrid ParseGrid(std::span<const std::uint8_t> bytes) {
173
173
  return grid;
174
174
  }
175
175
 
176
- // The grids of a raw buffer: each GridData header gives its grid's
177
- // size.
178
- std::vector<NanoVdbGrid> RawGrids(std::span<const std::uint8_t> bytes) {
176
+ // The grids of a raw buffer, or only their headers: each GridData header gives its grid's size.
177
+ std::vector<NanoVdbGrid> RawGrids(std::span<const std::uint8_t> bytes, bool headsOnly = false) {
179
178
  std::vector<NanoVdbGrid> grids;
180
179
  std::size_t offset = 0;
181
180
  while (offset + PNANOVDB_GRID_SIZE <= bytes.size()) {
@@ -189,7 +188,11 @@ std::vector<NanoVdbGrid> RawGrids(std::span<const std::uint8_t> bytes) {
189
188
  if (size < PNANOVDB_GRID_SIZE || offset + size > bytes.size()) {
190
189
  throw std::runtime_error("NanoVDB grid size runs past its data");
191
190
  }
192
- grids.push_back(ParseGrid(bytes.subspan(offset, size)));
191
+ const std::span<const std::uint8_t> grid =
192
+ bytes.subspan(offset, static_cast<std::size_t>(size));
193
+ grids.push_back(headsOnly ? NanoVdbGridHead(grid.first(std::min(
194
+ static_cast<std::size_t>(size), kNanoVdbHeadBytes)))
195
+ : ParseGrid(grid));
193
196
  offset += size;
194
197
  }
195
198
  if (grids.empty()) {
@@ -234,6 +237,10 @@ std::vector<NanoVdbGrid> ParseNanoVdbGrids(std::span<const std::uint8_t> bytes)
234
237
  return RawGrids(bytes);
235
238
  }
236
239
 
240
+ std::vector<NanoVdbGrid> ParseNanoVdbHeads(std::span<const std::uint8_t> bytes) {
241
+ return RawGrids(bytes, true);
242
+ }
243
+
237
244
  NanoVdbGrid NanoVdbGridHead(std::span<const std::uint8_t> head) {
238
245
  const auto magic = ReadLittleEndian<std::uint64_t>(head, 0);
239
246
  if (magic != kMagicNumber && magic != kMagicGrid) {
@@ -247,8 +254,9 @@ NanoVdbGrid NanoVdbGridHead(std::span<const std::uint8_t> head) {
247
254
  return grid;
248
255
  }
249
256
 
250
- std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
251
- // Grids are copied out of the mapping into buffers aligned for PNanoVDB.
257
+ static std::vector<NanoVdbGrid> ReadGrids(const std::filesystem::path& path, bool headsOnly) {
258
+ // Grids are copied out of the mapping into buffers aligned for PNanoVDB; heads touch only the
259
+ // pages holding them.
252
260
  const MappedFile file(path);
253
261
  const std::span<const std::uint8_t> data(
254
262
  reinterpret_cast<const std::uint8_t*>(file.Bytes().data()), file.Bytes().size());
@@ -256,7 +264,7 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
256
264
  try {
257
265
  const auto magic = ReadLittleEndian<std::uint64_t>(data, 0);
258
266
  if (magic == kMagicGrid) {
259
- return RawGrids(data);
267
+ return RawGrids(data, headsOnly);
260
268
  }
261
269
  if (magic != kMagicNumber && magic != kMagicFile) {
262
270
  throw std::runtime_error("not a NanoVDB file");
@@ -267,7 +275,7 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
267
275
  if (MajorVersion(ReadLittleEndian<std::uint32_t>(data, 8)) != kMajorVersion &&
268
276
  MajorVersion(ReadLittleEndian<std::uint32_t>(data, PNANOVDB_GRID_OFF_VERSION)) ==
269
277
  kMajorVersion) {
270
- return RawGrids(data);
278
+ return RawGrids(data, headsOnly);
271
279
  }
272
280
  std::vector<NanoVdbGrid> grids;
273
281
  std::size_t offset = 0;
@@ -296,7 +304,7 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
296
304
  if (offset + size > data.size()) {
297
305
  throw std::runtime_error("grid runs past the file's end");
298
306
  }
299
- std::vector<NanoVdbGrid> one = RawGrids(data.subspan(offset, size));
307
+ std::vector<NanoVdbGrid> one = RawGrids(data.subspan(offset, size), headsOnly);
300
308
  grids.insert(grids.end(), std::make_move_iterator(one.begin()),
301
309
  std::make_move_iterator(one.end()));
302
310
  offset += size;
@@ -315,6 +323,14 @@ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
315
323
  }
316
324
  }
317
325
 
326
+ std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path) {
327
+ return ReadGrids(path, false);
328
+ }
329
+
330
+ std::vector<NanoVdbGrid> ReadNanoVdbHeads(const std::filesystem::path& path) {
331
+ return ReadGrids(path, true);
332
+ }
333
+
318
334
  const NanoVdbGrid* FindNanoVdbGrid(std::span<const NanoVdbGrid> grids, std::string_view name,
319
335
  int index) {
320
336
  // An index into the caller's grids, which cppcheck follows where
@@ -95,12 +95,20 @@ struct NanoVdbGrid {
95
95
  /// `nanovdb_convert` without `-z`/`-b`).
96
96
  std::vector<NanoVdbGrid> ReadNanoVdb(const std::filesystem::path& path);
97
97
 
98
+ /// @brief Reads the headers of a NanoVDB file's grids (names, types, bounds and transforms)
99
+ /// without their voxels, as `NanoVdbGridHead` does for each grid.
100
+ /// @throws std::runtime_error As `ReadNanoVdb`.
101
+ std::vector<NanoVdbGrid> ReadNanoVdbHeads(const std::filesystem::path& path);
102
+
98
103
  /// @brief Splits a raw in-memory NanoVDB buffer into its grids.
99
104
  /// @param bytes Grids back to back, as Warp's `Volume.array()`.
100
105
  /// @return The grids.
101
106
  /// @throws std::runtime_error If it does not start with a version 32
102
107
  /// NanoVDB grid.
103
108
  std::vector<NanoVdbGrid> ParseNanoVdbGrids(std::span<const std::uint8_t> bytes);
109
+ /// @brief Reads the headers of a raw buffer's grids, without copying their voxels.
110
+ /// @throws std::runtime_error As `ParseNanoVdbGrids`.
111
+ std::vector<NanoVdbGrid> ParseNanoVdbHeads(std::span<const std::uint8_t> bytes);
104
112
 
105
113
  /// Bytes at a grid's start holding its header, tree and root, root
106
114
  /// statistics included.
@@ -2,13 +2,21 @@
2
2
  add_library(
3
3
  ernie_scene
4
4
  OBJECT
5
+ extent_cache.cpp
5
6
  path.cpp
6
7
  schema.cpp
7
8
  scene.cpp
8
9
  storage.cpp
9
10
  view.cpp
10
11
  xform.cpp
12
+ schemas/camera.cpp
13
+ schemas/collection.cpp
11
14
  schemas/geom.cpp
15
+ schemas/instancer.cpp
16
+ schemas/lux.cpp
17
+ schemas/mesh.cpp
12
18
  schemas/registry.cpp
19
+ schemas/shade.cpp
20
+ schemas/vol.cpp
13
21
  )
14
22
  target_link_libraries(ernie_scene PUBLIC ernie_physics ernie_io PRIVATE ernie_build_options)
@@ -0,0 +1,89 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ /// @file extent_cache.cpp
3
+ /// @brief Replaying row changes into the extent boxes and recomputing stale runs.
4
+ #include "ernie/scene/extent_cache.h"
5
+
6
+ #include <algorithm>
7
+
8
+ namespace ernie {
9
+
10
+ void ExtentCache::Track(BucketId bucket, ExtentFunction compute) {
11
+ buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
12
+ buckets_[bucket].compute = compute;
13
+ }
14
+
15
+ void ExtentCache::Update(const PrimStore& store) {
16
+ const ChangeSet changes = store.ChangesSince(cursor_);
17
+ const auto tracked = [&](BucketId bucket) {
18
+ return bucket < buckets_.size() && buckets_[bucket].compute != nullptr;
19
+ };
20
+ for (const BucketId bucket : changes.resets) {
21
+ if (tracked(bucket)) {
22
+ Resize(buckets_[bucket], 0);
23
+ }
24
+ }
25
+ for (const ChangeSet::Rows& rows : changes.rows) {
26
+ if (tracked(rows.bucket)) {
27
+ Replay(buckets_[rows.bucket], rows.change);
28
+ }
29
+ }
30
+ for (const ChangeSet::Values& values : changes.values) {
31
+ if (tracked(values.bucket)) {
32
+ for (const RowRange range : values.rows) {
33
+ buckets_[values.bucket].stale.SetRange(range.begin, range.end);
34
+ }
35
+ }
36
+ }
37
+ for (BucketId bucket = 0; bucket < buckets_.size(); ++bucket) {
38
+ if (tracked(bucket) && store.GetBucket(bucket).version > cursor_) {
39
+ Refresh(buckets_[bucket], store, bucket);
40
+ }
41
+ }
42
+ cursor_ = changes.version;
43
+ }
44
+
45
+ std::optional<Box> ExtentCache::Find(const PrimStore& store, BucketId bucket,
46
+ std::uint32_t row) const {
47
+ if (bucket >= buckets_.size() || buckets_[bucket].compute == nullptr ||
48
+ store.GetBucket(bucket).version > cursor_ || row >= buckets_[bucket].boxes.size()) {
49
+ return std::nullopt;
50
+ }
51
+ return buckets_[bucket].boxes[row];
52
+ }
53
+
54
+ void ExtentCache::Replay(Entry& entry, const StructuralChange& change) {
55
+ using Kind = StructuralChange::Kind;
56
+ if (change.kind == Kind::Added) {
57
+ Resize(entry, change.row + change.count);
58
+ entry.stale.SetRange(change.row, change.row + change.count);
59
+ } else if (change.kind == Kind::Moved) {
60
+ // Recomputed, not copied: the moved row's own value edits are reported at its old place.
61
+ entry.stale.Set(change.row);
62
+ Resize(entry, change.from);
63
+ } else if (change.row + 1 == entry.boxes.size()) {
64
+ // Removing the last row moves nothing; otherwise the Moved that follows shrinks it.
65
+ Resize(entry, change.row);
66
+ }
67
+ }
68
+
69
+ void ExtentCache::Resize(Entry& entry, std::uint32_t rows) {
70
+ entry.boxes.resize(rows);
71
+ entry.stale.Resize(rows);
72
+ }
73
+
74
+ void ExtentCache::Refresh(Entry& entry, const PrimStore& store, BucketId bucket) {
75
+ const std::uint32_t rows = store.GetBucket(bucket).Rows();
76
+ if (entry.boxes.size() != rows) {
77
+ // Too far behind to replay (a reset): recompute the bucket whole.
78
+ Resize(entry, rows);
79
+ entry.stale.SetRange(0, rows);
80
+ }
81
+ const ExtentRows columns{store, bucket};
82
+ entry.stale.ForEachRun([&](std::size_t begin, std::size_t end) {
83
+ entry.compute(columns, {static_cast<std::uint32_t>(begin), static_cast<std::uint32_t>(end)},
84
+ std::span(entry.boxes).subspan(begin, end - begin));
85
+ });
86
+ entry.stale.Clear();
87
+ }
88
+
89
+ } // namespace ernie
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: BSD-3-Clause
2
+ /// @file extent_cache.h
3
+ /// @brief Prims' extents kept per bucket and refreshed for the rows that changed.
4
+ #pragma once
5
+
6
+ #include "ernie/geometry/bounds.h"
7
+ #include "ernie/scene/schema.h"
8
+ #include "ernie/scene/storage.h"
9
+ #include "ernie/util/bytes.h"
10
+
11
+ #include <cstdint>
12
+ #include <optional>
13
+ #include <vector>
14
+
15
+ namespace ernie {
16
+
17
+ /// @brief The extents of every bucket with an extent function, a box per row. `Update` replays
18
+ /// the buckets' row changes and recomputes only the rows whose values or places changed.
19
+ class ExtentCache {
20
+ public:
21
+ /// Tracks a bucket, computing its extents with `compute`; null for a bucket without them.
22
+ void Track(BucketId bucket, ExtentFunction compute);
23
+ /// Brings every tracked bucket up to the store's version.
24
+ void Update(const PrimStore& store);
25
+ /// @return A row's extent, or none when its bucket changed since `Update` or has none.
26
+ std::optional<Box> Find(const PrimStore& store, BucketId bucket, std::uint32_t row) const;
27
+
28
+ private:
29
+ struct Entry {
30
+ ExtentFunction compute = nullptr;
31
+ std::vector<Box> boxes;
32
+ BitSet stale;
33
+ };
34
+
35
+ static void Replay(Entry& entry, const StructuralChange& change);
36
+ static void Resize(Entry& entry, std::uint32_t rows);
37
+ static void Refresh(Entry& entry, const PrimStore& store, BucketId bucket);
38
+
39
+ std::vector<Entry> buckets_;
40
+ std::uint64_t cursor_ = 0;
41
+ };
42
+
43
+ } // namespace ernie
@@ -7,6 +7,7 @@
7
7
  #include "ernie/scene/schemas/geom.h"
8
8
  #include "ernie/scene/tokens.h"
9
9
  #include "ernie/scene/xform.h"
10
+ #include "ernie/util/algorithm.h"
10
11
 
11
12
  #include <algorithm>
12
13
  #include <stdexcept>
@@ -15,9 +16,9 @@
15
16
  namespace ernie {
16
17
  namespace {
17
18
 
18
- /// @return A column layout holding `fallback` in unauthored rows.
19
- ColumnLayout MakeLayout(PathTable& paths, const AttributeDef& def) {
20
- const AttributeId attribute = paths.Names().Intern(def.name);
19
+ /// @return A column layout for the attribute `name` holding `def`'s fallback in unauthored rows.
20
+ ColumnLayout MakeLayout(PathTable& paths, const AttributeDef& def, std::string_view name) {
21
+ const AttributeId attribute = paths.Names().Intern(name);
21
22
  return WithColumnType(def.type, [&]<typename T>(std::type_identity<T>) {
22
23
  if constexpr (std::is_same_v<T, Tensor>) {
23
24
  return ColumnLayout::Of<T>(attribute);
@@ -38,7 +39,7 @@ std::string Describe(const Scene& scene, PrimId prim) {
38
39
  Scene::Scene()
39
40
  : invisible_(store_.Tokens().Intern(tokens::kInvisible)),
40
41
  defaultPurpose_(store_.Tokens().Intern(tokens::kDefault)) {
41
- BucketFor(nullptr);
42
+ FindOrAddBucket(nullptr, {});
42
43
  }
43
44
 
44
45
  PrimId Scene::Define(const Path& path, std::string_view type) {
@@ -57,12 +58,11 @@ PrimId Scene::Define(const Path& path, std::string_view type) {
57
58
  store_.Define(above, 0);
58
59
  }
59
60
  }
60
- const BucketId bucket = BucketFor(schema);
61
61
  if (const std::optional<PrimId> existing = store_.Find(id)) {
62
- store_.Move(*existing, bucket);
62
+ MoveTo(*existing, schema, Apis(*existing));
63
63
  return *existing;
64
64
  }
65
- return store_.Define(id, bucket);
65
+ return store_.Define(id, FindOrAddBucket(schema, {}));
66
66
  }
67
67
 
68
68
  bool Scene::Remove(const Path& path) {
@@ -136,9 +136,9 @@ std::vector<Path> Scene::Prims(std::string_view type) const {
136
136
 
137
137
  void Scene::Set(PrimId prim, std::string_view attribute, const Value& value) {
138
138
  const AttributeId token = store_.Tokens().Intern(attribute);
139
- const AttributeDef* def = Declared(prim, token);
139
+ const AttributeDef* def = Declared(store_.PrimBucket(prim), token);
140
140
  if (def != nullptr) {
141
- Validate(*def, value, PrimPath(prim));
141
+ Validate(*def, attribute, value, PrimPath(prim));
142
142
  }
143
143
  const ColumnType type = def != nullptr ? def->type : TypeForUndeclared(prim, attribute, value);
144
144
  WithColumnType(type, [&]<typename T>(std::type_identity<T>) {
@@ -155,6 +155,27 @@ void Scene::Set(const Path& path, std::string_view attribute, const Value& value
155
155
  Set(Require(path), attribute, value);
156
156
  }
157
157
 
158
+ void Scene::Write(PrimId prim, std::string_view attribute, Tensor array) {
159
+ const AttributeId token = store_.Tokens().Intern(attribute);
160
+ const AttributeDef* def = Declared(store_.PrimBucket(prim), token);
161
+ if (def == nullptr && !TakesUndeclared(prim, attribute)) {
162
+ throw std::invalid_argument(Describe(*this, prim) + " has no attribute '" +
163
+ std::string(attribute) + "'");
164
+ }
165
+ if (def != nullptr) {
166
+ ValidateArray(*def, attribute, array, PrimPath(prim));
167
+ }
168
+ store_.Set(prim, token, std::move(array));
169
+ }
170
+
171
+ const Tensor* Scene::Read(PrimId prim, std::string_view attribute) const {
172
+ const Column* column = AuthoredColumn(prim, attribute);
173
+ if (column == nullptr || column->values->Type() != ColumnType::Tensor) {
174
+ return nullptr;
175
+ }
176
+ return &store_.Read<Tensor>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
177
+ }
178
+
158
179
  std::optional<Value> Scene::Get(PrimId prim, std::string_view attribute) const {
159
180
  const Column* column = AuthoredColumn(prim, attribute);
160
181
  if (column == nullptr) {
@@ -216,9 +237,13 @@ std::optional<Box> Scene::Extent(PrimId prim) const {
216
237
  if (rule.kind != ExtentRule::Kind::Computed) {
217
238
  return std::nullopt;
218
239
  }
240
+ const BucketId bucket = store_.PrimBucket(prim);
219
241
  const std::uint32_t row = store_.PrimRow(prim);
242
+ if (const std::optional<Box> cached = extents_.Find(store_, bucket, row)) {
243
+ return cached;
244
+ }
220
245
  Box extent;
221
- rule.compute({store_, store_.PrimBucket(prim)}, {row, row + 1}, std::span(&extent, 1));
246
+ rule.compute({store_, bucket, this}, {row, row + 1}, std::span(&extent, 1));
222
247
  return extent;
223
248
  }
224
249
 
@@ -229,23 +254,31 @@ Box Scene::WorldBounds(const Path& path) const {
229
254
  const glm::dmat4 above =
230
255
  parent == kRootPath ? glm::dmat4(1.0) : WorldTransform(*store_.Find(parent));
231
256
  Box bounds;
232
- AddTo(bounds, id, above);
257
+ AddTo(bounds, id, above, true);
258
+ return bounds;
259
+ }
260
+
261
+ Box Scene::BoundsInParent(PrimId prim) const {
262
+ Box bounds;
263
+ AddTo(bounds, store_.PrimPath(prim), glm::dmat4(1.0), false);
233
264
  return bounds;
234
265
  }
235
266
 
236
- void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent) const {
267
+ void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visibleOnly) const {
237
268
  const PrimId prim = *store_.Find(path);
238
- if (LeavesOutOfBounds(prim)) {
269
+ if (visibleOnly && LeavesOutOfBounds(prim)) {
239
270
  return;
240
271
  }
241
272
  const glm::dmat4 local = LocalTransform(prim);
242
273
  const glm::dmat4 world = ResetsXformStack(*this, prim) ? local : parent * local;
274
+ // A prim with an extent bounds what it is made of, so its children aren't added again.
243
275
  if (const std::optional<Box> extent = Extent(prim)) {
244
276
  bounds.Extend(extent->Transformed(world));
277
+ return;
245
278
  }
246
279
  store_.Paths().ForEachChild(path, [&](PathId child) {
247
280
  if (store_.Find(child)) {
248
- AddTo(bounds, child, world);
281
+ AddTo(bounds, child, world, visibleOnly);
249
282
  }
250
283
  });
251
284
  }
@@ -258,26 +291,71 @@ PrimId Scene::Require(const Path& path) const {
258
291
  return *prim;
259
292
  }
260
293
 
261
- BucketId Scene::BucketFor(const SchemaDef* schema) {
262
- if (const auto found = bucketBySchema_.find(schema); found != bucketBySchema_.end()) {
263
- return found->second;
264
- }
294
+ BucketId Scene::FindOrAddBucket(const SchemaDef* schema, std::vector<Token> apis) {
265
295
  PathTable& paths = store_.Paths();
296
+ const BucketKey key{paths.Names().Intern(schema != nullptr ? schema->name : ""),
297
+ std::move(apis)};
298
+ if (const std::optional<BucketId> found = store_.FindBucket(key)) {
299
+ return *found;
300
+ }
266
301
  BucketSchema entry{schema, {}};
267
302
  std::vector<ColumnLayout> layout;
268
- for (const AttributeDef* def :
269
- schema != nullptr ? schema->AllAttributes() : std::vector<const AttributeDef*>{}) {
270
- layout.push_back(MakeLayout(paths, *def));
271
- entry.declared.emplace(layout.back().attribute, def);
303
+ const auto add = [&](const SchemaDef& declaring, const ApiName& api) {
304
+ for (const AttributeDef* def : declaring.AllAttributes()) {
305
+ layout.push_back(MakeLayout(paths, *def, api.Attribute(def->name)));
306
+ entry.declared.emplace(layout.back().attribute, def);
307
+ }
308
+ };
309
+ if (schema != nullptr) {
310
+ add(*schema, {});
311
+ }
312
+ for (const Token token : key.apiSchemas) {
313
+ const ApiName api = ApiName::Parse(paths.Names().Text(token));
314
+ add(*api.schema, api);
272
315
  }
273
- const Token type = paths.Names().Intern(schema != nullptr ? schema->name : "");
274
- const BucketId bucket = store_.AddBucket({type, {}}, layout);
316
+ const BucketId bucket = store_.AddBucket(key, layout);
275
317
  buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
276
318
  buckets_[bucket] = std::move(entry);
277
- bucketBySchema_.emplace(schema, bucket);
319
+ const ExtentRule rule = schema != nullptr ? schema->Extent() : kNoExtent;
320
+ const bool cached = rule.kind == ExtentRule::Kind::Computed && !rule.readsOtherPrims;
321
+ extents_.Track(bucket, cached ? rule.compute : nullptr);
278
322
  return bucket;
279
323
  }
280
324
 
325
+ void Scene::MoveTo(PrimId prim, const SchemaDef* schema, std::vector<Token> apis) {
326
+ store_.Move(prim, FindOrAddBucket(schema, std::move(apis)));
327
+ }
328
+
329
+ const std::vector<Token>& Scene::Apis(PrimId prim) const {
330
+ return store_.GetBucket(store_.PrimBucket(prim)).key.apiSchemas;
331
+ }
332
+
333
+ void Scene::ApplyApi(PrimId prim, std::string_view api) {
334
+ ApiName::Parse(api);
335
+ std::vector<Token> apis = Apis(prim);
336
+ apis.push_back(store_.Tokens().Intern(api));
337
+ MoveTo(prim, Schema(prim), std::move(apis));
338
+ }
339
+
340
+ bool Scene::RemoveApi(PrimId prim, std::string_view api) {
341
+ if (!HasApi(prim, api)) {
342
+ return false;
343
+ }
344
+ std::vector<Token> apis = Apis(prim);
345
+ std::erase(apis, *store_.Tokens().Find(api));
346
+ MoveTo(prim, Schema(prim), std::move(apis));
347
+ return true;
348
+ }
349
+
350
+ bool Scene::HasApi(PrimId prim, std::string_view api) const {
351
+ const std::optional<Token> token = store_.Tokens().Find(api);
352
+ return token && std::ranges::find(Apis(prim), *token) != Apis(prim).end();
353
+ }
354
+
355
+ std::vector<std::string> Scene::AppliedApis(PrimId prim) const {
356
+ return Map(Apis(prim), [&](Token token) { return std::string(store_.Tokens().Text(token)); });
357
+ }
358
+
281
359
  bool Scene::LeavesOutOfBounds(PrimId prim) const {
282
360
  const auto token = [&](std::string_view attribute) -> std::optional<Token> {
283
361
  const Column* column = AuthoredColumn(prim, attribute);
@@ -296,16 +374,33 @@ const Column* Scene::AuthoredColumn(PrimId prim, std::string_view attribute) con
296
374
  return column != nullptr && column->authored.Test(store_.PrimRow(prim)) ? column : nullptr;
297
375
  }
298
376
 
299
- const AttributeDef* Scene::Declared(PrimId prim, AttributeId attribute) const {
300
- const auto& declared = buckets_[store_.PrimBucket(prim)].declared;
377
+ const AttributeDef* Scene::Declared(BucketId bucket, AttributeId attribute) const {
378
+ const auto& declared = buckets_[bucket].declared;
301
379
  const auto found = declared.find(attribute);
302
380
  return found != declared.end() ? found->second : nullptr;
303
381
  }
304
382
 
383
+ Dirty Scene::Classify(const ChangeSet::Values& change) const {
384
+ if (const AttributeDef* def = Declared(change.bucket, change.attribute)) {
385
+ return def->meta.dirty;
386
+ }
387
+ const std::string_view name = store_.Tokens().Text(change.attribute);
388
+ return name.starts_with(tokens::kXformOpPrefix) ? Dirty::Transform
389
+ : name.starts_with(tokens::kPrimvarsPrefix) ? Dirty::Primvars
390
+ : Dirty::Params;
391
+ }
392
+
393
+ bool Scene::TakesUndeclared(PrimId prim, std::string_view attribute) const {
394
+ const SchemaDef* schema = Schema(prim);
395
+ return schema == nullptr || schema->IsOpen(attribute) ||
396
+ std::ranges::any_of(Apis(prim), [&](Token api) {
397
+ return ApiName::Parse(store_.Tokens().Text(api)).schema->IsOpen(attribute);
398
+ });
399
+ }
400
+
305
401
  ColumnType Scene::TypeForUndeclared(PrimId prim, std::string_view attribute,
306
402
  const Value& value) const {
307
- const SchemaDef* schema = Schema(prim);
308
- if (schema != nullptr && !schema->IsOpen(attribute)) {
403
+ if (!TakesUndeclared(prim, attribute)) {
309
404
  throw std::invalid_argument(Describe(*this, prim) + " has no attribute '" +
310
405
  std::string(attribute) + "'");
311
406
  }