72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
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]
|
|
}
|
|
};
|
|
}
|