ernie-renderer 0.2.0.dev16__tar.gz → 0.2.0.dev20__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.
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.github/workflows/ci.yml +1 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/CMakeLists.txt +5 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/CMakePresets.json +1 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/PKG-INFO +1 -1
- ernie_renderer-0.2.0.dev20/benchmarks/CMakeLists.txt +3 -0
- ernie_renderer-0.2.0.dev20/benchmarks/bench.h +52 -0
- ernie_renderer-0.2.0.dev20/benchmarks/main.cpp +22 -0
- ernie_renderer-0.2.0.dev20/benchmarks/scene/storage.cpp +118 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/ErnieTesting.cmake +1 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/CMakeLists.txt +2 -4
- ernie_renderer-0.2.0.dev20/ernie/geometry/CMakeLists.txt +3 -0
- ernie_renderer-0.2.0.dev20/ernie/geometry/bounds.h +69 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/CMakeLists.txt +1 -1
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/nanovdb.cpp +4 -14
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/nanovdb.h +5 -5
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/cloud.cpp +1 -2
- ernie_renderer-0.2.0.dev20/ernie/scene/CMakeLists.txt +3 -0
- ernie_renderer-0.2.0.dev20/ernie/scene/path.cpp +193 -0
- ernie_renderer-0.2.0.dev20/ernie/scene/path.h +152 -0
- ernie_renderer-0.2.0.dev20/ernie/scene/storage.cpp +271 -0
- ernie_renderer-0.2.0.dev20/ernie/scene/storage.h +420 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/bytes.h +51 -1
- ernie_renderer-0.2.0.dev20/ernie/util/hash_index.h +103 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/random.h +18 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/text.h +15 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/CMakeLists.txt +6 -0
- ernie_renderer-0.2.0.dev20/tests/common.h +33 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/consumer/CMakeLists.txt +0 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/io/ies_test.cpp +6 -4
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/io/image_test.cpp +4 -3
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/io/nanovdb_test.cpp +13 -16
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/io/raster_test.cpp +50 -55
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/io/texture_test.cpp +10 -10
- ernie_renderer-0.2.0.dev20/tests/scene/path_test.cpp +93 -0
- ernie_renderer-0.2.0.dev20/tests/scene/storage_test.cpp +186 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/bytes_test.cpp +16 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/disk_cache_test.cpp +3 -2
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/file_test.cpp +8 -13
- ernie_renderer-0.2.0.dev20/tests/util/hash_index_test.cpp +50 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/text_test.cpp +9 -0
- ernie_renderer-0.2.0.dev16/ernie/scene/CMakeLists.txt +0 -3
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.clang-format +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.clang-tidy +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.dockerignore +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.gersemirc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.gitattributes +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.github/scripts/coverage_badge.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.github/scripts/install-lavapipe-windows.sh +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.gitignore +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/.pre-commit-config.yaml +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/Dockerfile +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/ErnieConfig.cmake.in +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/ErnieFetch.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/ErnieInstall.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/ErniePackaging.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/ernie.pc.in +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/bc7enc.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/dlpack.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/glm.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/googletest.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/json.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/nanobind.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/openexr.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/stb.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/tracy.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/volk.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/cmake/third_party/vulkan_headers.cmake +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/docs/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/docs/index.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/docs/requirements.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/app/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/app/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/device/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/device/vulkan_devices.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/device/vulkan_devices.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/graph/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/ies.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/ies.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/image.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/image.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/raster.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/raster.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/texture.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/io/texture.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/astronomy.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/astronomy.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/atmosphere.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/atmosphere.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/cloud.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/constants.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/reflectance_library.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/reflectance_library.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/reflectance_table.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/regolith.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/regolith.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/scattering.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/scattering.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/solar.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/solar.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/solar_table.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/spectrum.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/physics/spectrum.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/python/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/python/ernie/__init__.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/python/module.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/render/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/disk_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/disk_cache.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/file.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/file.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/glm.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/linear_algebra.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/log.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/log.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/math.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/noise.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/noise.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/numbers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/parallel.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/profiler.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/profiler.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/tensor.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/tensor.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/version.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/version.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/ernie/util/worker_pool.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/mkdocs.yml +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/pyproject.toml +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/consumer/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/device/vulkan_devices_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/exr/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/exr/make_exr.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/exr/rgba_half_window.exr +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/exr/y_half_zips.exr +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ies/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ies/lamp.tilt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/images/grey16.png +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ktx2/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/float_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/volumes/cube.nvdb +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/fixtures/volumes/make_nvdb.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/astronomy_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/atmosphere_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/cloud_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/reflectance_library_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/regolith_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/scattering_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/solar_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/physics/spectrum_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/python/test_package.py +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/linear_algebra_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/log_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/math_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/noise_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/parallel_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/profiler_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/random_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/tensor_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/version_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/tests/util/worker_pool_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/LICENSES/MIT.txt +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/NOTICE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/README.md +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_containers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_idct.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/zstd/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/zstd/zstd.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/basisu/zstd/zstd_errors.h +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/nanovdb/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev16 → ernie_renderer-0.2.0.dev20}/third_party/nanovdb/PNanoVDB.h +0 -0
|
@@ -96,7 +96,7 @@ jobs:
|
|
|
96
96
|
- name: Build
|
|
97
97
|
run: cmake --build --preset ci --parallel 4
|
|
98
98
|
# The installed library used as end users use it: its headers compile alone and a program
|
|
99
|
-
# links and runs against it
|
|
99
|
+
# links and runs against it. Windows finds ernie.dll on the PATH.
|
|
100
100
|
- name: Install and build a consumer
|
|
101
101
|
shell: bash
|
|
102
102
|
run: |
|
|
@@ -15,10 +15,11 @@ project(
|
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
# Pre-release suffix such as .dev12, written by CI.
|
|
18
|
-
set(ERNIE_VERSION_SUFFIX ".
|
|
18
|
+
set(ERNIE_VERSION_SUFFIX ".dev20" 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)
|
|
22
|
+
option(ERNIE_BUILD_BENCHMARKS "Build Ernie's benchmarks" OFF)
|
|
22
23
|
option(ERNIE_BUILD_PYTHON "Build Ernie's Python module" OFF)
|
|
23
24
|
option(ERNIE_BUILD_APP "Build the ernie program" ON)
|
|
24
25
|
option(ERNIE_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
|
|
@@ -110,6 +111,9 @@ if(ERNIE_BUILD_TESTS)
|
|
|
110
111
|
enable_testing()
|
|
111
112
|
add_subdirectory(tests)
|
|
112
113
|
endif()
|
|
114
|
+
if(ERNIE_BUILD_BENCHMARKS)
|
|
115
|
+
add_subdirectory(benchmarks)
|
|
116
|
+
endif()
|
|
113
117
|
|
|
114
118
|
if(PROJECT_IS_TOP_LEVEL AND NOT SKBUILD)
|
|
115
119
|
include(cmake/ErniePackaging.cmake)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ernie-renderer
|
|
3
|
-
Version: 0.2.0.
|
|
3
|
+
Version: 0.2.0.dev20
|
|
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
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file bench.h
|
|
3
|
+
/// @brief Registering and timing benchmarks, which report against a target and never fail on time.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
#include <chrono>
|
|
8
|
+
#include <functional>
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
namespace ernie::bench {
|
|
13
|
+
|
|
14
|
+
/// What a benchmark measured: its fastest run and the time it aims for, in milliseconds.
|
|
15
|
+
struct Timing {
|
|
16
|
+
double ms = 0.0;
|
|
17
|
+
double targetMs = 0.0;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
struct Benchmark {
|
|
21
|
+
std::string name;
|
|
22
|
+
std::function<Timing()> run;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/// @return Every benchmark registered at static initialization.
|
|
26
|
+
inline std::vector<Benchmark>& Registry() {
|
|
27
|
+
static std::vector<Benchmark> benchmarks;
|
|
28
|
+
return benchmarks;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// Registers a benchmark from a namespace-scope `const bool`.
|
|
32
|
+
inline bool Register(std::string name, std::function<Timing()> run) {
|
|
33
|
+
Registry().push_back({std::move(name), std::move(run)});
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// @brief Times `step` `runs` times, after `setup` before each, to see past a noisy machine.
|
|
38
|
+
/// @return The fastest run, in milliseconds.
|
|
39
|
+
template <typename Setup, typename Step>
|
|
40
|
+
double Fastest(const Setup& setup, const Step& step, int runs = 5) {
|
|
41
|
+
double best = 1e30;
|
|
42
|
+
for (int run = 0; run < runs; ++run) {
|
|
43
|
+
setup();
|
|
44
|
+
const auto start = std::chrono::steady_clock::now();
|
|
45
|
+
step();
|
|
46
|
+
const auto elapsed = std::chrono::steady_clock::now() - start;
|
|
47
|
+
best = std::min(best, std::chrono::duration<double, std::milli>(elapsed).count());
|
|
48
|
+
}
|
|
49
|
+
return best;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
} // namespace ernie::bench
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file main.cpp
|
|
3
|
+
/// @brief Runs the registered benchmarks whose names contain the first argument, and prints each
|
|
4
|
+
/// fastest time beside its target.
|
|
5
|
+
#include "benchmarks/bench.h"
|
|
6
|
+
|
|
7
|
+
#include <cstdio>
|
|
8
|
+
#include <string_view>
|
|
9
|
+
|
|
10
|
+
int main(int argc, char** argv) {
|
|
11
|
+
const std::string_view filter = argc > 1 ? argv[1] : "";
|
|
12
|
+
std::printf("%-48s %12s %12s\n", "benchmark", "ms", "target ms");
|
|
13
|
+
for (const ernie::bench::Benchmark& benchmark : ernie::bench::Registry()) {
|
|
14
|
+
if (benchmark.name.find(filter) == std::string::npos) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const ernie::bench::Timing timing = benchmark.run();
|
|
18
|
+
std::printf("%-48s %12.3f %12.3f%s\n", benchmark.name.c_str(), timing.ms, timing.targetMs,
|
|
19
|
+
timing.ms > timing.targetMs ? " over" : "");
|
|
20
|
+
}
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file storage.cpp
|
|
3
|
+
/// @brief The prim store at 100,000 prims: create, first sync, one edit, edit all, add and remove.
|
|
4
|
+
#include "ernie/scene/storage.h"
|
|
5
|
+
#include "benchmarks/bench.h"
|
|
6
|
+
|
|
7
|
+
#include <memory>
|
|
8
|
+
#include <string>
|
|
9
|
+
#include <vector>
|
|
10
|
+
|
|
11
|
+
namespace ernie::bench {
|
|
12
|
+
namespace {
|
|
13
|
+
|
|
14
|
+
constexpr std::uint32_t kPrims = 100'000;
|
|
15
|
+
|
|
16
|
+
/// 100,000 instanced robots, one per environment, with transforms.
|
|
17
|
+
struct Robots {
|
|
18
|
+
std::unique_ptr<PrimStore> store;
|
|
19
|
+
AttributeId transform = 0;
|
|
20
|
+
BucketId bucket = 0;
|
|
21
|
+
std::vector<PrimId> prims;
|
|
22
|
+
|
|
23
|
+
void Reset() {
|
|
24
|
+
store = std::make_unique<PrimStore>();
|
|
25
|
+
transform = store->Tokens().Intern("xformOp:transform");
|
|
26
|
+
bucket = store->AddBucket(
|
|
27
|
+
{store->Tokens().Intern("Xform"), {}},
|
|
28
|
+
std::vector<ColumnLayout>{ColumnLayout::Of<glm::dmat4>(transform, glm::dmat4(1.0))});
|
|
29
|
+
prims.clear();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
void Create() {
|
|
33
|
+
PathTable& paths = store->Paths();
|
|
34
|
+
const PathId world = paths.Child(kRootPath, "World");
|
|
35
|
+
const Token robot = store->Tokens().Intern("robot");
|
|
36
|
+
std::vector<PathId> robots(kPrims);
|
|
37
|
+
paths.Reserve(2 * kPrims);
|
|
38
|
+
for (std::uint32_t i = 0; i < kPrims; ++i) {
|
|
39
|
+
robots[i] = paths.Child(paths.Child(world, "env_" + std::to_string(i)), robot);
|
|
40
|
+
}
|
|
41
|
+
prims = store->DefineMany(robots, bucket);
|
|
42
|
+
const std::span<glm::dmat4> transforms = store->Write<glm::dmat4>(bucket, transform);
|
|
43
|
+
for (std::uint32_t i = 0; i < kPrims; ++i) {
|
|
44
|
+
transforms[i] = glm::dmat4(1.0);
|
|
45
|
+
transforms[i][3] = glm::dvec4(i, 0.0, 0.0, 1.0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
void Fresh() {
|
|
50
|
+
Reset();
|
|
51
|
+
Create();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const bool kCreate = Register("scene.storage.create_100k", [] {
|
|
56
|
+
Robots robots;
|
|
57
|
+
return Timing{Fastest([&] { robots.Reset(); }, [&] { robots.Create(); }), 50.0};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const bool kFirstSync = Register("scene.storage.first_sync_100k", [] {
|
|
61
|
+
Robots robots;
|
|
62
|
+
return Timing{Fastest([&] { robots.Fresh(); }, [&] { robots.store->ChangesSince(0); }), 50.0};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const bool kOneEdit = Register("scene.storage.one_edit_of_100k", [] {
|
|
66
|
+
Robots robots;
|
|
67
|
+
robots.Fresh();
|
|
68
|
+
std::uint64_t cursor = 0;
|
|
69
|
+
const double ms =
|
|
70
|
+
Fastest([&] { cursor = robots.store->Version(); },
|
|
71
|
+
[&] {
|
|
72
|
+
robots.store->Set(robots.prims[54'321], robots.transform, glm::dmat4(2.0));
|
|
73
|
+
robots.store->ChangesSince(cursor);
|
|
74
|
+
});
|
|
75
|
+
return Timing{ms, 1.0};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const bool kEditAll = Register("scene.storage.edit_all_100k", [] {
|
|
79
|
+
Robots robots;
|
|
80
|
+
robots.Fresh();
|
|
81
|
+
std::uint64_t cursor = 0;
|
|
82
|
+
const double ms = Fastest([&] { cursor = robots.store->Version(); },
|
|
83
|
+
[&] {
|
|
84
|
+
for (glm::dmat4& transform : robots.store->Write<glm::dmat4>(
|
|
85
|
+
robots.bucket, robots.transform)) {
|
|
86
|
+
transform[3].y += 1.0;
|
|
87
|
+
}
|
|
88
|
+
robots.store->ChangesSince(cursor);
|
|
89
|
+
});
|
|
90
|
+
return Timing{ms, 10.0};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const bool kAddRemove = Register("scene.storage.add_remove_1000_of_100k", [] {
|
|
94
|
+
Robots robots;
|
|
95
|
+
std::uint64_t cursor = 0;
|
|
96
|
+
const double ms = Fastest(
|
|
97
|
+
[&] {
|
|
98
|
+
robots.Fresh();
|
|
99
|
+
cursor = robots.store->Version();
|
|
100
|
+
},
|
|
101
|
+
[&] {
|
|
102
|
+
for (std::uint32_t i = 0; i < 1000; ++i) {
|
|
103
|
+
robots.store->Remove(robots.prims[i * 97]);
|
|
104
|
+
}
|
|
105
|
+
PathTable& paths = robots.store->Paths();
|
|
106
|
+
const PathId spawned = paths.Child(kRootPath, "Spawned");
|
|
107
|
+
std::vector<PathId> added(1000);
|
|
108
|
+
for (std::uint32_t i = 0; i < 1000; ++i) {
|
|
109
|
+
added[i] = paths.Child(spawned, "p" + std::to_string(i));
|
|
110
|
+
}
|
|
111
|
+
robots.store->DefineMany(added, robots.bucket);
|
|
112
|
+
robots.store->ChangesSince(cursor);
|
|
113
|
+
});
|
|
114
|
+
return Timing{ms, 5.0};
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
} // namespace
|
|
118
|
+
} // namespace ernie::bench
|
|
@@ -4,7 +4,7 @@ include_guard(GLOBAL)
|
|
|
4
4
|
include("${CMAKE_CURRENT_LIST_DIR}/third_party/googletest.cmake")
|
|
5
5
|
include(GoogleTest)
|
|
6
6
|
|
|
7
|
-
# Hard timeouts per label
|
|
7
|
+
# Hard timeouts per label, to catch hangs; timings are tracked by benchmarks/.
|
|
8
8
|
set(ERNIE_TEST_TIMEOUT_unit 10)
|
|
9
9
|
set(ERNIE_TEST_TIMEOUT_gpu 60)
|
|
10
10
|
set(ERNIE_TEST_TIMEOUT_accuracy 120)
|
|
@@ -22,6 +22,7 @@ set_target_properties(
|
|
|
22
22
|
|
|
23
23
|
# One object library per layer; a layer links only the layers below it.
|
|
24
24
|
add_subdirectory(util)
|
|
25
|
+
add_subdirectory(geometry)
|
|
25
26
|
add_subdirectory(physics)
|
|
26
27
|
add_subdirectory(io)
|
|
27
28
|
add_subdirectory(scene)
|
|
@@ -31,6 +32,7 @@ add_subdirectory(render)
|
|
|
31
32
|
|
|
32
33
|
set(ernie_layers
|
|
33
34
|
ernie_util
|
|
35
|
+
ernie_geometry
|
|
34
36
|
ernie_physics
|
|
35
37
|
ernie_io
|
|
36
38
|
ernie_scene
|
|
@@ -54,12 +56,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
|
54
56
|
target_link_options(ernie PRIVATE "LINKER:--exclude-libs,ALL")
|
|
55
57
|
endif()
|
|
56
58
|
|
|
57
|
-
# The same objects as one static library, for in-tree programs and tests, which may also reach
|
|
58
|
-
# internal APIs, and for the Python module, which carries everything itself.
|
|
59
59
|
add_library(ernie_static STATIC)
|
|
60
60
|
target_link_libraries(ernie_static PUBLIC ${ernie_layers})
|
|
61
|
-
# Its objects export the API (ERNIE_API), so on Windows every program linking it would also write
|
|
62
|
-
# an import library; the ernie program's would collide with libernie's own ernie.lib and ernie.exp.
|
|
63
61
|
target_link_options(ernie_static INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/NOIMPLIB;/NOEXP>")
|
|
64
62
|
|
|
65
63
|
if(ERNIE_BUILD_APP)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file bounds.h
|
|
3
|
+
/// @brief Axis-aligned boxes in double precision.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <glm/glm.hpp>
|
|
7
|
+
|
|
8
|
+
#include <cmath>
|
|
9
|
+
#include <limits>
|
|
10
|
+
|
|
11
|
+
namespace ernie {
|
|
12
|
+
|
|
13
|
+
/// @brief An axis-aligned box; the default one is empty and grows to hold what it is given.
|
|
14
|
+
struct Box {
|
|
15
|
+
glm::dvec3 min{std::numeric_limits<double>::infinity()};
|
|
16
|
+
glm::dvec3 max{-std::numeric_limits<double>::infinity()};
|
|
17
|
+
|
|
18
|
+
static Box Around(const glm::dvec3& center, const glm::dvec3& halfSize) {
|
|
19
|
+
return {center - halfSize, center + halfSize};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
bool Empty() const {
|
|
23
|
+
return !(min.x <= max.x && min.y <= max.y && min.z <= max.z);
|
|
24
|
+
}
|
|
25
|
+
glm::dvec3 Center() const {
|
|
26
|
+
return 0.5 * (min + max);
|
|
27
|
+
}
|
|
28
|
+
glm::dvec3 Size() const {
|
|
29
|
+
return Empty() ? glm::dvec3(0.0) : max - min;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Box& Extend(const glm::dvec3& point) {
|
|
33
|
+
min = glm::min(min, point);
|
|
34
|
+
max = glm::max(max, point);
|
|
35
|
+
return *this;
|
|
36
|
+
}
|
|
37
|
+
Box& Extend(const Box& other) {
|
|
38
|
+
if (!other.Empty()) {
|
|
39
|
+
min = glm::min(min, other.min);
|
|
40
|
+
max = glm::max(max, other.max);
|
|
41
|
+
}
|
|
42
|
+
return *this;
|
|
43
|
+
}
|
|
44
|
+
Box Grown(double margin) const {
|
|
45
|
+
return Empty() ? *this : Box{min - margin, max + margin};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// @return The box holding this one after `transform` (Arvo's method, exact for affine maps).
|
|
49
|
+
Box Transformed(const glm::dmat4& transform) const {
|
|
50
|
+
if (Empty()) {
|
|
51
|
+
return *this;
|
|
52
|
+
}
|
|
53
|
+
const glm::dvec3 translation(transform[3]);
|
|
54
|
+
Box out{translation, translation};
|
|
55
|
+
for (int column = 0; column < 3; ++column) {
|
|
56
|
+
for (int row = 0; row < 3; ++row) {
|
|
57
|
+
const double a = transform[column][row] * min[column];
|
|
58
|
+
const double b = transform[column][row] * max[column];
|
|
59
|
+
out.min[row] += std::min(a, b);
|
|
60
|
+
out.max[row] += std::max(a, b);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bool operator==(const Box&) const = default;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
} // namespace ernie
|
|
@@ -222,22 +222,12 @@ bool NanoVdbGrid::Vector() const {
|
|
|
222
222
|
return type == NanoVdbType::Vec3f;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
min = glm::dvec3(std::numeric_limits<double>::infinity());
|
|
227
|
-
max = -min;
|
|
225
|
+
Box NanoVdbGrid::GridBounds() const {
|
|
228
226
|
if (Empty()) {
|
|
229
|
-
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
|
-
const glm::dvec3 lo = glm::dvec3(indexMin) - 1.0;
|
|
233
|
-
const glm::dvec3 hi = glm::dvec3(indexMax) + 1.0;
|
|
234
|
-
for (int corner = 0; corner < 8; ++corner) {
|
|
235
|
-
const glm::dvec3 index{(corner & 1) != 0 ? hi.x : lo.x, (corner & 2) != 0 ? hi.y : lo.y,
|
|
236
|
-
(corner & 4) != 0 ? hi.z : lo.z};
|
|
237
|
-
const glm::dvec3 point = glm::dvec3(indexToGrid * glm::dvec4(index, 1.0));
|
|
238
|
-
min = glm::min(min, point);
|
|
239
|
-
max = glm::max(max, point);
|
|
227
|
+
const glm::dvec3 origin(indexToGrid[3]);
|
|
228
|
+
return {origin, origin};
|
|
240
229
|
}
|
|
230
|
+
return Box{glm::dvec3(indexMin) - 1.0, glm::dvec3(indexMax) + 1.0}.Transformed(indexToGrid);
|
|
241
231
|
}
|
|
242
232
|
|
|
243
233
|
std::vector<NanoVdbGrid> ParseNanoVdbGrids(std::span<const std::uint8_t> bytes) {
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
/// @brief NanoVDB grids: reading .nvdb/.vdb files and building grids.
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
+
#include "ernie/geometry/bounds.h"
|
|
7
|
+
|
|
6
8
|
#include <glm/glm.hpp>
|
|
7
9
|
|
|
8
10
|
#include <cstdint>
|
|
@@ -79,11 +81,9 @@ struct NanoVdbGrid {
|
|
|
79
81
|
bool Scalar() const;
|
|
80
82
|
/// @return Whether volumes sample a 3-vector per voxel.
|
|
81
83
|
bool Vector() const;
|
|
82
|
-
/// @
|
|
83
|
-
///
|
|
84
|
-
|
|
85
|
-
/// @param max Receives the upper corner.
|
|
86
|
-
void GridBounds(glm::dvec3& min, glm::dvec3& max) const;
|
|
84
|
+
/// @return Active bounds in the grid frame, grown by a voxel on each side for trilinear
|
|
85
|
+
/// sampling; the grid's origin when it has no active voxels.
|
|
86
|
+
Box GridBounds() const;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
/// @brief Reads every grid of a NanoVDB file, in file order.
|
|
@@ -491,8 +491,7 @@ CloudTransportTable SimulateCloudTransport(const DropletPhaseTable& phase,
|
|
|
491
491
|
ParallelFor(shape.lightCosines * shape.thicknesses, [&](std::size_t job) {
|
|
492
492
|
const std::size_t light = job % shape.lightCosines;
|
|
493
493
|
const std::size_t thickness = shape.thicknesses - 1 - job / shape.lightCosines;
|
|
494
|
-
const std::uint64_t seed =
|
|
495
|
-
options.seed * 0x100000001b3ull + static_cast<std::uint64_t>(job) * 0x9e3779b9ull;
|
|
494
|
+
const std::uint64_t seed = HashCombine(options.seed, job);
|
|
496
495
|
const SlabTallies tallies =
|
|
497
496
|
SimulateSlab(shape, sampler, light, thickness, options.photons, seed);
|
|
498
497
|
StoreSlab(tallies, light, thickness, options.photons, table);
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file path.cpp
|
|
3
|
+
/// @brief Path parsing, token interning and the path table.
|
|
4
|
+
#include "ernie/scene/path.h"
|
|
5
|
+
|
|
6
|
+
#include "ernie/util/random.h"
|
|
7
|
+
#include "ernie/util/text.h"
|
|
8
|
+
|
|
9
|
+
#include <algorithm>
|
|
10
|
+
#include <stdexcept>
|
|
11
|
+
|
|
12
|
+
namespace ernie {
|
|
13
|
+
|
|
14
|
+
namespace {
|
|
15
|
+
|
|
16
|
+
/// Calls `visit(name)` for each name of an absolute path's text; "/a/" ends in an empty name.
|
|
17
|
+
template <typename Visit> void ForEachName(std::string_view text, const Visit& visit) {
|
|
18
|
+
if (text.size() <= 1) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (std::size_t start = 1; start <= text.size();) {
|
|
22
|
+
const std::size_t end = std::min(text.find('/', start), text.size());
|
|
23
|
+
visit(text.substr(start, end - start));
|
|
24
|
+
start = end + 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace
|
|
29
|
+
|
|
30
|
+
bool Path::IsValidName(std::string_view name) {
|
|
31
|
+
return IsIdentifier(name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Path::Path(std::string_view text) {
|
|
35
|
+
if (text.empty() || text.front() != '/') {
|
|
36
|
+
throw std::invalid_argument("Prim path '" + std::string(text) + "' is not absolute");
|
|
37
|
+
}
|
|
38
|
+
ForEachName(text, [&](std::string_view name) {
|
|
39
|
+
if (!IsValidName(name)) {
|
|
40
|
+
throw std::invalid_argument("Prim path '" + std::string(text) +
|
|
41
|
+
"' has an invalid name");
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
text_ = text;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Path Path::Root() {
|
|
48
|
+
return Path("/");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
std::string_view Path::Name() const {
|
|
52
|
+
if (text_.size() <= 1) {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
return std::string_view(text_).substr(text_.rfind('/') + 1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
Path Path::Parent() const {
|
|
59
|
+
if (text_.size() <= 1) {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
const std::size_t slash = text_.rfind('/');
|
|
63
|
+
return slash == 0 ? Root() : Path(std::string_view(text_).substr(0, slash));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
Path Path::Child(std::string_view name) const {
|
|
67
|
+
if (IsEmpty() || !IsValidName(name)) {
|
|
68
|
+
throw std::invalid_argument("Cannot append '" + std::string(name) + "' to '" + text_ + "'");
|
|
69
|
+
}
|
|
70
|
+
Path child;
|
|
71
|
+
child.text_ = IsRoot() ? "/" + std::string(name) : text_ + "/" + std::string(name);
|
|
72
|
+
return child;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
bool Path::HasPrefix(const Path& ancestor) const {
|
|
76
|
+
if (ancestor.IsEmpty() || IsEmpty()) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (ancestor.IsRoot()) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return text_.starts_with(ancestor.text_) &&
|
|
83
|
+
(text_.size() == ancestor.text_.size() || text_[ancestor.text_.size()] == '/');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
TokenTable::TokenTable() {
|
|
87
|
+
Intern("");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Token TokenTable::Intern(std::string_view text) {
|
|
91
|
+
const auto next = static_cast<Token>(texts_.size());
|
|
92
|
+
const Token token = index_.Insert(std::hash<std::string_view>()(text), next,
|
|
93
|
+
[&](Token other) { return texts_[other] == text; });
|
|
94
|
+
if (token == next) {
|
|
95
|
+
texts_.emplace_back(text);
|
|
96
|
+
}
|
|
97
|
+
return token;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
std::optional<Token> TokenTable::Find(std::string_view text) const {
|
|
101
|
+
return index_.Find(std::hash<std::string_view>()(text),
|
|
102
|
+
[&](Token other) { return texts_[other] == text; });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
PathTable::PathTable() : nodes_(1) {}
|
|
106
|
+
|
|
107
|
+
std::uint64_t PathTable::Hash(PathId parent, Token name) {
|
|
108
|
+
return Mix64(std::uint64_t{parent} << 32 | name);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void PathTable::Reserve(std::size_t count) {
|
|
112
|
+
nodes_.reserve(nodes_.size() + count);
|
|
113
|
+
children_.Reserve(children_.Size() + count);
|
|
114
|
+
names_.Reserve(count);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
PathId PathTable::Child(PathId parent, Token name) {
|
|
118
|
+
const auto next = static_cast<PathId>(nodes_.size());
|
|
119
|
+
const PathId id = children_.Insert(Hash(parent, name), next, [&](PathId other) {
|
|
120
|
+
return nodes_[other].parent == parent && nodes_[other].name == name;
|
|
121
|
+
});
|
|
122
|
+
if (id != next) {
|
|
123
|
+
return id;
|
|
124
|
+
}
|
|
125
|
+
nodes_.push_back({parent, name});
|
|
126
|
+
Node& above = nodes_[parent];
|
|
127
|
+
if (above.firstChild == kNoPath) {
|
|
128
|
+
above.firstChild = id;
|
|
129
|
+
} else {
|
|
130
|
+
nodes_[above.lastChild].nextSibling = id;
|
|
131
|
+
}
|
|
132
|
+
above.lastChild = id;
|
|
133
|
+
return id;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
PathId PathTable::Intern(const Path& path) {
|
|
137
|
+
if (path.IsEmpty()) {
|
|
138
|
+
throw std::invalid_argument("An empty path names no prim");
|
|
139
|
+
}
|
|
140
|
+
PathId id = kRootPath;
|
|
141
|
+
ForEachName(path.String(), [&](std::string_view name) { id = Child(id, name); });
|
|
142
|
+
return id;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
std::optional<PathId> PathTable::Find(const Path& path) const {
|
|
146
|
+
if (path.IsEmpty()) {
|
|
147
|
+
return std::nullopt;
|
|
148
|
+
}
|
|
149
|
+
PathId id = kRootPath;
|
|
150
|
+
bool found = true;
|
|
151
|
+
ForEachName(path.String(), [&](std::string_view name) {
|
|
152
|
+
const std::optional<Token> token = found ? names_.Find(name) : std::nullopt;
|
|
153
|
+
const std::optional<PathId> child =
|
|
154
|
+
token ? children_.Find(Hash(id, *token),
|
|
155
|
+
[&](PathId other) {
|
|
156
|
+
return nodes_[other].parent == id &&
|
|
157
|
+
nodes_[other].name == *token;
|
|
158
|
+
})
|
|
159
|
+
: std::nullopt;
|
|
160
|
+
found = child.has_value();
|
|
161
|
+
if (found) {
|
|
162
|
+
id = *child;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return found ? std::optional(id) : std::nullopt;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
Path PathTable::ToPath(PathId id) const {
|
|
169
|
+
if (id == kRootPath) {
|
|
170
|
+
return Path::Root();
|
|
171
|
+
}
|
|
172
|
+
std::vector<std::string_view> names;
|
|
173
|
+
for (; id != kRootPath; id = nodes_[id].parent) {
|
|
174
|
+
names.push_back(names_.Text(nodes_[id].name));
|
|
175
|
+
}
|
|
176
|
+
std::string text;
|
|
177
|
+
for (auto name = names.rbegin(); name != names.rend(); ++name) {
|
|
178
|
+
text += '/';
|
|
179
|
+
text += *name;
|
|
180
|
+
}
|
|
181
|
+
return Path(text);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
bool PathTable::HasPrefix(PathId id, PathId ancestor) const {
|
|
185
|
+
for (; id != kNoPath; id = nodes_[id].parent) {
|
|
186
|
+
if (id == ancestor) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
} // namespace ernie
|