scene/scene.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #pragma once | ||
| 3 | |||
| 4 | #include <cstdint> | ||
| 5 | #include <filesystem> | ||
| 6 | #include <functional> | ||
| 7 | #include <memory> | ||
| 8 | #include <optional> | ||
| 9 | #include <string> | ||
| 10 | #include <string_view> | ||
| 11 | #include <utility> | ||
| 12 | #include <vector> | ||
| 13 | |||
| 14 | #include "chrono_batch_render/device/device.h" | ||
| 15 | #include "chrono_batch_render/device/operation.h" | ||
| 16 | #include "chrono_batch_render/device/ref.h" | ||
| 17 | #include "chrono_batch_render/device/stream.h" | ||
| 18 | #include "chrono_batch_render/export.h" | ||
| 19 | #include "chrono_batch_render/scene/defines.h" | ||
| 20 | #include "chrono_batch_render/scene/prim.h" | ||
| 21 | #include "chrono_batch_render/scene/records/render_vars.h" | ||
| 22 | #include "chrono_batch_render/stage/schema/schema.h" | ||
| 23 | #include "chrono_batch_render/stage/structure/tokens.h" | ||
| 24 | #include "chrono_batch_render/stage/types.h" | ||
| 25 | #include "chrono_batch_render/stage/views/attribute.h" | ||
| 26 | #include "chrono_batch_render/stage/views/poses.h" | ||
| 27 | #include "chrono_batch_render/stage/views/view.h" | ||
| 28 | #include "chrono_batch_render/util/span.h" | ||
| 29 | |||
| 30 | namespace chrono::batch_render { | ||
| 31 | |||
| 32 | 355 | struct CHRONO_BATCH_RENDER_API SceneDesc { | |
| 33 | device::DeviceDesc device; | ||
| 34 | device::Traversal traversal = device::Traversal::Auto; | ||
| 35 | uint32_t maxRefits = 16; | ||
| 36 | uint32_t pointsPerBox = 1; | ||
| 37 | float curveTolerance = 0.05f; | ||
| 38 | uint32_t maxCurveSteps = 16; | ||
| 39 | bool exactCurves = false; | ||
| 40 | unsigned textureThreads = 4; | ||
| 41 | bool waitForKernels = true; | ||
| 42 | }; | ||
| 43 | |||
| 44 | struct PublishDesc { | ||
| 45 | std::optional<Ordinal> ordinal; | ||
| 46 | bool wait = false; | ||
| 47 | }; | ||
| 48 | |||
| 49 | class SceneImpl; | ||
| 50 | class ImportJob; | ||
| 51 | struct ImportReader; | ||
| 52 | struct ImportDesc; | ||
| 53 | struct ImportSource; | ||
| 54 | |||
| 55 | using ShaderLoader = | ||
| 56 | std::function<std::vector<std::string>(Scene& scene, const std::filesystem::path& file)>; | ||
| 57 | |||
| 58 | CHRONO_BATCH_RENDER_API void SetShaderLoader(ShaderLoader loader); | ||
| 59 | CHRONO_BATCH_RENDER_API uint32_t RetypePrims(Scene& scene, SchemaId from, SchemaId to); | ||
| 60 | CHRONO_BATCH_RENDER_API ShaderPrim Define(Scene& scene, std::string_view path, | ||
| 61 | const Shader::Desc& desc); | ||
| 62 | CHRONO_BATCH_RENDER_API PrimRange Define(Scene& scene, Span<const std::string> paths, | ||
| 63 | const Shader::Desc& desc, const BatchDesc& batch = {}); | ||
| 64 | |||
| 65 | class CHRONO_BATCH_RENDER_API PrimCopy { | ||
| 66 | public: | ||
| 67 | PrimCopy(); | ||
| 68 | ~PrimCopy(); | ||
| 69 | PrimCopy(const PrimCopy& other); | ||
| 70 | PrimCopy(PrimCopy&& other) noexcept; | ||
| 71 | PrimCopy& operator=(const PrimCopy& other); | ||
| 72 | PrimCopy& operator=(PrimCopy&& other) noexcept; | ||
| 73 | |||
| 74 | bool Empty() const; | ||
| 75 | std::string_view Name() const; | ||
| 76 | uint32_t PrimCount() const; | ||
| 77 | |||
| 78 | private: | ||
| 79 | friend class Scene; | ||
| 80 | struct State; | ||
| 81 | std::shared_ptr<const State> m_state; | ||
| 82 | }; | ||
| 83 | |||
| 84 | class CHRONO_BATCH_RENDER_API Overrides { | ||
| 85 | public: | ||
| 86 | Overrides(); | ||
| 87 | ~Overrides(); | ||
| 88 | Overrides(const Overrides&) = delete; | ||
| 89 | Overrides& operator=(const Overrides&) = delete; | ||
| 90 | Overrides(Overrides&& other) noexcept; | ||
| 91 | Overrides& operator=(Overrides&& other) noexcept; | ||
| 92 | |||
| 93 | void Set(Prim prim, ColumnRef column, Span<const std::byte> cell); | ||
| 94 | |||
| 95 | 3 | template <class T> void Set(Prim prim, Field<T> field, const T& value) { | |
| 96 | 3 | const AttributeCell<T> cell = value; | |
| 97 | 3 | Set(prim, field.Column(), AsBytes(Span<const AttributeCell<T>>(&cell, 1))); | |
| 98 | 3 | } | |
| 99 | |||
| 100 | void Clear(Prim prim, ColumnRef column); | ||
| 101 | void Clear(); | ||
| 102 | |||
| 103 | 1 | bool Empty() const { | |
| 104 | 1 | return m_cells.empty(); | |
| 105 | } | ||
| 106 | |||
| 107 | private: | ||
| 108 | friend class Scene; | ||
| 109 | |||
| 110 | Overrides(Ref<Scene> scene, uint64_t owner); | ||
| 111 | |||
| 112 | Ref<Scene> m_scene; | ||
| 113 | uint64_t m_owner = 0; | ||
| 114 | std::vector<std::pair<Prim, ColumnRef>> m_cells; | ||
| 115 | }; | ||
| 116 | |||
| 117 | class CHRONO_BATCH_RENDER_API ComposedWorld { | ||
| 118 | public: | ||
| 119 | ComposedWorld(); | ||
| 120 | ~ComposedWorld(); | ||
| 121 | ComposedWorld(const ComposedWorld&) = delete; | ||
| 122 | ComposedWorld& operator=(const ComposedWorld&) = delete; | ||
| 123 | ComposedWorld(ComposedWorld&& other) noexcept; | ||
| 124 | ComposedWorld& operator=(ComposedWorld&& other) noexcept; | ||
| 125 | |||
| 126 | void Set(const ComposedWorldDesc& desc); | ||
| 127 | |||
| 128 | uint32_t World() const { | ||
| 129 | return m_world; | ||
| 130 | } | ||
| 131 | |||
| 132 | private: | ||
| 133 | friend class Scene; | ||
| 134 | |||
| 135 | ComposedWorld(Ref<Scene> scene, uint32_t world); | ||
| 136 | void Release(); | ||
| 137 | |||
| 138 | Ref<Scene> m_scene; | ||
| 139 | uint32_t m_world = kGlobalWorld; | ||
| 140 | }; | ||
| 141 | |||
| 142 | enum class TexelType : uint8_t { Uint8, Float32 }; | ||
| 143 | |||
| 144 | struct TextureData { | ||
| 145 | uint32_t width = 0; | ||
| 146 | uint32_t height = 0; | ||
| 147 | uint32_t channels = 4; | ||
| 148 | TexelType type = TexelType::Float32; | ||
| 149 | Span<const std::byte> texels; | ||
| 150 | }; | ||
| 151 | |||
| 152 | class CHRONO_BATCH_RENDER_API Scene : public RefCounted { | ||
| 153 | public: | ||
| 154 | static Ref<Scene> Create(const SceneDesc& desc = {}); | ||
| 155 | static Ref<Scene> Create(device::Device& device, const SceneDesc& desc = {}); | ||
| 156 | ~Scene() override; | ||
| 157 | |||
| 158 | template <class T> | ||
| 159 | 2044 | typename T::PrimType Define(std::string_view path, const typename T::Desc& desc = {}) { | |
| 160 | 2037 | return typename T::PrimType(chrono::batch_render::Define(*this, path, desc)); | |
| 161 | } | ||
| 162 | |||
| 163 | template <class T> | ||
| 164 | 7 | PrimRange Define(Span<const std::string> paths, const typename T::Desc& desc = {}, | |
| 165 | const BatchDesc& batch = {}) { | ||
| 166 | 7 | return chrono::batch_render::Define(*this, paths, desc, batch); | |
| 167 | } | ||
| 168 | |||
| 169 | Prim Define(std::string_view path, SchemaId schema); | ||
| 170 | PrimRange Define(Span<const std::string> paths, SchemaId schema, const BatchDesc& batch = {}); | ||
| 171 | void Remove(Prim prim); | ||
| 172 | Overrides CreateOverrides(); | ||
| 173 | bool Overridden(Prim prim, ColumnRef column) const; | ||
| 174 | std::vector<std::byte> ReadAuthored(Prim prim, ColumnRef column) const; | ||
| 175 | void MarkSession(Prim prim); | ||
| 176 | ComposedWorld ComposeWorld(Prim world, const ComposedWorldDesc& desc = {}); | ||
| 177 | |||
| 178 | 22 | template <class T> void Apply(Prim prim, const typename T::Desc& desc = {}) { | |
| 179 | 21 | chrono::batch_render::Apply(*this, Span<const Prim>(&prim, 1), desc); | |
| 180 | } | ||
| 181 | |||
| 182 | template <class T> void Apply(Span<const Prim> prims, const typename T::Desc& desc = {}) { | ||
| 183 | chrono::batch_render::Apply(*this, prims, desc); | ||
| 184 | } | ||
| 185 | |||
| 186 | template <class T> void Apply(const PrimRange& range, const typename T::Desc& desc = {}) { | ||
| 187 | chrono::batch_render::Apply(*this, Handles(range), desc); | ||
| 188 | } | ||
| 189 | |||
| 190 | template <class T> | ||
| 191 | 3 | void Apply(Prim prim, std::string_view instance, const typename T::Desc& desc = {}) { | |
| 192 | 3 | chrono::batch_render::Apply(*this, Span<const Prim>(&prim, 1), instance, desc); | |
| 193 | } | ||
| 194 | |||
| 195 | template <class T> | ||
| 196 | void Apply(Span<const Prim> prims, std::string_view instance, | ||
| 197 | const typename T::Desc& desc = {}) { | ||
| 198 | chrono::batch_render::Apply(*this, prims, instance, desc); | ||
| 199 | } | ||
| 200 | |||
| 201 | template <class T> | ||
| 202 | void Apply(const PrimRange& range, std::string_view instance, | ||
| 203 | const typename T::Desc& desc = {}) { | ||
| 204 | chrono::batch_render::Apply(*this, Handles(range), instance, desc); | ||
| 205 | } | ||
| 206 | |||
| 207 | template <class T> void Unapply(Prim prim, std::string_view instance) { | ||
| 208 | Unapply(Span<const Prim>(&prim, 1), T::kSchema, instance); | ||
| 209 | } | ||
| 210 | |||
| 211 | template <class T> void Unapply(Span<const Prim> prims, std::string_view instance) { | ||
| 212 | Unapply(prims, T::kSchema, instance); | ||
| 213 | } | ||
| 214 | |||
| 215 | 6 | template <class T> void Unapply(Prim prim) { | |
| 216 | 6 | Unapply(Span<const Prim>(&prim, 1), T::kSchema); | |
| 217 | } | ||
| 218 | |||
| 219 | template <class T> void Unapply(Span<const Prim> prims) { | ||
| 220 | Unapply(prims, T::kSchema); | ||
| 221 | } | ||
| 222 | |||
| 223 | template <class T> void Unapply(const PrimRange& range) { | ||
| 224 | Unapply(Handles(range), T::kSchema); | ||
| 225 | } | ||
| 226 | |||
| 227 | void Apply(Span<const Prim> prims, SchemaId api); | ||
| 228 | void Apply(Span<const Prim> prims, SchemaId api, std::string_view instance); | ||
| 229 | void Unapply(Span<const Prim> prims, SchemaId api); | ||
| 230 | void Unapply(Span<const Prim> prims, SchemaId api, std::string_view instance); | ||
| 231 | std::vector<Prim> Handles(const PrimRange& range) const; | ||
| 232 | Prim Move(Prim prim, std::string_view path); | ||
| 233 | Prim Rename(Prim prim, std::string_view name); | ||
| 234 | PrimCopy Copy(Prim prim); | ||
| 235 | Prim Paste(const PrimCopy& copy, std::string_view path); | ||
| 236 | PrimRange Clone(Prim source, Span<const std::string> targets, const CloneDesc& desc = {}); | ||
| 237 | PrimRange Clone(Prim source, uint32_t count, const CloneDesc& desc = {}); | ||
| 238 | ImportJob Import(std::string_view path, const std::filesystem::path& file); | ||
| 239 | ImportJob Import(std::string_view path, const std::filesystem::path& file, | ||
| 240 | const ImportDesc& desc); | ||
| 241 | ImportJob Import(std::string_view path, const ImportSource& source); | ||
| 242 | ImportJob Import(std::string_view path, const ImportSource& source, const ImportDesc& desc); | ||
| 243 | ImportJob Import(std::string_view path, const ImportReader& reader, const ImportDesc& desc); | ||
| 244 | |||
| 245 | std::optional<Prim> Find(std::string_view path) const; | ||
| 246 | Prim ByIndex(uint32_t index) const; | ||
| 247 | View Select(std::string_view pattern, SchemaId schema = SchemaId::None) const; | ||
| 248 | View Select(Span<const std::string> paths, SchemaId schema = SchemaId::None) const; | ||
| 249 | View Select(const PrimRange& range, SchemaId schema = SchemaId::None, uint32_t index = 0) const; | ||
| 250 | View Select(Prim prim) const; | ||
| 251 | View Select(std::string_view pattern, SchemaId api, std::string_view instance) const; | ||
| 252 | View Select(Prim prim, SchemaId api, std::string_view instance) const; | ||
| 253 | |||
| 254 | 4 | template <class T> typename T::ViewType Select(std::string_view pattern) const { | |
| 255 | 4 | return typename T::ViewType(Select(pattern, T::kSchema)); | |
| 256 | } | ||
| 257 | |||
| 258 | template <class T> | ||
| 259 | typename T::ViewType Select(std::string_view pattern, std::string_view instance) const { | ||
| 260 | return typename T::ViewType(Select(pattern, T::kSchema, instance)); | ||
| 261 | } | ||
| 262 | |||
| 263 | uint32_t PrimCount() const; | ||
| 264 | uint32_t WorldCount() const; | ||
| 265 | std::optional<Box> Bounds(uint32_t world = kGlobalWorld) const; | ||
| 266 | device::Download ReadBoundsAsync(uint32_t world = kGlobalWorld) const; | ||
| 267 | device::Download ReadAllBoundsAsync() const; | ||
| 268 | device::Download ReadPrimBoundsAsync(Span<const std::string> paths) const; | ||
| 269 | std::vector<Box> PrimBounds(Span<const std::string> paths) const; | ||
| 270 | |||
| 271 | device::Operation Publish(const PublishDesc& desc = {}, Stream producer = Stream::None()); | ||
| 272 | void Advance(double dt); | ||
| 273 | double Time() const; | ||
| 274 | void SetTime(double time); | ||
| 275 | bool Pending() const; | ||
| 276 | Ordinal Published() const; | ||
| 277 | uint64_t StructureVersion() const; | ||
| 278 | Snapshot Acquire(Stream consumer = Stream::None()); | ||
| 279 | using RefCounted::Release; | ||
| 280 | void Release(const Snapshot& snapshot, Stream consumer = Stream::None()); | ||
| 281 | void Require(Span<const chrono::batch_render::Token> taxonomies); | ||
| 282 | |||
| 283 | void AddFile(std::string path, FileBytes bytes, std::optional<Prim> owner = std::nullopt); | ||
| 284 | void AddTexture(std::string path, const TextureData& data, | ||
| 285 | std::optional<Prim> owner = std::nullopt); | ||
| 286 | void RemoveFile(std::string_view path); | ||
| 287 | |||
| 288 | chrono::batch_render::Token Token(std::string_view text); | ||
| 289 | std::string_view Text(chrono::batch_render::Token token) const; | ||
| 290 | device::Device& GetDevice() const; | ||
| 291 | |||
| 292 | private: | ||
| 293 | friend class SceneImpl; | ||
| 294 | |||
| 295 | ImportJob StartImport(std::string_view path, const ImportReader& reader, const ImportDesc& desc, | ||
| 296 | std::string source); | ||
| 297 | |||
| 298 | Scene(device::Device& device, const SceneDesc& desc); | ||
| 299 | |||
| 300 | std::unique_ptr<SceneImpl> m_impl; | ||
| 301 | }; | ||
| 302 | |||
| 303 | } | ||
| 304 |