using AcDream.App.Rendering.Gpu; using AcDream.Core.Meshing; using DatReaderWriter.Enums; namespace AcDream.App.Rendering.Wb; /// /// Bucket identity for 's per-frame group dictionary. /// Two (entity, batch) pairs that share the same render /// in a single glMultiDrawElementsIndirect draw command. Promoted to /// internal at file scope (was a private nested type) so /// can store it inside /// without depending on dispatcher internals. /// /// Campaign V slice V4t replaced the raw 64-bit /// ARB_bindless_texture handle with . The /// substitution is a bijection — the device interns one slot per resident /// handle — so exactly the same (entity, batch) pairs bucket together as /// before, which is the property that keeps submission order identical. This /// key's VALUE never orders anything: groups are enumerated in the dictionary's /// insertion order and sorted by cull mode then camera distance /// (CompareOpaqueSubmissionOrder / CompareTransparentSubmissionOrder), /// and the delayed-alpha path sorts by viewer distance then submission ordinal. /// The key reaches only equality, hashing, and the scene-digest fingerprints. /// /// Campaign VM VM6 review fix round: joined /// the key so a mesh subset reachable from BOTH a procedural-scenery entity /// and a non-scenery entity (same index range/texture/translucency/cull /// mode) buckets into two DIFFERENT groups instead of coalescing into one /// group whose InstanceGroup.FoliageFlags was last-writer-wins between /// the two classifications — which flickered the shared group's flags /// between frames and let the caster (keyed correctly from the start) and /// the receiver (previously keyed without this field) disagree about the /// same subset. /// /// Campaign VM VM6 review fix round 3 (N2b): /// is REQUIRED (no default) and declared before (which /// keeps its default) so that a new GroupKey(...) omitting it is a /// compile error, not a silent fall-back to 0. The round-2 packed-classifier /// blocker (F1) was exactly a silently-defaulted FoliageFlags reaching /// production; a caller can no longer forget this field the way that one /// could. /// internal readonly record struct GroupKey( uint FirstIndex, int BaseVertex, int IndexCount, GpuTextureSlot TextureSlot, uint TextureLayer, TranslucencyKind Translucency, uint FoliageFlags, CullMode CullMode = CullMode.CounterClockwise);