ernie-renderer 0.2.0.dev37__tar.gz → 0.2.0.dev43__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.dev37 → ernie_renderer-0.2.0.dev43}/CMakeLists.txt +1 -1
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/PKG-INFO +1 -1
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/benchmarks/scene/extents.cpp +21 -6
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/CMakeLists.txt +2 -0
- ernie_renderer-0.2.0.dev43/ernie/scene/holder_index.cpp +111 -0
- ernie_renderer-0.2.0.dev43/ernie/scene/holder_index.h +42 -0
- ernie_renderer-0.2.0.dev43/ernie/scene/inherit.cpp +120 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/scene.cpp +52 -15
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/scene.h +47 -3
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schema.cpp +22 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schema.h +13 -1
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/geom.cpp +2 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/geom.h +52 -5
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/mesh.cpp +13 -6
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/mesh.h +47 -5
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/registry.cpp +6 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/shade.h +1 -1
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/storage.h +19 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/tokens.h +2 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/CMakeLists.txt +2 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/extent_cache_test.cpp +3 -3
- ernie_renderer-0.2.0.dev43/tests/scene/holder_index_test.cpp +63 -0
- ernie_renderer-0.2.0.dev43/tests/scene/inherit_test.cpp +129 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/mesh_test.cpp +21 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/schema_test.cpp +28 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/vol_test.cpp +1 -1
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.clang-format +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.clang-tidy +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.dockerignore +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.gersemirc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.gitattributes +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.github/scripts/coverage_badge.py +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.github/scripts/install-lavapipe-windows.sh +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.github/workflows/ci.yml +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.gitignore +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/.pre-commit-config.yaml +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/CMakePresets.json +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/Dockerfile +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/benchmarks/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/benchmarks/bench.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/benchmarks/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/benchmarks/scene/storage.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/ErnieConfig.cmake.in +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/ErnieFetch.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/ErnieInstall.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/ErniePackaging.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/ErnieTesting.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/ernie.pc.in +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/bc7enc.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/dlpack.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/glm.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/googletest.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/json.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/nanobind.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/openexr.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/stb.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/tracy.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/volk.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/cmake/third_party/vulkan_headers.cmake +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/docs/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/docs/index.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/docs/requirements.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/app/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/app/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/device/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/device/vulkan_devices.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/device/vulkan_devices.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/geometry/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/geometry/bounds.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/graph/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/ies.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/ies.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/image.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/image.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/nanovdb.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/nanovdb.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/raster.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/raster.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/texture.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/io/texture.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/astronomy.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/astronomy.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/atmosphere.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/atmosphere.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/cloud.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/cloud.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/constants.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/reflectance_library.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/reflectance_library.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/reflectance_table.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/regolith.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/regolith.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/scattering.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/scattering.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/solar.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/solar.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/solar_table.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/spectrum.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/physics/spectrum.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/python/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/python/ernie/__init__.py +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/python/module.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/render/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/convert.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/extent_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/extent_cache.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/path.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/path.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/camera.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/camera.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/collection.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/collection.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/instancer.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/instancer.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/laser.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/laser.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/lux.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/lux.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/planet.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/planet.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/render.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/render.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/shade.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/vol.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/vol.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/storage.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/value.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/view.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/view.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/xform.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/scene/xform.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/algorithm.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/bytes.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/disk_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/disk_cache.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/file.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/file.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/glm.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/hash_index.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/linear_algebra.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/log.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/log.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/math.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/noise.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/noise.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/numbers.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/parallel.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/profiler.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/profiler.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/random.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/tensor.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/tensor.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/text.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/version.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/version.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/ernie/util/worker_pool.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/mkdocs.yml +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/pyproject.toml +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/common.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/consumer/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/consumer/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/device/vulkan_devices_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/make_exr.py +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/rgba_half_window.exr +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/y_half_zips.exr +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/lamp.tilt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/images/grey16.png +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/float_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/volumes/cube.nvdb +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/fixtures/volumes/make_nvdb.py +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/geometry/bounds_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/io/ies_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/io/image_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/io/nanovdb_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/io/raster_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/io/texture_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/astronomy_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/atmosphere_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/cloud_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/reflectance_library_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/regolith_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/scattering_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/solar_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/physics/spectrum_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/python/test_package.py +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/api_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/instancer_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/lux_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/path_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/planet_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/render_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/scene_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/shade_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/storage_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/scene/xform_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/algorithm_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/bytes_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/disk_cache_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/file_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/hash_index_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/linear_algebra_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/log_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/math_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/noise_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/parallel_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/profiler_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/random_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/tensor_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/text_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/version_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/tests/util/worker_pool_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSES/MIT.txt +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/NOTICE +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/README.md +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_containers.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_idct.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/zstd/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/zstd/zstd.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/basisu/zstd/zstd_errors.h +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/third_party/nanovdb/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev37 → ernie_renderer-0.2.0.dev43}/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 ".dev43" 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.dev43
|
|
4
4
|
Summary: Efficient Renderer for Natural and Interplanetary Environments: a physically based, spectral Vulkan ray tracer
|
|
5
5
|
Author: Alex Maietta
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
2
|
/// @file extents.cpp
|
|
3
|
-
/// @brief
|
|
3
|
+
/// @brief Scene updates at 100,000 prims: the first, one edit's, and one inherited edit's.
|
|
4
4
|
#include "benchmarks/bench.h"
|
|
5
5
|
#include "ernie/scene/schemas/geom.h"
|
|
6
6
|
|
|
@@ -21,20 +21,35 @@ std::unique_ptr<Scene> MakeSpheres() {
|
|
|
21
21
|
return scene;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const bool kFirstUpdate = Register("scene.
|
|
24
|
+
const bool kFirstUpdate = Register("scene.update.first_100k", [] {
|
|
25
25
|
std::unique_ptr<Scene> scene;
|
|
26
|
-
return Timing{Fastest([&] { scene = MakeSpheres(); }, [&] { scene->
|
|
26
|
+
return Timing{Fastest([&] { scene = MakeSpheres(); }, [&] { scene->Update(); }), 10.0};
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
const bool kOneEdit = Register("scene.
|
|
29
|
+
const bool kOneEdit = Register("scene.update.after_one_edit_of_100k", [] {
|
|
30
30
|
std::unique_ptr<Scene> scene = MakeSpheres();
|
|
31
|
-
scene->
|
|
31
|
+
scene->Update();
|
|
32
32
|
const PrimId ball = *scene->Find("/World/Ball_54321");
|
|
33
33
|
double radius = 1.0;
|
|
34
34
|
const double ms = Fastest([&] { scene->Set(ball, Sphere::kRadius, radius += 1.0); },
|
|
35
|
-
[&] { scene->
|
|
35
|
+
[&] { scene->Update(); });
|
|
36
36
|
return Timing{ms, 1.0};
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
+
const bool kInheritedEdit = Register("scene.update.after_hiding_the_parent_of_100k", [] {
|
|
40
|
+
std::unique_ptr<Scene> scene = MakeSpheres();
|
|
41
|
+
scene->Define("/World", "Xform");
|
|
42
|
+
scene->Update();
|
|
43
|
+
const PrimId world = *scene->Find("/World");
|
|
44
|
+
bool hidden = false;
|
|
45
|
+
const double ms = Fastest(
|
|
46
|
+
[&] {
|
|
47
|
+
hidden = !hidden;
|
|
48
|
+
scene->Set(world, Imageable::kVisibility, hidden ? "invisible" : "inherited");
|
|
49
|
+
},
|
|
50
|
+
[&] { scene->Update(); });
|
|
51
|
+
return Timing{ms, 10.0};
|
|
52
|
+
});
|
|
53
|
+
|
|
39
54
|
} // namespace
|
|
40
55
|
} // namespace ernie::bench
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file holder_index.cpp
|
|
3
|
+
/// @brief Re-indexing changed relationship cells, and finding a target's live holders.
|
|
4
|
+
#include "ernie/scene/holder_index.h"
|
|
5
|
+
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
#include <unordered_set>
|
|
8
|
+
|
|
9
|
+
namespace ernie {
|
|
10
|
+
namespace {
|
|
11
|
+
|
|
12
|
+
bool IsRelationship(ColumnType type) {
|
|
13
|
+
return type == ColumnType::Relationship || type == ColumnType::Relationships;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/// @return The targets of a relationship cell, without the unset one.
|
|
17
|
+
std::vector<PathId> Targets(const PrimStore& store, BucketId bucket, const Column& column,
|
|
18
|
+
std::uint32_t row) {
|
|
19
|
+
std::vector<PathId> targets;
|
|
20
|
+
if (column.values->Type() == ColumnType::Relationship) {
|
|
21
|
+
targets.push_back(store.Read<Target>(bucket, column.attribute)[row].path);
|
|
22
|
+
} else {
|
|
23
|
+
for (const Target target : store.Read<std::vector<Target>>(bucket, column.attribute)[row]) {
|
|
24
|
+
targets.push_back(target.path);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
std::erase(targets, kNoPath);
|
|
28
|
+
return targets;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} // namespace
|
|
32
|
+
|
|
33
|
+
void HolderIndex::Update(const PrimStore& store) {
|
|
34
|
+
const ChangeSet changes = store.ChangesSince(cursor_);
|
|
35
|
+
for (const ChangeSet::Values& values : changes.values) {
|
|
36
|
+
const Bucket& bucket = store.GetBucket(values.bucket);
|
|
37
|
+
const Column& column = *bucket.Find(values.attribute);
|
|
38
|
+
if (!IsRelationship(column.values->Type())) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
for (const RowRange range : values.rows) {
|
|
42
|
+
for (std::uint32_t row = range.begin; row < std::min(range.end, bucket.Rows()); ++row) {
|
|
43
|
+
Index(bucket.prims[row], values.attribute,
|
|
44
|
+
Targets(store, values.bucket, column, row));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// A bucket too far behind to replay reports every row of every column, as a fresh one does.
|
|
49
|
+
for (const BucketId id : changes.resets) {
|
|
50
|
+
const Bucket& bucket = store.GetBucket(id);
|
|
51
|
+
for (const Column& column : bucket.columns) {
|
|
52
|
+
for (std::uint32_t row = 0;
|
|
53
|
+
IsRelationship(column.values->Type()) && row < bucket.Rows(); ++row) {
|
|
54
|
+
Index(bucket.prims[row], column.attribute, Targets(store, id, column, row));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
cursor_ = changes.version;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void HolderIndex::Index(PrimId prim, AttributeId attribute, std::vector<PathId> targets) {
|
|
62
|
+
const Cell cell = Key(prim, attribute);
|
|
63
|
+
const auto found = targets_.find(cell);
|
|
64
|
+
if (found != targets_.end()) {
|
|
65
|
+
for (const PathId old : found->second) {
|
|
66
|
+
holders_[old].erase(cell);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const PathId target : targets) {
|
|
70
|
+
holders_[target][cell] = prim.generation;
|
|
71
|
+
}
|
|
72
|
+
if (!targets.empty()) {
|
|
73
|
+
targets_[cell] = std::move(targets);
|
|
74
|
+
} else if (found != targets_.end()) {
|
|
75
|
+
targets_.erase(found);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
std::vector<PrimId> HolderIndex::Find(const PrimStore& store, PathId target) const {
|
|
80
|
+
std::vector<PrimId> found;
|
|
81
|
+
const auto holders = holders_.find(target);
|
|
82
|
+
if (holders == holders_.end()) {
|
|
83
|
+
return found;
|
|
84
|
+
}
|
|
85
|
+
std::unordered_set<std::uint32_t> slots;
|
|
86
|
+
for (const auto& [cell, generation] : holders->second) {
|
|
87
|
+
const PrimId prim{static_cast<std::uint32_t>(cell >> 32), generation};
|
|
88
|
+
// Cells of removed prims, or of prims since moved to a bucket without the attribute, stay
|
|
89
|
+
// until their slot's next prim writes them.
|
|
90
|
+
if (Holds(store, prim, static_cast<AttributeId>(cell), target) &&
|
|
91
|
+
slots.insert(prim.slot).second) {
|
|
92
|
+
found.push_back(prim);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return found;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
bool HolderIndex::Holds(const PrimStore& store, PrimId prim, AttributeId attribute, PathId target) {
|
|
99
|
+
if (!store.Alive(prim)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const BucketId bucket = store.PrimBucket(prim);
|
|
103
|
+
const Column* column = store.GetBucket(bucket).Find(attribute);
|
|
104
|
+
if (column == nullptr || !IsRelationship(column->values->Type())) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const std::vector<PathId> targets = Targets(store, bucket, *column, store.PrimRow(prim));
|
|
108
|
+
return std::ranges::find(targets, target) != targets.end();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
} // namespace ernie
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file holder_index.h
|
|
3
|
+
/// @brief The reverse index of relationships: which prims target each path.
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "ernie/scene/storage.h"
|
|
7
|
+
|
|
8
|
+
#include <cstdint>
|
|
9
|
+
#include <unordered_map>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
namespace ernie {
|
|
13
|
+
|
|
14
|
+
/// @brief Which prims' relationships target each path, kept up to date from the store's changes,
|
|
15
|
+
/// so an edit to a target reaches its holders: a prototype its instancers, a material the prims
|
|
16
|
+
/// bound to it (through their resolved bindings), a body its terrains.
|
|
17
|
+
class HolderIndex {
|
|
18
|
+
public:
|
|
19
|
+
/// Re-indexes the relationship cells that changed since the last update.
|
|
20
|
+
void Update(const PrimStore& store);
|
|
21
|
+
/// @return The live prims with a relationship targeting `target`, each once.
|
|
22
|
+
std::vector<PrimId> Find(const PrimStore& store, PathId target) const;
|
|
23
|
+
|
|
24
|
+
private:
|
|
25
|
+
/// A relationship cell: the prim's slot and the attribute, packed.
|
|
26
|
+
using Cell = std::uint64_t;
|
|
27
|
+
static Cell Key(PrimId prim, AttributeId attribute) {
|
|
28
|
+
return (std::uint64_t{prim.slot} << 32) | attribute;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void Index(PrimId prim, AttributeId attribute, std::vector<PathId> targets);
|
|
32
|
+
/// @return Whether the prim is alive and its relationship still targets `target`.
|
|
33
|
+
static bool Holds(const PrimStore& store, PrimId prim, AttributeId attribute, PathId target);
|
|
34
|
+
|
|
35
|
+
/// Each target's holding cells, with the generation of the prim that wrote them.
|
|
36
|
+
std::unordered_map<PathId, std::unordered_map<Cell, std::uint32_t>> holders_;
|
|
37
|
+
/// Each cell's targets, to unindex them when it changes.
|
|
38
|
+
std::unordered_map<Cell, std::vector<PathId>> targets_;
|
|
39
|
+
std::uint64_t cursor_ = 0;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
} // namespace ernie
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
/// @file inherit.cpp
|
|
3
|
+
/// @brief Resolving inherited attributes from the nearest authoring ancestor into their resolved
|
|
4
|
+
/// columns, for only the subtrees whose authored values or prims changed.
|
|
5
|
+
#include "ernie/scene/convert.h"
|
|
6
|
+
#include "ernie/scene/scene.h"
|
|
7
|
+
|
|
8
|
+
#include <algorithm>
|
|
9
|
+
#include <concepts>
|
|
10
|
+
#include <limits>
|
|
11
|
+
|
|
12
|
+
namespace ernie {
|
|
13
|
+
|
|
14
|
+
void Scene::Resolve() {
|
|
15
|
+
const ChangeSet changes = store_.ChangesSince(resolved_);
|
|
16
|
+
for (const AttributeDef* def : InheritedAttributes()) {
|
|
17
|
+
const AttributeId attribute = store_.Tokens().Intern(def->name);
|
|
18
|
+
const AttributeId resolved = store_.Tokens().Intern(ResolvedName(def->name));
|
|
19
|
+
WithColumnType(def->type, [&]<typename T>(std::type_identity<T>) {
|
|
20
|
+
if constexpr (std::equality_comparable<T> && !std::same_as<T, Tensor>) {
|
|
21
|
+
const T fallback = ToElement<T>(store_.Paths(), def->fallback).value_or(T{});
|
|
22
|
+
BitSet roots = ResolveRoots(changes, attribute);
|
|
23
|
+
std::vector<PathId> order;
|
|
24
|
+
roots.ForEachRun([&](std::size_t begin, std::size_t end) {
|
|
25
|
+
for (std::size_t path = begin; path < end; ++path) {
|
|
26
|
+
order.push_back(static_cast<PathId>(path));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// Ancestors intern first, so most roots are reached from one above them.
|
|
30
|
+
for (const PathId root : order) {
|
|
31
|
+
if (roots.Test(root)) {
|
|
32
|
+
ResolveSubtree<T>(root, attribute, resolved, fallback, roots);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
// Its own writes are to resolved columns, which no resolve reads.
|
|
39
|
+
resolved_ = store_.Version();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
BitSet Scene::ResolveRoots(const ChangeSet& changes, AttributeId attribute) const {
|
|
43
|
+
BitSet roots;
|
|
44
|
+
roots.Resize(store_.Paths().Size());
|
|
45
|
+
const auto add = [&](BucketId bucket, std::uint32_t begin, std::uint32_t end) {
|
|
46
|
+
const Bucket& rows = store_.GetBucket(bucket);
|
|
47
|
+
for (std::uint32_t row = begin; row < std::min(end, rows.Rows()); ++row) {
|
|
48
|
+
roots.Set(store_.PrimPath(rows.prims[row]));
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
for (const BucketId bucket : changes.resets) {
|
|
52
|
+
add(bucket, 0, std::numeric_limits<std::uint32_t>::max());
|
|
53
|
+
}
|
|
54
|
+
for (const ChangeSet::Rows& rows : changes.rows) {
|
|
55
|
+
if (rows.change.kind == StructuralChange::Kind::Added) {
|
|
56
|
+
add(rows.bucket, rows.change.row, rows.change.row + rows.change.count);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (const ChangeSet::Values& values : changes.values) {
|
|
60
|
+
if (values.attribute == attribute) {
|
|
61
|
+
for (const RowRange range : values.rows) {
|
|
62
|
+
add(values.bucket, range.begin, range.end);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return roots;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
template <typename T> const T* Scene::Inheritable(PrimId prim, AttributeId attribute) const {
|
|
70
|
+
const BucketId bucket = store_.PrimBucket(prim);
|
|
71
|
+
const Column* column = store_.GetBucket(bucket).Find(attribute);
|
|
72
|
+
const std::uint32_t row = store_.PrimRow(prim);
|
|
73
|
+
if (column == nullptr || !column->authored.Test(row) ||
|
|
74
|
+
column->values->Type() != kColumnType<T>) {
|
|
75
|
+
return nullptr;
|
|
76
|
+
}
|
|
77
|
+
const T* own = &store_.Read<T>(bucket, attribute)[row];
|
|
78
|
+
if constexpr (std::same_as<T, Token>) {
|
|
79
|
+
return *own == inherited_ ? nullptr : own;
|
|
80
|
+
}
|
|
81
|
+
return own;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
template <typename T> T Scene::Above(PathId path, AttributeId attribute, const T& fallback) const {
|
|
85
|
+
const PathTable& paths = store_.Paths();
|
|
86
|
+
for (PathId above = paths.Parent(path); above != kRootPath; above = paths.Parent(above)) {
|
|
87
|
+
const std::optional<PrimId> prim = store_.Find(above);
|
|
88
|
+
if (const T* own = prim ? Inheritable<T>(*prim, attribute) : nullptr) {
|
|
89
|
+
return *own;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return fallback;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
template <typename T>
|
|
96
|
+
void Scene::ResolveSubtree(PathId root, AttributeId attribute, AttributeId resolved,
|
|
97
|
+
const T& fallback, BitSet& roots) {
|
|
98
|
+
std::vector<std::pair<PathId, T>> pending{{root, Above<T>(root, attribute, fallback)}};
|
|
99
|
+
while (!pending.empty()) {
|
|
100
|
+
const auto [path, above] = std::move(pending.back());
|
|
101
|
+
pending.pop_back();
|
|
102
|
+
const std::optional<PrimId> prim = store_.Find(path);
|
|
103
|
+
if (!prim) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const bool isRoot = roots.Test(path);
|
|
107
|
+
roots.Set(path, false);
|
|
108
|
+
const T* own = Inheritable<T>(*prim, attribute);
|
|
109
|
+
const T value = own != nullptr ? *own : above;
|
|
110
|
+
// Prims without the column (typeless ones, materials) pass the value through.
|
|
111
|
+
const bool stored = store_.GetBucket(store_.PrimBucket(*prim)).Find(resolved) != nullptr;
|
|
112
|
+
// An unchanged prim's descendants are unchanged too, unless they are roots themselves.
|
|
113
|
+
if (store_.Derive(*prim, resolved, value) || isRoot || !stored) {
|
|
114
|
+
store_.Paths().ForEachChild(path,
|
|
115
|
+
[&](PathId child) { pending.emplace_back(child, value); });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
} // namespace ernie
|
|
@@ -38,7 +38,8 @@ std::string Describe(const Scene& scene, PrimId prim) {
|
|
|
38
38
|
} // namespace
|
|
39
39
|
|
|
40
40
|
Scene::Scene()
|
|
41
|
-
:
|
|
41
|
+
: inherited_(store_.Tokens().Intern(tokens::kInherited)),
|
|
42
|
+
invisible_(store_.Tokens().Intern(tokens::kInvisible)),
|
|
42
43
|
defaultPurpose_(store_.Tokens().Intern(tokens::kDefault)) {
|
|
43
44
|
FindOrAddBucket(nullptr, {});
|
|
44
45
|
}
|
|
@@ -170,15 +171,20 @@ void Scene::Write(PrimId prim, std::string_view attribute, Tensor array) {
|
|
|
170
171
|
}
|
|
171
172
|
|
|
172
173
|
const Tensor* Scene::Read(PrimId prim, std::string_view attribute) const {
|
|
173
|
-
|
|
174
|
-
if (column == nullptr || column->values->Type() != ColumnType::Tensor) {
|
|
175
|
-
return nullptr;
|
|
176
|
-
}
|
|
177
|
-
return &store_.Read<Tensor>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
|
|
174
|
+
return Authored<Tensor>(prim, attribute);
|
|
178
175
|
}
|
|
179
176
|
|
|
180
177
|
std::optional<Value> Scene::Get(PrimId prim, std::string_view attribute) const {
|
|
181
|
-
|
|
178
|
+
return CellValue(prim, AuthoredColumn(prim, attribute));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
std::optional<Value> Scene::GetResolved(PrimId prim, std::string_view attribute) const {
|
|
182
|
+
const std::optional<Token> token = store_.Tokens().Find(ResolvedName(attribute));
|
|
183
|
+
return CellValue(prim,
|
|
184
|
+
token ? store_.GetBucket(store_.PrimBucket(prim)).Find(*token) : nullptr);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
std::optional<Value> Scene::CellValue(PrimId prim, const Column* column) const {
|
|
182
188
|
if (column == nullptr) {
|
|
183
189
|
return std::nullopt;
|
|
184
190
|
}
|
|
@@ -248,6 +254,11 @@ std::optional<Box> Scene::Extent(PrimId prim) const {
|
|
|
248
254
|
return extent;
|
|
249
255
|
}
|
|
250
256
|
|
|
257
|
+
std::vector<PrimId> Scene::Holders(const Path& target) const {
|
|
258
|
+
const std::optional<PathId> id = store_.Paths().Find(target);
|
|
259
|
+
return id ? holders_.Find(store_, *id) : std::vector<PrimId>{};
|
|
260
|
+
}
|
|
261
|
+
|
|
251
262
|
Box Scene::WorldBounds(const Path& path) const {
|
|
252
263
|
const PrimId prim = Require(path);
|
|
253
264
|
const PathId id = store_.PrimPath(prim);
|
|
@@ -277,11 +288,17 @@ void Scene::AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visib
|
|
|
277
288
|
bounds.Extend(extent->Transformed(world));
|
|
278
289
|
return;
|
|
279
290
|
}
|
|
291
|
+
bool loaded = false;
|
|
280
292
|
store_.Paths().ForEachChild(path, [&](PathId child) {
|
|
281
293
|
if (store_.Find(child)) {
|
|
294
|
+
loaded = true;
|
|
282
295
|
AddTo(bounds, child, world, visibleOnly);
|
|
283
296
|
}
|
|
284
297
|
});
|
|
298
|
+
// A model whose subtree isn't loaded is bounded by its hint.
|
|
299
|
+
if (!loaded) {
|
|
300
|
+
bounds.Extend(ExtentsHint(prim, !visibleOnly).Transformed(world));
|
|
301
|
+
}
|
|
285
302
|
}
|
|
286
303
|
|
|
287
304
|
PrimId Scene::Require(const Path& path) const {
|
|
@@ -323,6 +340,11 @@ BucketId Scene::FindOrAddBucket(const SchemaDef* schema, std::vector<Token> apis
|
|
|
323
340
|
for (const ApiName& api : allApis) {
|
|
324
341
|
add(*api.schema, api);
|
|
325
342
|
}
|
|
343
|
+
if (schema != nullptr && schema->IsA(Imageable::Definition())) {
|
|
344
|
+
for (const AttributeDef* def : InheritedAttributes()) {
|
|
345
|
+
layout.push_back(MakeLayout(paths, *def, ResolvedName(def->name), def->fallback));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
326
348
|
const BucketId bucket = store_.AddBucket(key, layout);
|
|
327
349
|
buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
|
|
328
350
|
buckets_[bucket] = std::move(entry);
|
|
@@ -400,15 +422,24 @@ std::vector<std::string> Scene::AppliedApis(PrimId prim) const {
|
|
|
400
422
|
}
|
|
401
423
|
|
|
402
424
|
bool Scene::LeavesOutOfBounds(PrimId prim) const {
|
|
403
|
-
const
|
|
404
|
-
const Column* column = AuthoredColumn(prim, attribute);
|
|
405
|
-
return column ? std::optional(store_.Read<Token>(store_.PrimBucket(prim),
|
|
406
|
-
column->attribute)[store_.PrimRow(prim)])
|
|
407
|
-
: std::nullopt;
|
|
408
|
-
};
|
|
425
|
+
const Token* visibility = Authored<Token>(prim, Imageable::kVisibility);
|
|
409
426
|
// Purpose is inherited, so a subtree under another purpose is left out whole.
|
|
410
|
-
const
|
|
411
|
-
return
|
|
427
|
+
const Token* purpose = Authored<Token>(prim, Imageable::kPurpose);
|
|
428
|
+
return (visibility && *visibility == invisible_) || (purpose && *purpose != defaultPurpose_);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
Box Scene::ExtentsHint(PrimId prim, bool allPurposes) const {
|
|
432
|
+
const auto* hint = Authored<std::vector<float>>(prim, GeomModelAPI::kExtentsHint);
|
|
433
|
+
if (hint == nullptr) {
|
|
434
|
+
return {};
|
|
435
|
+
}
|
|
436
|
+
// Six floats per purpose, the default purpose first.
|
|
437
|
+
const std::size_t floats = allPurposes ? hint->size() : std::min<std::size_t>(6, hint->size());
|
|
438
|
+
Box box;
|
|
439
|
+
for (std::size_t i = 0; i + 6 <= floats; i += 6) {
|
|
440
|
+
box.Extend(AuthoredExtent(std::span(*hint).subspan(i, 6)));
|
|
441
|
+
}
|
|
442
|
+
return box;
|
|
412
443
|
}
|
|
413
444
|
|
|
414
445
|
const Column* Scene::AuthoredColumn(PrimId prim, std::string_view attribute) const {
|
|
@@ -428,12 +459,18 @@ Dirty Scene::Classify(const ChangeSet::Values& change) const {
|
|
|
428
459
|
return def->meta.dirty;
|
|
429
460
|
}
|
|
430
461
|
const std::string_view name = store_.Tokens().Text(change.attribute);
|
|
462
|
+
if (name.starts_with(tokens::kResolvedPrefix)) {
|
|
463
|
+
return FindInherited(name.substr(tokens::kResolvedPrefix.size()))->meta.dirty;
|
|
464
|
+
}
|
|
431
465
|
return name.starts_with(tokens::kXformOpPrefix) ? Dirty::Transform
|
|
432
466
|
: name.starts_with(tokens::kPrimvarsPrefix) ? Dirty::Primvars
|
|
433
467
|
: Dirty::Params;
|
|
434
468
|
}
|
|
435
469
|
|
|
436
470
|
bool Scene::TakesUndeclared(PrimId prim, std::string_view attribute) const {
|
|
471
|
+
if (attribute.starts_with(tokens::kResolvedPrefix)) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
437
474
|
const SchemaDef* schema = Schema(prim);
|
|
438
475
|
return schema == nullptr || schema->IsOpen(attribute) ||
|
|
439
476
|
std::ranges::any_of(AllApis(schema, Apis(prim)),
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
#include "ernie/geometry/bounds.h"
|
|
7
7
|
#include "ernie/scene/extent_cache.h"
|
|
8
|
+
#include "ernie/scene/holder_index.h"
|
|
8
9
|
#include "ernie/scene/schema.h"
|
|
9
10
|
#include "ernie/scene/storage.h"
|
|
10
11
|
#include "ernie/scene/value.h"
|
|
@@ -68,6 +69,10 @@ class Scene {
|
|
|
68
69
|
/// @return The authored value, or none.
|
|
69
70
|
std::optional<Value> Get(PrimId prim, std::string_view attribute) const;
|
|
70
71
|
std::optional<Value> Get(const Path& path, std::string_view attribute) const;
|
|
72
|
+
/// @return An inherited attribute's value as of the last `Update`: the prim's own or its
|
|
73
|
+
/// nearest authoring ancestor's (where "inherited" isn't authoring), else the fallback; none
|
|
74
|
+
/// for a prim that isn't Imageable.
|
|
75
|
+
std::optional<Value> GetResolved(PrimId prim, std::string_view attribute) const;
|
|
71
76
|
/// @brief Authors an array attribute with a tensor on the host or a device, shared, not copied.
|
|
72
77
|
/// @throws std::invalid_argument for a non-array attribute, or a tensor of the wrong type or
|
|
73
78
|
/// shape.
|
|
@@ -84,12 +89,20 @@ class Scene {
|
|
|
84
89
|
glm::dmat4 LocalTransform(PrimId prim) const;
|
|
85
90
|
glm::dmat4 WorldTransform(PrimId prim) const;
|
|
86
91
|
/// @return The prim's extent in its own space; none when it isn't computed from attributes.
|
|
87
|
-
/// Cached since `
|
|
92
|
+
/// Cached since `Update` when its bucket hasn't changed, computed otherwise.
|
|
88
93
|
std::optional<Box> Extent(PrimId prim) const;
|
|
89
|
-
/// @brief
|
|
90
|
-
|
|
94
|
+
/// @brief Brings derived data up to date with the edits since the last update, once per step
|
|
95
|
+
/// before renderers pull changes: resolves inherited attributes for the subtrees whose
|
|
96
|
+
/// authored values or prims changed, re-indexes changed relationships, then recomputes the
|
|
97
|
+
/// changed rows' cached extents.
|
|
98
|
+
void Update() {
|
|
99
|
+
Resolve();
|
|
100
|
+
holders_.Update(store_);
|
|
91
101
|
extents_.Update(store_);
|
|
92
102
|
}
|
|
103
|
+
/// @return The prims whose relationships target `target` as of the last `Update`, resolved
|
|
104
|
+
/// material bindings included: what an edit to `target` reaches.
|
|
105
|
+
std::vector<PrimId> Holders(const Path& target) const;
|
|
93
106
|
/// @return The world box of the prim and its visible descendants of the default purpose.
|
|
94
107
|
/// Prims with extents bound their own subtrees, as UsdGeomBBoxCache prunes at Boundables.
|
|
95
108
|
Box WorldBounds(const Path& path) const;
|
|
@@ -126,6 +139,31 @@ class Scene {
|
|
|
126
139
|
std::vector<ApiName> AllApis(const SchemaDef* schema, std::span<const Token> applied) const;
|
|
127
140
|
/// @return The attribute's column when the prim authors it, or null.
|
|
128
141
|
const Column* AuthoredColumn(PrimId prim, std::string_view attribute) const;
|
|
142
|
+
/// @return The attribute's value when the prim authors it as a `T`, or null.
|
|
143
|
+
template <typename T> const T* Authored(PrimId prim, std::string_view attribute) const {
|
|
144
|
+
const Column* column = AuthoredColumn(prim, attribute);
|
|
145
|
+
if (column == nullptr || column->values->Type() != kColumnType<T>) {
|
|
146
|
+
return nullptr;
|
|
147
|
+
}
|
|
148
|
+
return &store_.Read<T>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
|
|
149
|
+
}
|
|
150
|
+
std::optional<Value> CellValue(PrimId prim, const Column* column) const;
|
|
151
|
+
|
|
152
|
+
/// Resolves every inherited attribute for the subtrees changed since the last resolve.
|
|
153
|
+
void Resolve();
|
|
154
|
+
/// @return The paths of the prims whose subtrees resolve `attribute` again: those added, reset
|
|
155
|
+
/// or with it changed.
|
|
156
|
+
BitSet ResolveRoots(const ChangeSet& changes, AttributeId attribute) const;
|
|
157
|
+
/// @return What `attribute` resolves to from the prim's own value: null when it doesn't
|
|
158
|
+
/// author it, or authors "inherited".
|
|
159
|
+
template <typename T> const T* Inheritable(PrimId prim, AttributeId attribute) const;
|
|
160
|
+
/// @return The value `path` inherits from its ancestors.
|
|
161
|
+
template <typename T> T Above(PathId path, AttributeId attribute, const T& fallback) const;
|
|
162
|
+
/// Resolves `attribute` over the subtree at `root`, descending past a prim only while its
|
|
163
|
+
/// resolved value changes or it is one of `roots`, which it clears as it reaches them.
|
|
164
|
+
template <typename T>
|
|
165
|
+
void ResolveSubtree(PathId root, AttributeId attribute, AttributeId resolved, const T& fallback,
|
|
166
|
+
BitSet& roots);
|
|
129
167
|
const AttributeDef* Declared(BucketId bucket, AttributeId attribute) const;
|
|
130
168
|
/// @return Whether the prim's type or an applied API schema leaves the attribute's namespace
|
|
131
169
|
/// open; any attribute for a prim without a type.
|
|
@@ -133,15 +171,21 @@ class Scene {
|
|
|
133
171
|
ColumnType TypeForUndeclared(PrimId prim, std::string_view attribute, const Value& value) const;
|
|
134
172
|
/// @return Whether the prim and its subtree are invisible or of a purpose bounds leave out.
|
|
135
173
|
bool LeavesOutOfBounds(PrimId prim) const;
|
|
174
|
+
/// @return GeomModelAPI's extentsHint: the default purpose's box, or with `allPurposes`, all.
|
|
175
|
+
Box ExtentsHint(PrimId prim, bool allPurposes) const;
|
|
136
176
|
/// Adds a subtree's extents under `parent`'s transform; with `visibleOnly`, only its visible
|
|
137
177
|
/// default-purpose prims'.
|
|
138
178
|
void AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visibleOnly) const;
|
|
139
179
|
|
|
140
180
|
PrimStore store_;
|
|
181
|
+
/// The store version inherited attributes were last resolved at.
|
|
182
|
+
std::uint64_t resolved_ = 0;
|
|
183
|
+
Token inherited_ = 0;
|
|
141
184
|
Token invisible_ = 0;
|
|
142
185
|
Token defaultPurpose_ = 0;
|
|
143
186
|
std::vector<BucketSchema> buckets_;
|
|
144
187
|
ExtentCache extents_;
|
|
188
|
+
HolderIndex holders_;
|
|
145
189
|
};
|
|
146
190
|
|
|
147
191
|
} // namespace ernie
|
|
@@ -175,6 +175,28 @@ const SchemaDef* FindSchema(std::string_view name) {
|
|
|
175
175
|
return found != schemas.end() ? *found : nullptr;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
std::span<const AttributeDef* const> InheritedAttributes() {
|
|
179
|
+
static const std::vector<const AttributeDef*> kInherited = [] {
|
|
180
|
+
std::vector<const AttributeDef*> inherited;
|
|
181
|
+
for (const SchemaDef* schema : Schemas()) {
|
|
182
|
+
for (const AttributeDef& def : schema->attributes) {
|
|
183
|
+
if (def.meta.inherited) {
|
|
184
|
+
inherited.push_back(&def);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return inherited;
|
|
189
|
+
}();
|
|
190
|
+
return kInherited;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const AttributeDef* FindInherited(std::string_view name) {
|
|
194
|
+
const std::span<const AttributeDef* const> inherited = InheritedAttributes();
|
|
195
|
+
const auto found =
|
|
196
|
+
std::ranges::find_if(inherited, [&](const AttributeDef* def) { return def->name == name; });
|
|
197
|
+
return found != inherited.end() ? *found : nullptr;
|
|
198
|
+
}
|
|
199
|
+
|
|
178
200
|
ApiName ApiName::Parse(std::string_view api) {
|
|
179
201
|
const std::size_t colon = api.find(':');
|
|
180
202
|
const std::string_view name = api.substr(0, colon);
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
#include "ernie/geometry/bounds.h"
|
|
7
7
|
#include "ernie/scene/storage.h"
|
|
8
|
+
#include "ernie/scene/tokens.h"
|
|
8
9
|
#include "ernie/scene/value.h"
|
|
9
10
|
|
|
10
11
|
#include <array>
|
|
11
12
|
#include <cstdint>
|
|
12
13
|
#include <optional>
|
|
13
14
|
#include <span>
|
|
15
|
+
#include <string>
|
|
14
16
|
#include <string_view>
|
|
15
17
|
#include <vector>
|
|
16
18
|
|
|
@@ -87,7 +89,8 @@ struct AttributeMeta {
|
|
|
87
89
|
/// The ranks a tensor may have, as a dense grid's 3; none for flat or vector arrays.
|
|
88
90
|
std::vector<std::int64_t> ranks{};
|
|
89
91
|
Dirty dirty = Dirty::Params;
|
|
90
|
-
/// Resolved from the nearest authoring
|
|
92
|
+
/// Resolved from the nearest ancestor authoring it (other than as "inherited") into its
|
|
93
|
+
/// `ResolvedName` column.
|
|
91
94
|
bool inherited = false;
|
|
92
95
|
};
|
|
93
96
|
|
|
@@ -234,6 +237,15 @@ struct SchemaDef {
|
|
|
234
237
|
std::span<const SchemaDef* const> Schemas();
|
|
235
238
|
/// @return The schema named `name`, or null.
|
|
236
239
|
const SchemaDef* FindSchema(std::string_view name);
|
|
240
|
+
/// @return Every attribute declared inherited, once each.
|
|
241
|
+
std::span<const AttributeDef* const> InheritedAttributes();
|
|
242
|
+
/// @return The inherited attribute named `name`, or null.
|
|
243
|
+
const AttributeDef* FindInherited(std::string_view name);
|
|
244
|
+
/// @return The column holding an inherited attribute's resolved values:
|
|
245
|
+
/// `ernie:resolved:visibility`.
|
|
246
|
+
inline std::string ResolvedName(std::string_view attribute) {
|
|
247
|
+
return std::string(tokens::kResolvedPrefix) + std::string(attribute);
|
|
248
|
+
}
|
|
237
249
|
|
|
238
250
|
/// What a multiple-apply schema's attribute names hold in place of the instance's name.
|
|
239
251
|
inline constexpr std::string_view kInstanceName = "__INSTANCE_NAME__";
|
|
@@ -60,6 +60,8 @@ ERNIE_DEFINE_SCHEMA(Xform, Concrete, kDescendantsExtent, ERNIE_NO_ATTRIBUTES,
|
|
|
60
60
|
.openNamespaces = {"*"})
|
|
61
61
|
ERNIE_DEFINE_SCHEMA(Scope, Concrete, kDescendantsExtent, ERNIE_NO_ATTRIBUTES,
|
|
62
62
|
.openNamespaces = {"*"})
|
|
63
|
+
ERNIE_DEFINE_SCHEMA(GeomModelAPI, SingleApply, kInheritExtent, ERNIE_MODEL_API_ATTRIBUTES)
|
|
64
|
+
ERNIE_DEFINE_SCHEMA(GeomSubset, Concrete, kNoExtent, ERNIE_SUBSET_ATTRIBUTES)
|
|
63
65
|
ERNIE_DEFINE_SCHEMA(Cube, Concrete, ComputedExtent(CentredExtent<CubeHalves>),
|
|
64
66
|
ERNIE_CUBE_ATTRIBUTES)
|
|
65
67
|
ERNIE_DEFINE_SCHEMA(Sphere, Concrete, ComputedExtent(CentredExtent<SphereHalves>),
|