ernie-renderer 0.2.0.dev20__tar.gz → 0.2.0.dev21__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.dev20 → ernie_renderer-0.2.0.dev21}/CMakeLists.txt +1 -1
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/PKG-INFO +1 -1
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/device/vulkan_devices.cpp +2 -5
- ernie_renderer-0.2.0.dev21/ernie/scene/CMakeLists.txt +14 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/convert.h +191 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/scene/path.h +7 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/scene.cpp +324 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/scene.h +106 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/schema.cpp +124 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/schema.h +182 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/schemas/geom.cpp +99 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/schemas/geom.h +174 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/schemas/registry.cpp +18 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/scene/storage.cpp +1 -1
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/scene/storage.h +66 -41
- ernie_renderer-0.2.0.dev21/ernie/scene/tokens.h +35 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/value.h +53 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/view.cpp +38 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/view.h +211 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/xform.cpp +227 -0
- ernie_renderer-0.2.0.dev21/ernie/scene/xform.h +49 -0
- ernie_renderer-0.2.0.dev21/ernie/util/algorithm.h +26 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/text.h +7 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/CMakeLists.txt +8 -1
- ernie_renderer-0.2.0.dev21/tests/geometry/bounds_test.cpp +39 -0
- ernie_renderer-0.2.0.dev21/tests/scene/scene_test.cpp +150 -0
- ernie_renderer-0.2.0.dev21/tests/scene/schema_test.cpp +116 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/scene/storage_test.cpp +7 -7
- ernie_renderer-0.2.0.dev21/tests/scene/xform_test.cpp +570 -0
- ernie_renderer-0.2.0.dev21/tests/util/algorithm_test.cpp +22 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/text_test.cpp +6 -0
- ernie_renderer-0.2.0.dev20/ernie/scene/CMakeLists.txt +0 -3
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.clang-format +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.clang-tidy +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.dockerignore +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.gersemirc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.gitattributes +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.github/scripts/coverage_badge.py +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.github/scripts/install-lavapipe-windows.sh +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.github/workflows/ci.yml +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.gitignore +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/.pre-commit-config.yaml +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/CMakePresets.json +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/Dockerfile +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/benchmarks/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/benchmarks/bench.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/benchmarks/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/benchmarks/scene/storage.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/ErnieConfig.cmake.in +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/ErnieFetch.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/ErnieInstall.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/ErniePackaging.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/ErnieTesting.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/ernie.pc.in +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/bc7enc.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/dlpack.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/glm.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/googletest.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/json.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/nanobind.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/openexr.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/stb.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/tracy.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/volk.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/cmake/third_party/vulkan_headers.cmake +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/docs/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/docs/index.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/docs/requirements.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/app/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/app/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/device/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/device/vulkan_devices.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/geometry/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/geometry/bounds.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/graph/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/ies.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/ies.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/image.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/image.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/nanovdb.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/nanovdb.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/raster.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/raster.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/texture.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/io/texture.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/astronomy.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/astronomy.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/atmosphere.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/atmosphere.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/cloud.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/cloud.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/constants.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/reflectance_library.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/reflectance_library.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/reflectance_table.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/regolith.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/regolith.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/scattering.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/scattering.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/solar.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/solar.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/solar_table.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/spectrum.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/physics/spectrum.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/python/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/python/ernie/__init__.py +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/python/module.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/render/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/scene/path.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/bytes.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/disk_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/disk_cache.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/file.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/file.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/glm.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/hash_index.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/linear_algebra.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/log.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/log.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/math.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/noise.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/noise.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/numbers.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/parallel.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/profiler.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/profiler.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/random.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/tensor.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/tensor.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/version.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/version.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/ernie/util/worker_pool.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/mkdocs.yml +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/pyproject.toml +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/common.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/consumer/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/consumer/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/device/vulkan_devices_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/exr/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/exr/make_exr.py +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/exr/rgba_half_window.exr +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/exr/y_half_zips.exr +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ies/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ies/lamp.tilt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/images/grey16.png +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ktx2/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/float_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/volumes/cube.nvdb +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/fixtures/volumes/make_nvdb.py +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/io/ies_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/io/image_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/io/nanovdb_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/io/raster_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/io/texture_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/astronomy_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/atmosphere_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/cloud_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/reflectance_library_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/regolith_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/scattering_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/solar_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/physics/spectrum_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/python/test_package.py +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/scene/path_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/bytes_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/disk_cache_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/file_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/hash_index_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/linear_algebra_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/log_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/math_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/noise_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/parallel_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/profiler_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/random_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/tensor_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/version_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/tests/util/worker_pool_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/LICENSES/MIT.txt +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/NOTICE +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/README.md +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_containers.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_idct.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/zstd/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/zstd/zstd.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/basisu/zstd/zstd_errors.h +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/third_party/nanovdb/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev20 → ernie_renderer-0.2.0.dev21}/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 ".
|
|
18
|
+
set(ERNIE_VERSION_SUFFIX ".dev21" 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.
|
|
3
|
+
Version: 0.2.0.dev21
|
|
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
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
/// @file vulkan_devices.cpp
|
|
3
3
|
/// @brief Lists Vulkan devices through a short-lived instance.
|
|
4
4
|
#include "ernie/device/vulkan_devices.h"
|
|
5
|
+
#include "ernie/util/algorithm.h"
|
|
5
6
|
|
|
6
7
|
#include <volk.h>
|
|
7
8
|
|
|
8
9
|
#include <algorithm>
|
|
9
|
-
#include <iterator>
|
|
10
10
|
#include <stdexcept>
|
|
11
11
|
#include <string_view>
|
|
12
12
|
|
|
@@ -107,10 +107,7 @@ std::vector<VulkanDeviceInfo> ListVulkanDevices() {
|
|
|
107
107
|
std::vector<VkPhysicalDevice> devices(count);
|
|
108
108
|
vkEnumeratePhysicalDevices(instance.Get(), &count, devices.data());
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
infos.reserve(devices.size());
|
|
112
|
-
std::ranges::transform(devices, std::back_inserter(infos), ReadDeviceInfo);
|
|
113
|
-
return infos;
|
|
110
|
+
return Map(devices, ReadDeviceInfo);
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
const char* ToString(VulkanDeviceType type) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
add_library(
|
|
3
|
+
ernie_scene
|
|
4
|
+
OBJECT
|
|
5
|
+
path.cpp
|
|
6
|
+
schema.cpp
|
|
7
|
+
scene.cpp
|
|
8
|
+
storage.cpp
|
|
9
|
+
view.cpp
|
|
10
|
+
xform.cpp
|
|
11
|
+
schemas/geom.cpp
|
|
12
|
+
schemas/registry.cpp
|
|
13
|
+
)
|
|
14
|
+
target_link_libraries(ernie_scene PUBLIC ernie_physics ernie_io PRIVATE ernie_build_options)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file convert.h
|
|
3
|
+
/// @brief Conversions between `Value`s and column elements.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "ernie/scene/storage.h"
|
|
7
|
+
#include "ernie/scene/value.h"
|
|
8
|
+
#include "ernie/util/algorithm.h"
|
|
9
|
+
|
|
10
|
+
#include <cmath>
|
|
11
|
+
#include <optional>
|
|
12
|
+
#include <type_traits>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
namespace ernie {
|
|
16
|
+
|
|
17
|
+
/// @return A number of any width, or none.
|
|
18
|
+
inline std::optional<double> ToNumber(const Value& value) {
|
|
19
|
+
if (const auto* d = value.Get<double>()) {
|
|
20
|
+
return *d;
|
|
21
|
+
}
|
|
22
|
+
if (const auto* f = value.Get<float>()) {
|
|
23
|
+
return *f;
|
|
24
|
+
}
|
|
25
|
+
if (const auto* i = value.Get<int>()) {
|
|
26
|
+
return *i;
|
|
27
|
+
}
|
|
28
|
+
return std::nullopt;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// @return A vector of N doubles from one of floats, doubles or (for two) ints, or none.
|
|
32
|
+
template <glm::length_t N> std::optional<glm::vec<N, double>> ToVector(const Value& value) {
|
|
33
|
+
if (const auto* d = value.Get<glm::vec<N, double>>()) {
|
|
34
|
+
return *d;
|
|
35
|
+
}
|
|
36
|
+
if (const auto* f = value.Get<glm::vec<N, float>>()) {
|
|
37
|
+
return glm::vec<N, double>(*f);
|
|
38
|
+
}
|
|
39
|
+
if constexpr (N == 2) {
|
|
40
|
+
if (const auto* i = value.Get<glm::ivec2>()) {
|
|
41
|
+
return glm::dvec2(*i);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return std::nullopt;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// @return The numbers of a number, or the components of a vector; none for other values.
|
|
48
|
+
inline std::vector<double> ToNumbers(const Value& value) {
|
|
49
|
+
if (const std::optional<double> number = ToNumber(value)) {
|
|
50
|
+
return {*number};
|
|
51
|
+
}
|
|
52
|
+
const auto components = [](const auto& vector) {
|
|
53
|
+
std::vector<double> numbers(static_cast<std::size_t>(vector.length()));
|
|
54
|
+
for (glm::length_t i = 0; i < vector.length(); ++i) {
|
|
55
|
+
numbers[static_cast<std::size_t>(i)] = vector[i];
|
|
56
|
+
}
|
|
57
|
+
return numbers;
|
|
58
|
+
};
|
|
59
|
+
if (const auto v = ToVector<2>(value)) {
|
|
60
|
+
return components(*v);
|
|
61
|
+
}
|
|
62
|
+
if (const auto v = ToVector<3>(value)) {
|
|
63
|
+
return components(*v);
|
|
64
|
+
}
|
|
65
|
+
if (const auto v = ToVector<4>(value)) {
|
|
66
|
+
return components(*v);
|
|
67
|
+
}
|
|
68
|
+
return {};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// @return `value` as a column element, interning tokens and paths; none if it is another kind.
|
|
72
|
+
template <typename T> std::optional<T> ToElement(PathTable& paths, const Value& value) {
|
|
73
|
+
if constexpr (std::is_same_v<T, std::uint8_t>) {
|
|
74
|
+
if (const auto* b = value.Get<bool>()) {
|
|
75
|
+
return static_cast<std::uint8_t>(*b);
|
|
76
|
+
}
|
|
77
|
+
if (const auto* i = value.Get<int>(); i && (*i == 0 || *i == 1)) {
|
|
78
|
+
return static_cast<std::uint8_t>(*i);
|
|
79
|
+
}
|
|
80
|
+
} else if constexpr (std::is_same_v<T, std::int32_t>) {
|
|
81
|
+
if (const std::optional<double> n = ToNumber(value); n && std::trunc(*n) == *n) {
|
|
82
|
+
return static_cast<std::int32_t>(*n);
|
|
83
|
+
}
|
|
84
|
+
} else if constexpr (std::is_same_v<T, double>) {
|
|
85
|
+
return ToNumber(value);
|
|
86
|
+
} else if constexpr (std::is_same_v<T, glm::dvec2> || std::is_same_v<T, glm::dvec3> ||
|
|
87
|
+
std::is_same_v<T, glm::dvec4>) {
|
|
88
|
+
return ToVector<T::length()>(value);
|
|
89
|
+
} else if constexpr (std::is_same_v<T, glm::dquat>) {
|
|
90
|
+
if (const auto* q = value.Get<glm::dquat>()) {
|
|
91
|
+
return *q;
|
|
92
|
+
}
|
|
93
|
+
} else if constexpr (std::is_same_v<T, glm::dmat4>) {
|
|
94
|
+
if (const auto* m = value.Get<glm::dmat4>()) {
|
|
95
|
+
return *m;
|
|
96
|
+
}
|
|
97
|
+
} else if constexpr (std::is_same_v<T, Token>) {
|
|
98
|
+
if (const auto* text = value.Get<std::string>()) {
|
|
99
|
+
return paths.Names().Intern(*text);
|
|
100
|
+
}
|
|
101
|
+
} else if constexpr (std::is_same_v<T, Target>) {
|
|
102
|
+
if (const auto* path = value.Get<Path>()) {
|
|
103
|
+
return Target{path->IsEmpty() ? kNoPath : paths.Intern(*path)};
|
|
104
|
+
}
|
|
105
|
+
} else if constexpr (std::is_same_v<T, std::vector<Target>>) {
|
|
106
|
+
if (const auto* path = value.Get<Path>()) {
|
|
107
|
+
return std::vector<Target>{{paths.Intern(*path)}};
|
|
108
|
+
}
|
|
109
|
+
if (const auto* list = value.Get<std::vector<Path>>()) {
|
|
110
|
+
return Map(*list, [&](const Path& path) { return Target{paths.Intern(path)}; });
|
|
111
|
+
}
|
|
112
|
+
} else if constexpr (std::is_same_v<T, std::vector<float>>) {
|
|
113
|
+
if (const auto* floats = value.Get<std::vector<float>>()) {
|
|
114
|
+
return *floats;
|
|
115
|
+
}
|
|
116
|
+
if (const std::optional<double> n = ToNumber(value)) {
|
|
117
|
+
return std::vector<float>{static_cast<float>(*n)};
|
|
118
|
+
}
|
|
119
|
+
} else if constexpr (std::is_same_v<T, std::vector<Token>>) {
|
|
120
|
+
if (const auto* texts = value.Get<std::vector<std::string>>()) {
|
|
121
|
+
return Map(*texts, [&](const std::string& text) { return paths.Names().Intern(text); });
|
|
122
|
+
}
|
|
123
|
+
// An empty list, as Python and JSON pass one.
|
|
124
|
+
if (const auto* floats = value.Get<std::vector<float>>(); floats && floats->empty()) {
|
|
125
|
+
return std::vector<Token>{};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return std::nullopt;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// @return A column element as a `Value`; tensors have none.
|
|
132
|
+
template <typename T> Value ToValue(const PathTable& paths, const T& element) {
|
|
133
|
+
if constexpr (std::is_same_v<T, std::uint8_t>) {
|
|
134
|
+
return element != 0;
|
|
135
|
+
} else if constexpr (std::is_same_v<T, std::int32_t>) {
|
|
136
|
+
return static_cast<int>(element);
|
|
137
|
+
} else if constexpr (std::is_same_v<T, Token>) {
|
|
138
|
+
return std::string(paths.Names().Text(element));
|
|
139
|
+
} else if constexpr (std::is_same_v<T, Target>) {
|
|
140
|
+
return element.path == kNoPath ? Path() : paths.ToPath(element.path);
|
|
141
|
+
} else if constexpr (std::is_same_v<T, std::vector<Target>>) {
|
|
142
|
+
return Map(element, [&](const Target& target) { return paths.ToPath(target.path); });
|
|
143
|
+
} else if constexpr (std::is_same_v<T, std::vector<Token>>) {
|
|
144
|
+
return Map(element, [&](Token token) { return std::string(paths.Names().Text(token)); });
|
|
145
|
+
} else if constexpr (std::is_same_v<T, Tensor>) {
|
|
146
|
+
return Value();
|
|
147
|
+
} else {
|
|
148
|
+
return element;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/// @return The column type an undeclared attribute's first value makes, or none.
|
|
153
|
+
inline std::optional<ColumnType> InferColumnType(const Value& value) {
|
|
154
|
+
return std::visit(
|
|
155
|
+
[](const auto& v) -> std::optional<ColumnType> {
|
|
156
|
+
using V = std::decay_t<decltype(v)>;
|
|
157
|
+
if constexpr (std::is_same_v<V, bool>) {
|
|
158
|
+
return ColumnType::Bool;
|
|
159
|
+
} else if constexpr (std::is_same_v<V, int>) {
|
|
160
|
+
return ColumnType::Int;
|
|
161
|
+
} else if constexpr (std::is_same_v<V, float> || std::is_same_v<V, double>) {
|
|
162
|
+
return ColumnType::Double;
|
|
163
|
+
} else if constexpr (std::is_same_v<V, glm::ivec2> || std::is_same_v<V, glm::vec2> ||
|
|
164
|
+
std::is_same_v<V, glm::dvec2>) {
|
|
165
|
+
return ColumnType::Vec2;
|
|
166
|
+
} else if constexpr (std::is_same_v<V, glm::vec3> || std::is_same_v<V, glm::dvec3>) {
|
|
167
|
+
return ColumnType::Vec3;
|
|
168
|
+
} else if constexpr (std::is_same_v<V, glm::vec4> || std::is_same_v<V, glm::dvec4>) {
|
|
169
|
+
return ColumnType::Vec4;
|
|
170
|
+
} else if constexpr (std::is_same_v<V, glm::dquat>) {
|
|
171
|
+
return ColumnType::Quat;
|
|
172
|
+
} else if constexpr (std::is_same_v<V, glm::dmat4>) {
|
|
173
|
+
return ColumnType::Matrix;
|
|
174
|
+
} else if constexpr (std::is_same_v<V, std::string>) {
|
|
175
|
+
return ColumnType::TokenValue;
|
|
176
|
+
} else if constexpr (std::is_same_v<V, Path>) {
|
|
177
|
+
return ColumnType::Relationship;
|
|
178
|
+
} else if constexpr (std::is_same_v<V, std::vector<Path>>) {
|
|
179
|
+
return ColumnType::Relationships;
|
|
180
|
+
} else if constexpr (std::is_same_v<V, std::vector<float>>) {
|
|
181
|
+
return ColumnType::FloatArray;
|
|
182
|
+
} else if constexpr (std::is_same_v<V, std::vector<std::string>>) {
|
|
183
|
+
return ColumnType::TokenArray;
|
|
184
|
+
} else {
|
|
185
|
+
return std::nullopt;
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
value.Raw());
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
} // namespace ernie
|
|
@@ -113,6 +113,13 @@ class PathTable {
|
|
|
113
113
|
PathId NextSibling(PathId id) const {
|
|
114
114
|
return nodes_[id].nextSibling;
|
|
115
115
|
}
|
|
116
|
+
/// Calls `visit(child)` for each child of `id`, in the order they were added.
|
|
117
|
+
template <typename Visit> void ForEachChild(PathId id, const Visit& visit) const {
|
|
118
|
+
for (PathId child = nodes_[id].firstChild; child != kNoPath;
|
|
119
|
+
child = nodes_[child].nextSibling) {
|
|
120
|
+
visit(child);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
116
123
|
/// @return Whether `id` is `ancestor` or lies below it.
|
|
117
124
|
bool HasPrefix(PathId id, PathId ancestor) const;
|
|
118
125
|
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file scene.cpp
|
|
3
|
+
/// @brief Prims, attributes, transforms and bounds over the columnar store.
|
|
4
|
+
#include "ernie/scene/scene.h"
|
|
5
|
+
|
|
6
|
+
#include "ernie/scene/convert.h"
|
|
7
|
+
#include "ernie/scene/schemas/geom.h"
|
|
8
|
+
#include "ernie/scene/tokens.h"
|
|
9
|
+
#include "ernie/scene/xform.h"
|
|
10
|
+
|
|
11
|
+
#include <algorithm>
|
|
12
|
+
#include <stdexcept>
|
|
13
|
+
#include <string>
|
|
14
|
+
|
|
15
|
+
namespace ernie {
|
|
16
|
+
namespace {
|
|
17
|
+
|
|
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);
|
|
21
|
+
return WithColumnType(def.type, [&]<typename T>(std::type_identity<T>) {
|
|
22
|
+
if constexpr (std::is_same_v<T, Tensor>) {
|
|
23
|
+
return ColumnLayout::Of<T>(attribute);
|
|
24
|
+
} else {
|
|
25
|
+
return ColumnLayout::Of<T>(attribute, ToElement<T>(paths, def.fallback).value_or(T{}));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
std::string Describe(const Scene& scene, PrimId prim) {
|
|
31
|
+
const std::string_view type = scene.TypeName(prim);
|
|
32
|
+
return "'" + scene.PrimPath(prim).String() + "'" +
|
|
33
|
+
(type.empty() ? std::string() : " (" + std::string(type) + ")");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
} // namespace
|
|
37
|
+
|
|
38
|
+
Scene::Scene()
|
|
39
|
+
: invisible_(store_.Tokens().Intern(tokens::kInvisible)),
|
|
40
|
+
defaultPurpose_(store_.Tokens().Intern(tokens::kDefault)) {
|
|
41
|
+
BucketFor(nullptr);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
PrimId Scene::Define(const Path& path, std::string_view type) {
|
|
45
|
+
if (path.IsEmpty() || path.IsRoot()) {
|
|
46
|
+
throw std::invalid_argument("Cannot define the prim at '" + path.String() + "'");
|
|
47
|
+
}
|
|
48
|
+
const SchemaDef* schema = type.empty() ? nullptr : FindSchema(type);
|
|
49
|
+
if (!type.empty() && (schema == nullptr || schema->kind != SchemaKind::Concrete)) {
|
|
50
|
+
throw std::invalid_argument("Cannot define '" + path.String() + "' as '" +
|
|
51
|
+
std::string(type) + "', which is no prim type");
|
|
52
|
+
}
|
|
53
|
+
PathTable& paths = store_.Paths();
|
|
54
|
+
const PathId id = paths.Intern(path);
|
|
55
|
+
for (PathId above = paths.Parent(id); above != kRootPath; above = paths.Parent(above)) {
|
|
56
|
+
if (!store_.Find(above)) {
|
|
57
|
+
store_.Define(above, 0);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const BucketId bucket = BucketFor(schema);
|
|
61
|
+
if (const std::optional<PrimId> existing = store_.Find(id)) {
|
|
62
|
+
store_.Move(*existing, bucket);
|
|
63
|
+
return *existing;
|
|
64
|
+
}
|
|
65
|
+
return store_.Define(id, bucket);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
bool Scene::Remove(const Path& path) {
|
|
69
|
+
if (path.IsRoot()) {
|
|
70
|
+
throw std::invalid_argument("Cannot remove the root prim");
|
|
71
|
+
}
|
|
72
|
+
const std::optional<PathId> id = store_.Paths().Find(path);
|
|
73
|
+
if (!id || !store_.Find(*id)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
std::vector<PathId> pending{*id};
|
|
77
|
+
while (!pending.empty()) {
|
|
78
|
+
const PathId next = pending.back();
|
|
79
|
+
pending.pop_back();
|
|
80
|
+
if (const std::optional<PrimId> prim = store_.Find(next)) {
|
|
81
|
+
store_.Remove(*prim);
|
|
82
|
+
}
|
|
83
|
+
store_.Paths().ForEachChild(next, [&](PathId child) { pending.push_back(child); });
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
std::optional<PrimId> Scene::Find(const Path& path) const {
|
|
89
|
+
const std::optional<PathId> id = store_.Paths().Find(path);
|
|
90
|
+
return id ? store_.Find(*id) : std::nullopt;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
Path Scene::PrimPath(PrimId prim) const {
|
|
94
|
+
return store_.Paths().ToPath(store_.PrimPath(prim));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
std::string_view Scene::TypeName(PrimId prim) const {
|
|
98
|
+
const SchemaDef* schema = Schema(prim);
|
|
99
|
+
return schema != nullptr ? schema->name : std::string_view();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const SchemaDef* Scene::Schema(PrimId prim) const {
|
|
103
|
+
return buckets_[store_.PrimBucket(prim)].schema;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
std::vector<Path> Scene::Children(const Path& path) const {
|
|
107
|
+
std::vector<Path> children;
|
|
108
|
+
const PathTable& paths = store_.Paths();
|
|
109
|
+
if (const std::optional<PathId> id = path.IsRoot() ? kRootPath : paths.Find(path)) {
|
|
110
|
+
paths.ForEachChild(*id, [&](PathId child) {
|
|
111
|
+
if (store_.Find(child)) {
|
|
112
|
+
children.push_back(paths.ToPath(child));
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return children;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
std::vector<Path> Scene::Prims(std::string_view type) const {
|
|
120
|
+
const SchemaDef* base = type.empty() ? nullptr : FindSchema(type);
|
|
121
|
+
if (!type.empty() && base == nullptr) {
|
|
122
|
+
throw std::invalid_argument("'" + std::string(type) + "' is no prim type");
|
|
123
|
+
}
|
|
124
|
+
std::vector<Path> prims;
|
|
125
|
+
for (BucketId bucket = 0; bucket < buckets_.size(); ++bucket) {
|
|
126
|
+
const SchemaDef* schema = buckets_[bucket].schema;
|
|
127
|
+
if (base == nullptr || (schema != nullptr && schema->IsA(*base))) {
|
|
128
|
+
for (const PrimId prim : store_.GetBucket(bucket).prims) {
|
|
129
|
+
prims.push_back(PrimPath(prim));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
std::ranges::sort(prims);
|
|
134
|
+
return prims;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void Scene::Set(PrimId prim, std::string_view attribute, const Value& value) {
|
|
138
|
+
const AttributeId token = store_.Tokens().Intern(attribute);
|
|
139
|
+
const AttributeDef* def = Declared(prim, token);
|
|
140
|
+
if (def != nullptr) {
|
|
141
|
+
Validate(*def, value, PrimPath(prim));
|
|
142
|
+
}
|
|
143
|
+
const ColumnType type = def != nullptr ? def->type : TypeForUndeclared(prim, attribute, value);
|
|
144
|
+
WithColumnType(type, [&]<typename T>(std::type_identity<T>) {
|
|
145
|
+
std::optional<T> element = ToElement<T>(store_.Paths(), value);
|
|
146
|
+
if (!element) {
|
|
147
|
+
throw std::invalid_argument(Describe(*this, prim) + ": '" + std::string(attribute) +
|
|
148
|
+
"' takes another type of value");
|
|
149
|
+
}
|
|
150
|
+
store_.Set(prim, token, std::move(*element));
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
void Scene::Set(const Path& path, std::string_view attribute, const Value& value) {
|
|
155
|
+
Set(Require(path), attribute, value);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
std::optional<Value> Scene::Get(PrimId prim, std::string_view attribute) const {
|
|
159
|
+
const Column* column = AuthoredColumn(prim, attribute);
|
|
160
|
+
if (column == nullptr) {
|
|
161
|
+
return std::nullopt;
|
|
162
|
+
}
|
|
163
|
+
return WithColumnType(column->values->Type(), [&]<typename T>(std::type_identity<T>) {
|
|
164
|
+
const auto values = store_.Read<T>(store_.PrimBucket(prim), column->attribute);
|
|
165
|
+
return ToValue(store_.Paths(), values[store_.PrimRow(prim)]);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
std::optional<Value> Scene::Get(const Path& path, std::string_view attribute) const {
|
|
170
|
+
return Get(Require(path), attribute);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
bool Scene::Clear(PrimId prim, std::string_view attribute) {
|
|
174
|
+
const Column* column = AuthoredColumn(prim, attribute);
|
|
175
|
+
if (column != nullptr) {
|
|
176
|
+
store_.Clear(prim, column->attribute);
|
|
177
|
+
}
|
|
178
|
+
return column != nullptr;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
bool Scene::IsAuthored(PrimId prim, std::string_view attribute) const {
|
|
182
|
+
return AuthoredColumn(prim, attribute) != nullptr;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
std::vector<std::string> Scene::Attributes(const Path& path) const {
|
|
186
|
+
const PrimId prim = Require(path);
|
|
187
|
+
std::vector<std::string> names;
|
|
188
|
+
for (const Column& column : store_.GetBucket(store_.PrimBucket(prim)).columns) {
|
|
189
|
+
if (column.authored.Test(store_.PrimRow(prim))) {
|
|
190
|
+
names.emplace_back(store_.Tokens().Text(column.attribute));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return names;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
glm::dmat4 Scene::LocalTransform(PrimId prim) const {
|
|
197
|
+
const SchemaDef* schema = Schema(prim);
|
|
198
|
+
const bool xformable = schema != nullptr && schema->IsA(Xformable::Definition());
|
|
199
|
+
return xformable ? ComposeXformOps(*this, prim) : glm::dmat4(1.0);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
glm::dmat4 Scene::WorldTransform(PrimId prim) const {
|
|
203
|
+
glm::dmat4 world = LocalTransform(prim);
|
|
204
|
+
const PathTable& paths = store_.Paths();
|
|
205
|
+
for (PathId above = paths.Parent(store_.PrimPath(prim));
|
|
206
|
+
above != kRootPath && !ResetsXformStack(*this, prim); above = paths.Parent(above)) {
|
|
207
|
+
prim = *store_.Find(above);
|
|
208
|
+
world = LocalTransform(prim) * world;
|
|
209
|
+
}
|
|
210
|
+
return world;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
std::optional<Box> Scene::Extent(PrimId prim) const {
|
|
214
|
+
const SchemaDef* schema = Schema(prim);
|
|
215
|
+
const ExtentRule rule = schema != nullptr ? schema->Extent() : kNoExtent;
|
|
216
|
+
if (rule.kind != ExtentRule::Kind::Computed) {
|
|
217
|
+
return std::nullopt;
|
|
218
|
+
}
|
|
219
|
+
const std::uint32_t row = store_.PrimRow(prim);
|
|
220
|
+
Box extent;
|
|
221
|
+
rule.compute({store_, store_.PrimBucket(prim)}, {row, row + 1}, std::span(&extent, 1));
|
|
222
|
+
return extent;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
Box Scene::WorldBounds(const Path& path) const {
|
|
226
|
+
const PrimId prim = Require(path);
|
|
227
|
+
const PathId id = store_.PrimPath(prim);
|
|
228
|
+
const PathId parent = store_.Paths().Parent(id);
|
|
229
|
+
const glm::dmat4 above =
|
|
230
|
+
parent == kRootPath ? glm::dmat4(1.0) : WorldTransform(*store_.Find(parent));
|
|
231
|
+
Box bounds;
|
|
232
|
+
AddTo(bounds, id, above);
|
|
233
|
+
return bounds;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent) const {
|
|
237
|
+
const PrimId prim = *store_.Find(path);
|
|
238
|
+
if (LeavesOutOfBounds(prim)) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const glm::dmat4 local = LocalTransform(prim);
|
|
242
|
+
const glm::dmat4 world = ResetsXformStack(*this, prim) ? local : parent * local;
|
|
243
|
+
if (const std::optional<Box> extent = Extent(prim)) {
|
|
244
|
+
bounds.Extend(extent->Transformed(world));
|
|
245
|
+
}
|
|
246
|
+
store_.Paths().ForEachChild(path, [&](PathId child) {
|
|
247
|
+
if (store_.Find(child)) {
|
|
248
|
+
AddTo(bounds, child, world);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
PrimId Scene::Require(const Path& path) const {
|
|
254
|
+
const std::optional<PrimId> prim = Find(path);
|
|
255
|
+
if (!prim) {
|
|
256
|
+
throw std::invalid_argument("No prim at '" + path.String() + "'");
|
|
257
|
+
}
|
|
258
|
+
return *prim;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
BucketId Scene::BucketFor(const SchemaDef* schema) {
|
|
262
|
+
if (const auto found = bucketBySchema_.find(schema); found != bucketBySchema_.end()) {
|
|
263
|
+
return found->second;
|
|
264
|
+
}
|
|
265
|
+
PathTable& paths = store_.Paths();
|
|
266
|
+
BucketSchema entry{schema, {}};
|
|
267
|
+
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);
|
|
272
|
+
}
|
|
273
|
+
const Token type = paths.Names().Intern(schema != nullptr ? schema->name : "");
|
|
274
|
+
const BucketId bucket = store_.AddBucket({type, {}}, layout);
|
|
275
|
+
buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
|
|
276
|
+
buckets_[bucket] = std::move(entry);
|
|
277
|
+
bucketBySchema_.emplace(schema, bucket);
|
|
278
|
+
return bucket;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
bool Scene::LeavesOutOfBounds(PrimId prim) const {
|
|
282
|
+
const auto token = [&](std::string_view attribute) -> std::optional<Token> {
|
|
283
|
+
const Column* column = AuthoredColumn(prim, attribute);
|
|
284
|
+
return column ? std::optional(store_.Read<Token>(store_.PrimBucket(prim),
|
|
285
|
+
column->attribute)[store_.PrimRow(prim)])
|
|
286
|
+
: std::nullopt;
|
|
287
|
+
};
|
|
288
|
+
// Purpose is inherited, so a subtree under another purpose is left out whole.
|
|
289
|
+
const std::optional<Token> purpose = token(Imageable::kPurpose);
|
|
290
|
+
return token(Imageable::kVisibility) == invisible_ || (purpose && *purpose != defaultPurpose_);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const Column* Scene::AuthoredColumn(PrimId prim, std::string_view attribute) const {
|
|
294
|
+
const std::optional<Token> token = store_.Tokens().Find(attribute);
|
|
295
|
+
const Column* column = token ? store_.GetBucket(store_.PrimBucket(prim)).Find(*token) : nullptr;
|
|
296
|
+
return column != nullptr && column->authored.Test(store_.PrimRow(prim)) ? column : nullptr;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const AttributeDef* Scene::Declared(PrimId prim, AttributeId attribute) const {
|
|
300
|
+
const auto& declared = buckets_[store_.PrimBucket(prim)].declared;
|
|
301
|
+
const auto found = declared.find(attribute);
|
|
302
|
+
return found != declared.end() ? found->second : nullptr;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
ColumnType Scene::TypeForUndeclared(PrimId prim, std::string_view attribute,
|
|
306
|
+
const Value& value) const {
|
|
307
|
+
const SchemaDef* schema = Schema(prim);
|
|
308
|
+
if (schema != nullptr && !schema->IsOpen(attribute)) {
|
|
309
|
+
throw std::invalid_argument(Describe(*this, prim) + " has no attribute '" +
|
|
310
|
+
std::string(attribute) + "'");
|
|
311
|
+
}
|
|
312
|
+
const Token token = *store_.Tokens().Find(attribute);
|
|
313
|
+
if (const Column* column = store_.GetBucket(store_.PrimBucket(prim)).Find(token)) {
|
|
314
|
+
return column->values->Type();
|
|
315
|
+
}
|
|
316
|
+
const std::optional<ColumnType> type = InferColumnType(value);
|
|
317
|
+
if (!type) {
|
|
318
|
+
throw std::invalid_argument(Describe(*this, prim) + ": '" + std::string(attribute) +
|
|
319
|
+
"' takes no empty value");
|
|
320
|
+
}
|
|
321
|
+
return *type;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
} // namespace ernie
|