GeorgeS2019
| **Godot Feature** | **Description** | |------------------|-----------------| | **TileMetadata** (`.cpp/.h`) | Godot’s approach to tile metadata—Unity uses more granular feature ID/property classes. |
#5 · open · 4 comments
| **Godot Feature** | **Description** | |------------------|-----------------| | **TileMetadata** (`.cpp/.h`) | Godot’s approach to tile metadata—Unity uses more granular feature ID/property classes. |
### 🧩 Unity’s Granular Feature Metadata System Unity breaks down metadata into **specialized, reusable components**, each handling a specific aspect of feature metadata: | Unity Class/File | Purpose | |------------------|---------| | `CesiumFeatureIdAttributeImpl.*` | Handles feature ID attributes embedded in vertex data. | | `CesiumFeatureIdTextureImpl.*` | Manages feature IDs stored in textures. | | `CesiumPropertyTablePropertyImpl.*` | Represents individual properties in a property table. | | `CesiumMetadataImpl.*` | Coordinates access to metadata across tiles. | | `CesiumMetadataValueImpl.*` | Optimizes value access and type conversion. | | `CesiumFeaturesMetadataUtility.*` | Provides utility functions for metadata parsing and conversion. | This modularity allows Unity to: - Support multiple feature ID sources (attributes, textures, implicit IDs). - Handle per-feature properties with type safety and performance optimizations. - Extend or override behavior for specific metadata types. --- ### 🧱 Godot’s TileMetadata: Simpler, Unified Godot’s `TileMetadata.cpp/h` acts as a **single container** for all metadata associated with a tile. It’s simpler and easier to manage but lacks the fine-grained separation seen in Unity. - Likely stores all feature IDs and properties in one structure. - Easier to integrate into Godot’s node system. - Less flexible for advanced metadata workflows (e.g., styling by feature ID, dynamic property access). --- ### 🧠 Summary Unity’s system is **more granular and extensible**, ideal for complex metadata-driven rendering or interaction. Godot’s approach is **simpler and more monolithic**, which works well for basic use cases but may require refactoring for advanced features.

<html> <body> <!--StartFragment--><html><head></head><body><p>To bring <strong>Godot’s Cesium TileMetadata.h</strong> closer to the <strong>granular, modular system Unity uses</strong>, you’d want to break out responsibilities into specialized classes rather than funneling everything through <code>TileMetadata</code> + <code>CesiumPropertyInfo</code>. Here’s a structured list of changes and additions:</p> <hr> <h2>🔑 Proposed Class Additions for Granularity</h2> <h3>1. <strong>Feature ID Sources</strong></h3> <ul> <li><strong><code>FeatureIdAttributeSource</code></strong> <ul> <li>Handles feature IDs embedded in vertex attributes.</li> <li>Provides GPU‑friendly pathways for instancing/selection.</li> </ul></li> <li><strong><code>FeatureIdTextureSource</code></strong> <ul> <li>Manages feature IDs stored in textures.</li> <li>Supports caching and late binding for texture‑based IDs.</li> </ul></li> <li><strong><code>FeatureIdImplicitSource</code></strong> <ul> <li>Provides implicit ID generation when no explicit source exists.</li> <li>Useful for fallback or procedural tiles.</li> </ul></li> </ul> <hr> <h3>2. <strong>Property Wrappers</strong></h3> <ul> <li><strong><code>PropertyTableProperty</code></strong> <ul> <li>Represents a single property with type‑safe getters.</li> <li>Lazy conversion (only convert when accessed).</li> <li>Mirrors Unity’s <code>CesiumPropertyTablePropertyImpl</code>.</li> </ul></li> </ul> <hr> <h3>3. <strong>Value Layer</strong></h3> <ul> <li><strong><code>MetadataValue</code></strong> <ul> <li>Encapsulates typed accessors (<code>as_float64()</code>, <code>as_vec3f()</code>, <code>try_get_enum()</code>).</li> <li>Small‑object optimization to reduce Variant churn.</li> <li>Dedicated conversion layer separate from template helpers.</li> </ul></li> </ul> <hr> <h3>4. <strong>Metadata Coordination</strong></h3> <ul> <li><strong><code>MetadataCoordinator</code></strong> <ul> <li>Centralized manager for multiple property tables.</li> <li>Provides unified API for querying properties across tables.</li> <li>Similar to Unity’s <code>CesiumMetadataImpl</code>.</li> </ul></li> </ul> <hr> <h3>5. <strong>Utility Functions</strong></h3> <ul> <li><strong><code>MetadataUtility</code></strong> <ul> <li>Static helpers for parsing, validation, and conversion.</li> <li>Enum range validation, matrix mapping, color type handling.</li> <li>Equivalent to Unity’s <code>CesiumFeaturesMetadataUtility</code>.</li> </ul></li> </ul> <hr> <h3>6. <strong>Matrix & Enum Support</strong></h3> <ul> <li><strong><code>MatrixPropertyHandler</code></strong> <ul> <li>Implements conversion paths for Mat2/Mat3/Mat4.</li> <li>Maps glm matrices to Godot Matrix types.</li> </ul></li> <li><strong><code>EnumPropertyHandler</code></strong> <ul> <li>Stores enum tables and validates ranges.</li> <li>Prevents silent coercion into scalars/booleans.</li> </ul></li> </ul> <hr> <h2>🛠 Structural Changes to TileMetadata.h</h2> <ul> <li><strong>Refactor <code>TileMetadata</code></strong> into a <strong>facade</strong>: <ul> <li>Delegates to specialized classes (<code>FeatureIdSource</code>, <code>PropertyTableProperty</code>, <code>MetadataValue</code>).</li> <li>Keeps <code>Dictionary/Variant</code> outputs for GDScript ergonomics.</li> </ul></li> <li><strong>Introduce caching layer</strong>: <ul> <li>Preconvert common types (e.g., Float64→Float32 vec arrays).</li> <li>Avoid repeated coercions in hot loops.</li> </ul></li> <li><strong>Add accessor API</strong>: <ul> <li><code>get_property(name)</code> → returns <code>PropertyTableProperty</code>.</li> <li><code>get_feature_id(source, index)</code> → dispatches to correct <code>FeatureIdSource</code>.</li> </ul></li> </ul> <hr> <h2>📊 Comparison Snapshot</h2> Unity Granular System | Godot Current | Proposed Godot Additions -- | -- | -- CesiumFeatureIdAttributeImpl | None | FeatureIdAttributeSource CesiumFeatureIdTextureImpl | None | FeatureIdTextureSource CesiumPropertyTablePropertyImpl | CesiumPropertyInfo | PropertyTableProperty CesiumMetadataImpl | TileMetadata | MetadataCoordinator CesiumMetadataValueImpl | Template helpers | MetadataValue CesiumFeaturesMetadataUtility | Inline templates | MetadataUtility <hr> <h2>🎯 Outcome</h2> <p>By modularizing into these classes:</p> <ul> <li><strong>Granularity</strong>: Each metadata source/type is handled independently.</li> <li><strong>Performance</strong>: Typed accessors and caching reduce Variant overhead.</li> <li><strong>Extensibility</strong>: New metadata forms (colors, packed bitfields, GPU pathways) can be added without touching core.</li> <li><strong>Developer ergonomics</strong>: Typed wrappers for C++ performance, Dictionary/Variant for GDScript prototyping.</li> </ul> <hr> </body></html><!--EndFragment--> </body> </html>
<html> <body> <!--StartFragment--><html><head></head><body><h1>Comparison of Unity granular feature metadata system and Godot Cesium metadata API</h1> <hr> <h2>High-level differences</h2> Aspect | Unity granular system (Cesium for Unity) | Godot Cesium API (code provided) -- | -- | -- Feature ID sources | Separate implementations for vertex attributes, textures, and implicit IDs via CesiumFeatureIdAttributeImpl, CesiumFeatureIdTextureImpl | No explicit feature ID source abstraction; focuses on property table parsing via CesiumGltf::PropertyTableView Property access model | Strongly typed property wrappers (CesiumPropertyTablePropertyImpl) with centralized coordination (CesiumMetadataImpl) | Properties normalized into Godot Dictionary and Variant via CesiumPropertyInfo and EPropertyType/EComponentType Value typing and conversion | Dedicated value layer (CesiumMetadataValueImpl) optimizing type coercion and performance | Template-based mapping to Variant, with enums for type/component and warnings for narrowing conversions Extensibility | Modular implementations per metadata source; behavior can be extended or overridden per type/source | Centralized conversion path; extensibility requires altering template helpers or adding new EPropertyType/EComponentType cases Performance strategy | Source-specific optimizations; avoids unnecessary allocations; type-safe access paths | Conversion to Variant and Dictionary for engine interoperability; potential overhead and narrowing during float64→float32 Developer ergonomics | Strong separation of concerns, clear source-specific APIs, C#-friendly | Single entry point (TileMetadata) yielding engine-native structures (Dictionary/Variant), GDScript-friendly <blockquote> <p>Summary: Unity emphasizes modular, source-specific metadata handling with strong typing and performance specialization, while the Godot code prioritizes a unified, engine-native representation via Dictionary/Variant for broad usability.</p> </blockquote> <hr> <h2>What the Godot Cesium API exposes</h2> <ul> <li><strong>Entry point:</strong> <ul> <li>TileMetadata aggregates property tables with <code>init</code>, <code>add_table(const CesiumGltf::PropertyTableView&)</code>, and exposes them via <code>get_table(index)</code> returning a Godot <code>Dictionary</code>.</li> </ul></li> <li><strong>Type system:</strong> <ul> <li><strong>EPropertyType</strong> covers scalar, vectors, matrices, string, boolean, enum.</li> <li><strong>EComponentType</strong> describes underlying numeric types (Int/Uint 8–64, Float32/64).</li> </ul></li> <li><strong>Value container:</strong> <ul> <li><strong>CesiumPropertyInfo</strong> holds <strong>propertyType</strong>, <strong>componentType</strong>, <strong>isArray</strong>, and a <strong>Variant</strong> <code>data</code>.</li> </ul></li> <li><strong>Conversion helpers:</strong> <ul> <li><strong>get_component_type<T></strong> infers numeric component types using CesiumGltf traits and C++ type traits.</li> <li><strong>make_vector_type<T></strong> maps glm vectors to Godot Vector2/Vector3/Vector4 or integer vector variants, with error/warning handling for invalid types and narrowing.</li> <li><strong>make_array_type<T></strong> converts metadata arrays to Godot Array of Variants, preserving element type info in the parent.</li> <li><strong>make_metadata_value<T></strong> is the central dispatcher, distinguishing arrays, VecN, strings, booleans/scalars via CesiumGltf trait checks, then returning a Ref to CesiumPropertyInfo.</li> </ul></li> <li><strong>Runtime representation:</strong> <ul> <li>Property tables are stored in <code>std::vector<Dictionary></code> (<code>m_tables</code>) and an overall <code>Dictionary</code> cache (<code>m_accesibleRepresentation</code>), aligning with Godot’s scripting ergonomics.</li> </ul></li> </ul> <hr> <h2>Where Unity provides more granularity</h2> <ul> <li><p><strong>Feature ID sources:</strong></p> <ul> <li><strong>Unity:</strong> Different classes for attributes vs textures vs implicit IDs allow tailored parsing, caching, and late binding per source.</li> <li><strong>Godot (code shown):</strong> No separate abstraction for feature ID sources; all metadata arrives via PropertyTableView and is normalized into Variants.</li> </ul></li> <li><p><strong>Property table access and typing:</strong></p> <ul> <li><strong>Unity:</strong> Per-property wrappers with type safety and fast paths, avoiding per-access boxing/unboxing.</li> <li><strong>Godot:</strong> Unified Variant-based container simplifies usage, but introduces runtime type checks and potential conversions.</li> </ul></li> <li><p><strong>Value conversion layer:</strong></p> <ul> <li><strong>Unity:</strong> A dedicated value layer abstracts type coercion, minimizing allocations and branch cost across hot paths.</li> <li><strong>Godot:</strong> Conversion is embedded in templates; warnings are emitted on narrowing (e.g., Float64→Float32), but there’s no separate optimization layer.</li> </ul></li> <li><p><strong>Extensibility surface:</strong></p> <ul> <li><strong>Unity:</strong> Drop-in extensions for new metadata forms (e.g., new texture encodings) without touching core property accessors.</li> <li><strong>Godot:</strong> To introduce new types (e.g., color types, packed bitfields), you extend EPropertyType/EComponentType and the conversion helpers.</li> </ul></li> </ul> <hr> <h2>Strengths of the Godot approach</h2> <ul> <li><p><strong>Engine-native ergonomics:</strong></p> <ul> <li><strong>Dictionary/Variant</strong> outputs integrate seamlessly with GDScript and Godot’s editor tooling, speeding prototyping and scripting.</li> </ul></li> <li><p><strong>Clear vector and array handling:</strong></p> <ul> <li>Explicit mapping to Vector2/Vector3/Vector4 and Array makes common GIS/3D use cases straightforward.</li> </ul></li> <li><p><strong>Safety cues during conversion:</strong></p> <ul> <li><strong>ERR_PRINT/WARN_PRINT</strong> provide immediate feedback on invalid component mixes and narrowing conversions, aiding debugging.</li> </ul></li> </ul> <hr> <h2>Gaps relative to Unity and practical enhancements</h2> <ul> <li><p><strong>Missing feature ID source abstraction:</strong></p> <ul> <li>Add interfaces like <strong>IFeatureIdSource</strong> with concrete implementations for vertex attributes, textures, and implicit IDs.</li> <li><strong>Benefit:</strong> Enables targeted caching, GPU-friendly pathways, and selective refresh.</li> </ul></li> <li><p><strong>Dedicated value layer for performance:</strong></p> <ul> <li>Introduce a <strong>MetadataValue</strong> class encapsulating typed accessors (e.g., as_float64(), as_vec3f(), try_get_enum()) with small-object optimization.</li> <li><strong>Benefit:</strong> Reduces Variant churn and branchy template paths in hot loops.</li> </ul></li> <li><p><strong>Per-property wrappers:</strong></p> <ul> <li>Create <strong>PropertyTableProperty</strong> objects exposing type-safe getters and lazy conversion, keyed by property name.</li> <li><strong>Benefit:</strong> Mirrors Unity’s property-centric ergonomics and aids static analysis.</li> </ul></li> <li><p><strong>Matrix support parity:</strong></p> <ul> <li>The enum lists Mat2/Mat3/Mat4, but conversion paths for matrices are not implemented.</li> <li>Implement glm→Godot matrix mapping or a custom Matrix type for consistent handling.</li> </ul></li> <li><p><strong>Enum typing and validation:</strong></p> <ul> <li>Add enum value tables and range validation to avoid silently treating enums as booleans/scalars in mixed cases.</li> </ul></li> <li><p><strong>Batch access and caching:</strong></p> <ul> <li>Cache common conversions (e.g., Float64→Float32 vec arrays) per table to avoid repeated per-feature coercions.</li> </ul></li> </ul> <hr> <h2>Example usage patterns and recommended wrappers</h2> <ul> <li><p><strong>Godot scripting-friendly accessor layer:</strong></p> <ul> <li><strong>Goal:</strong> Keep Dictionary/Variant for GDScript while offering typed C++ access for performance-critical paths.</li> <li><strong>Design:</strong> <ul> <li><strong>TileMetadataView:</strong> exposes <code>get_table_names()</code>, <code>get_property(name)</code>, <code>get_feature_id(source, index)</code> with typed returns.</li> <li><strong>MetadataCache:</strong> memoizes conversions and provides bulk readers (e.g., <code>read_vec3_array(property)</code>).</li> </ul></li> </ul></li> <li><p><strong>Feature ID integration path:</strong></p> <ul> <li><strong>Add:</strong> <code>FeatureIdAttributeSource</code>, <code>FeatureIdTextureSource</code>, <code>FeatureIdImplicitSource</code> classes.</li> <li><strong>Expose:</strong> Unified API <code>get_feature_id(Index3D position)</code> that dispatches to the configured source.</li> </ul></li> <li><p><strong>Type-safe property API:</strong></p> <ul> <li><strong>Add:</strong> <code>Property<T></code> wrapper with explicit specializations for scalar, vector, matrix, boolean, string, enum.</li> <li><strong>Provide:</strong> <code>try_get<T>(name)</code> returning std::optional<T> to avoid Variant ambiguity.</li> </ul></li> </ul> <hr> <h2>Personalized guidance for your workflow</h2> <ul> <li><strong>For visualization pipelines and large tilesets:</strong> <ul> <li><strong>Use typed caches</strong> for vec arrays and avoid per-frame Variant parsing; preconvert Float64 data to Float32 if your renderer is single precision.</li> </ul></li> <li><strong>For GPU interop experiments:</strong> <ul> <li><strong>Feature IDs via attributes</strong> are the most direct path to GPU instancing or selection buffers; add an attribute-source class before texture-based IDs.</li> </ul></li> <li><strong>For editor tooling:</strong> <ul> <li>Keep the Dictionary/Variant output for GDScript tools, but back it with typed C++ views to preserve both agility and performance.</li> </ul></li> </ul> </body></html><!--EndFragment--> </body> </html>