using AcDream.Core.Terrain; namespace AcDream.Core.Meshing; /// /// One sub-mesh of a GfxObj: a vertex+index buffer that uses a single Surface. /// A GfxObj with multiple surfaces produces multiple sub-meshes. /// public sealed record GfxObjSubMesh( uint SurfaceId, Vertex[] Vertices, uint[] Indices) { /// /// How this sub-mesh should be composited into the frame. /// Populated from Surface.Type flags at upload time. /// public TranslucencyKind Translucency { get; init; } = TranslucencyKind.Opaque; /// /// Surface.Luminosity. Retail uses this as material emissive. /// public float Luminosity { get; init; } = 0f; /// /// Surface.Diffuse. Retail sky keyframes route SkyObjectReplace.MaxBright /// through CPhysicsObj::SetDiffusion (0x005119e0), which lands in /// CMaterial::SetDiffuseSimple (0x00539750). /// public float Diffuse { get; init; } = 1f; /// /// True when at least one vertex UV component lies outside [0, 1], so /// the mesh expects texture repeat instead of clamp. /// public bool NeedsUvRepeat { get; init; } = false; /// /// Final opacity multiplier derived from Surface.Translucency. Retail /// translucency is transparency: 0.0 is opaque and 1.0 is invisible. /// CMaterial::SetTranslucencySimple at 0x005396f0 writes material alpha /// as 1 - translucency. /// public float SurfOpacity { get; init; } = 1f; /// /// True when the raw Surface.Type has the Additive bit. Retail disables /// fixed-function fog alpha for this raw bit even if the final blend mode /// is forced to AlphaBlend by the Translucent+ClipMap branch. /// public bool DisableFog { get; init; } = false; }