ernie-renderer 0.2.0.dev40__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.dev40 → ernie_renderer-0.2.0.dev43}/CMakeLists.txt +1 -1
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/PKG-INFO +1 -1
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/benchmarks/scene/extents.cpp +21 -6
- {ernie_renderer-0.2.0.dev40 → 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.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/scene.cpp +28 -10
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/scene.h +44 -4
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schema.cpp +22 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schema.h +13 -1
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/geom.h +4 -4
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/shade.h +1 -1
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/storage.h +19 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/tokens.h +2 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/CMakeLists.txt +2 -0
- {ernie_renderer-0.2.0.dev40 → 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.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/vol_test.cpp +1 -1
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.clang-format +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.clang-tidy +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.dockerignore +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.gersemirc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.gitattributes +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.github/scripts/coverage_badge.py +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.github/scripts/install-lavapipe-windows.sh +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.github/workflows/ci.yml +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.gitignore +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/.pre-commit-config.yaml +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/CMakePresets.json +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/Dockerfile +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/benchmarks/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/benchmarks/bench.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/benchmarks/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/benchmarks/scene/storage.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/ErnieConfig.cmake.in +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/ErnieFetch.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/ErnieInstall.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/ErniePackaging.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/ErnieTesting.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/ernie.pc.in +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/bc7enc.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/dlpack.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/glm.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/googletest.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/json.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/nanobind.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/openexr.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/stb.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/tracy.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/volk.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/cmake/third_party/vulkan_headers.cmake +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/docs/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/docs/index.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/docs/requirements.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/app/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/app/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/device/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/device/vulkan_devices.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/device/vulkan_devices.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/geometry/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/geometry/bounds.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/graph/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/ies.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/ies.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/image.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/image.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/nanovdb.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/nanovdb.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/raster.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/raster.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/texture.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/io/texture.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/astronomy.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/astronomy.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/atmosphere.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/atmosphere.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/cloud.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/cloud.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/constants.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/reflectance_library.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/reflectance_library.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/reflectance_table.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/regolith.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/regolith.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/scattering.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/scattering.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/solar.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/solar.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/solar_table.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/spectrum.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/physics/spectrum.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/python/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/python/ernie/__init__.py +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/python/module.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/render/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/convert.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/extent_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/extent_cache.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/path.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/path.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/camera.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/camera.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/collection.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/collection.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/geom.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/instancer.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/instancer.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/laser.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/laser.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/lux.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/lux.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/mesh.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/mesh.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/planet.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/planet.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/registry.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/render.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/render.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/shade.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/vol.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/schemas/vol.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/storage.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/value.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/view.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/view.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/xform.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/scene/xform.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/algorithm.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/bytes.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/disk_cache.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/disk_cache.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/file.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/file.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/glm.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/hash_index.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/linear_algebra.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/log.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/log.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/math.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/noise.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/noise.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/numbers.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/parallel.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/profiler.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/profiler.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/random.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/tensor.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/tensor.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/text.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/version.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/version.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/ernie/util/worker_pool.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/mkdocs.yml +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/pyproject.toml +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/common.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/consumer/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/consumer/main.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/device/vulkan_devices_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/make_exr.py +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/rgb_float_zip.exr +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/rgba_half_window.exr +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/exr/y_half_zips.exr +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/downlight_quadrant.ies +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/floodlight_type_b.ies +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ies/lamp.tilt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/images/grey16.png +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/quadrants_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/quadrants_uastc_zstd.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/tilted_normal_etc1s.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/ktx2/tilted_normal_uastc.ktx2 +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/float_deflate_predictor3.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/float_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/int16_bigtiff_bigendian.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_lzw_predictor2.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_planar_lzw.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_planar_raw.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/tiff/rgb_tiled_deflate.tif +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/volumes/cube.nvdb +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/fixtures/volumes/make_nvdb.py +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/geometry/bounds_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/io/ies_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/io/image_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/io/nanovdb_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/io/raster_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/io/texture_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/astronomy_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/atmosphere_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/cloud_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/reflectance_library_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/regolith_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/scattering_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/solar_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/physics/spectrum_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/python/test_package.py +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/api_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/instancer_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/lux_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/mesh_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/path_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/planet_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/render_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/scene_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/schema_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/shade_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/storage_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/scene/xform_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/algorithm_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/bytes_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/disk_cache_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/file_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/hash_index_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/linear_algebra_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/log_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/math_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/noise_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/parallel_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/profiler_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/random_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/tensor_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/text_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/version_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/tests/util/worker_pool_test.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/CMakeLists.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSES/Apache-2.0.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSES/BSD-3-clause.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/LICENSES/MIT.txt +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/NOTICE +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/README.md +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_astc_cfgs.inl +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_astc_hdr_core.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_astc_helpers.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_containers.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_containers_impl.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_dds_transcoder.inl +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_etc1_mods.inl +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_file_headers.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_idct.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder.cpp +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_internal.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_astc.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_astc_0_255.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_55.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_atc_56.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_alpha.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_bc7_m5_color.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_5.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_dxt1_6.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_45.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_tables_pvrtc2_alpha_33.inc +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_transcoder_uastc.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_xbc7_decoder.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/transcoder/basisu_xbc7_decoder.inl +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/zstd/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/zstd/zstd.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/basisu/zstd/zstd_errors.h +0 -0
- {ernie_renderer-0.2.0.dev40 → ernie_renderer-0.2.0.dev43}/third_party/nanovdb/LICENSE +0 -0
- {ernie_renderer-0.2.0.dev40 → 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
|
}
|
|
@@ -169,20 +170,21 @@ void Scene::Write(PrimId prim, std::string_view attribute, Tensor array) {
|
|
|
169
170
|
store_.Set(prim, token, std::move(array));
|
|
170
171
|
}
|
|
171
172
|
|
|
172
|
-
template <typename T> const T* Scene::Authored(PrimId prim, std::string_view attribute) const {
|
|
173
|
-
const Column* column = AuthoredColumn(prim, attribute);
|
|
174
|
-
if (column == nullptr || column->values->Type() != kColumnType<T>) {
|
|
175
|
-
return nullptr;
|
|
176
|
-
}
|
|
177
|
-
return &store_.Read<T>(store_.PrimBucket(prim), column->attribute)[store_.PrimRow(prim)];
|
|
178
|
-
}
|
|
179
|
-
|
|
180
173
|
const Tensor* Scene::Read(PrimId prim, std::string_view attribute) const {
|
|
181
174
|
return Authored<Tensor>(prim, attribute);
|
|
182
175
|
}
|
|
183
176
|
|
|
184
177
|
std::optional<Value> Scene::Get(PrimId prim, std::string_view attribute) const {
|
|
185
|
-
|
|
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 {
|
|
186
188
|
if (column == nullptr) {
|
|
187
189
|
return std::nullopt;
|
|
188
190
|
}
|
|
@@ -252,6 +254,11 @@ std::optional<Box> Scene::Extent(PrimId prim) const {
|
|
|
252
254
|
return extent;
|
|
253
255
|
}
|
|
254
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
|
+
|
|
255
262
|
Box Scene::WorldBounds(const Path& path) const {
|
|
256
263
|
const PrimId prim = Require(path);
|
|
257
264
|
const PathId id = store_.PrimPath(prim);
|
|
@@ -333,6 +340,11 @@ BucketId Scene::FindOrAddBucket(const SchemaDef* schema, std::vector<Token> apis
|
|
|
333
340
|
for (const ApiName& api : allApis) {
|
|
334
341
|
add(*api.schema, api);
|
|
335
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
|
+
}
|
|
336
348
|
const BucketId bucket = store_.AddBucket(key, layout);
|
|
337
349
|
buckets_.resize(std::max<std::size_t>(buckets_.size(), bucket + 1));
|
|
338
350
|
buckets_[bucket] = std::move(entry);
|
|
@@ -447,12 +459,18 @@ Dirty Scene::Classify(const ChangeSet::Values& change) const {
|
|
|
447
459
|
return def->meta.dirty;
|
|
448
460
|
}
|
|
449
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
|
+
}
|
|
450
465
|
return name.starts_with(tokens::kXformOpPrefix) ? Dirty::Transform
|
|
451
466
|
: name.starts_with(tokens::kPrimvarsPrefix) ? Dirty::Primvars
|
|
452
467
|
: Dirty::Params;
|
|
453
468
|
}
|
|
454
469
|
|
|
455
470
|
bool Scene::TakesUndeclared(PrimId prim, std::string_view attribute) const {
|
|
471
|
+
if (attribute.starts_with(tokens::kResolvedPrefix)) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
456
474
|
const SchemaDef* schema = Schema(prim);
|
|
457
475
|
return schema == nullptr || schema->IsOpen(attribute) ||
|
|
458
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;
|
|
@@ -127,7 +140,30 @@ class Scene {
|
|
|
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;
|
|
129
142
|
/// @return The attribute's value when the prim authors it as a `T`, or null.
|
|
130
|
-
template <typename T> const T* Authored(PrimId prim, std::string_view attribute) const
|
|
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);
|
|
131
167
|
const AttributeDef* Declared(BucketId bucket, AttributeId attribute) const;
|
|
132
168
|
/// @return Whether the prim's type or an applied API schema leaves the attribute's namespace
|
|
133
169
|
/// open; any attribute for a prim without a type.
|
|
@@ -142,10 +178,14 @@ class Scene {
|
|
|
142
178
|
void AddTo(Box& bounds, PathId path, const glm::dmat4& parent, bool visibleOnly) const;
|
|
143
179
|
|
|
144
180
|
PrimStore store_;
|
|
181
|
+
/// The store version inherited attributes were last resolved at.
|
|
182
|
+
std::uint64_t resolved_ = 0;
|
|
183
|
+
Token inherited_ = 0;
|
|
145
184
|
Token invisible_ = 0;
|
|
146
185
|
Token defaultPurpose_ = 0;
|
|
147
186
|
std::vector<BucketSchema> buckets_;
|
|
148
187
|
ExtentCache extents_;
|
|
188
|
+
HolderIndex holders_;
|
|
149
189
|
};
|
|
150
190
|
|
|
151
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__";
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
X(std::string, Visibility, "visibility", "inherited", \
|
|
21
21
|
"\"invisible\" hides the prim and its descendants.", \
|
|
22
22
|
.group = "Prim", .options = {tokens::kInherited, tokens::kInvisible}, \
|
|
23
|
-
.dirty = Dirty::Visibility)
|
|
23
|
+
.dirty = Dirty::Visibility, .inherited = true) \
|
|
24
24
|
X(std::string, Purpose, "purpose", "default", \
|
|
25
|
-
"Which renders include it: default, render, proxy or guide
|
|
25
|
+
"Which renders include it and its descendants: default, render, proxy or guide.", \
|
|
26
26
|
.group = "Prim", \
|
|
27
27
|
.options = {tokens::kDefault, tokens::kRender, tokens::kProxy, tokens::kGuide}, \
|
|
28
|
-
.dirty = Dirty::Visibility)
|
|
28
|
+
.dirty = Dirty::Visibility, .inherited = true) \
|
|
29
29
|
X(int, World, "ernie:world", -1, \
|
|
30
30
|
"The batch world the prim and its descendants are in; -1 for every world.", \
|
|
31
|
-
.group = "Prim", .lower = AtLeast(-1.0), .inherited = true)
|
|
31
|
+
.group = "Prim", .lower = AtLeast(-1.0), .dirty = Dirty::Visibility, .inherited = true)
|
|
32
32
|
|
|
33
33
|
#define ERNIE_XFORMABLE_ATTRIBUTES(X) \
|
|
34
34
|
X(std::vector<std::string>, XformOpOrder, "xformOpOrder", std::vector<std::string>{}, \
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
#define ERNIE_MATERIAL_BINDING_API_ATTRIBUTES(X) \
|
|
17
17
|
X(Path, MaterialBinding, "material:binding", Path(), \
|
|
18
18
|
"The Material the prim and its descendants are drawn with.", .label = "Material", \
|
|
19
|
-
.group = "Material", .dirty = Dirty::Material)
|
|
19
|
+
.group = "Material", .dirty = Dirty::Material, .inherited = true)
|
|
20
20
|
|
|
21
21
|
#define ERNIE_SHADER_ATTRIBUTES(X) \
|
|
22
22
|
X(std::string, Id, "info:id", "", \
|
|
@@ -361,6 +361,25 @@ class PrimStore {
|
|
|
361
361
|
}
|
|
362
362
|
return &Values<T>(*column)[slot.row];
|
|
363
363
|
}
|
|
364
|
+
/// @brief Writes a value derived from others into a column the bucket has, leaving it
|
|
365
|
+
/// unauthored and touching the row only when the value changes.
|
|
366
|
+
/// @return Whether it changed; false too when the bucket has no such column.
|
|
367
|
+
template <typename T> bool Derive(PrimId prim, AttributeId attribute, const T& value) {
|
|
368
|
+
const SlotData& slot = Slot(prim);
|
|
369
|
+
Bucket& bucket = *buckets_[slot.bucket];
|
|
370
|
+
const auto found = bucket.columnIndex.find(attribute);
|
|
371
|
+
if (found == bucket.columnIndex.end()) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
Column& column = bucket.columns[found->second];
|
|
375
|
+
T& cell = Values<T>(column)[slot.row];
|
|
376
|
+
if (cell == value) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
cell = value;
|
|
380
|
+
Touch(slot.bucket, column, slot.row, slot.row + 1, Next());
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
364
383
|
/// @brief Unauthors an attribute, putting its fallback back.
|
|
365
384
|
void Clear(PrimId prim, AttributeId attribute);
|
|
366
385
|
|
|
@@ -19,6 +19,8 @@ inline constexpr std::string_view kOrient = "xformOp:orient";
|
|
|
19
19
|
inline constexpr std::string_view kScale = "xformOp:scale";
|
|
20
20
|
inline constexpr std::string_view kResetXformStack = "!resetXformStack!";
|
|
21
21
|
inline constexpr std::string_view kInvertPrefix = "!invert!";
|
|
22
|
+
/// The namespace of inherited attributes' resolved values, which only the scene writes.
|
|
23
|
+
inline constexpr std::string_view kResolvedPrefix = "ernie:resolved:";
|
|
22
24
|
|
|
23
25
|
inline constexpr std::string_view kInherited = "inherited";
|
|
24
26
|
inline constexpr std::string_view kInvisible = "invisible";
|