export interface UVQualityReport { missingUVs: boolean; extremeStretching: boolean; overlappingUVs: boolean; highComplexity: boolean; recommendTriplanar: boolean; details: { vertexCount: number; uvRange: [number, number]; }; } export function analyzeUVQuality( positions: Float32Array, uvs?: Float32Array, indices?: Uint32Array | Uint16Array ): UVQualityReport { const vertexCount = positions.length / 3; const highComplexity = vertexCount > 50000; // Arbitrary threshold for complex geometry if (!uvs || uvs.length === 0) { return { missingUVs: true, extremeStretching: false, overlappingUVs: false, highComplexity, recommendTriplanar: true, details: { vertexCount, uvRange: [0, 0] } }; } let minU = Infinity, maxU = -Infinity; let minV = Infinity, maxV = -Infinity; for (let i = 0; i < uvs.length; i += 2) { const u = uvs[i]; const v = uvs[i + 1]; if (u < minU) minU = u; if (u > maxU) maxU = u; if (v < minV) minV = v; if (v > maxV) maxV = v; } const uRange = maxU - minU; const vRange = maxV - minV; // Basic heuristic: if UVs are heavily clamped or barely cover any area const extremeStretching = (uRange < 0.01 && uRange > 0) || (vRange < 0.01 && vRange > 0); // Overlapping detection is computationally expensive, skipping deep check for now // A robust check would require comparing triangle areas in UV space vs World space const overlappingUVs = false; const recommendTriplanar = extremeStretching || highComplexity; return { missingUVs: false, extremeStretching, overlappingUVs, highComplexity, recommendTriplanar, details: { vertexCount, uvRange: [uRange, vRange] } }; }