Checkpoint shared cover support profile

This commit is contained in:
2026-06-05 14:52:00 +02:00
parent a92822bc44
commit ac382a6cac
+32 -23
View File
@@ -296,20 +296,7 @@ function addCoverAssembly(pageWidth, depth, thickness, spineWidth, coverOuterX)
}
function createCoverAssemblyGeometry(pageWidth, depth, thickness, spineWidth, coverOuterX) {
const spineHalf = spineArcHalf(spineWidth);
const hingeX = spineHalf + hingeInset();
const outerX = coverOuterX ?? spineHalf + pageWidth + COVER_OVERHANG;
const outerTopY = BOOK_PROFILE.tableY + thickness;
const connectionTopY = BOOK_PROFILE.raisedHingeY;
const spineTopY = BOOK_PROFILE.tableY + thickness;
const section = [
{ x: -outerX, y: outerTopY },
{ x: -hingeX, y: connectionTopY },
{ x: -spineHalf, y: spineTopY },
{ x: spineHalf, y: spineTopY },
{ x: hingeX, y: connectionTopY },
{ x: outerX, y: outerTopY }
];
const section = coverProfilePoints(spineWidth, coverOuterX ?? spineArcHalf(spineWidth) + pageWidth + COVER_OVERHANG);
const positions = [];
const uvs = [];
const indices = [];
@@ -409,6 +396,25 @@ function hingeInset() {
return Math.max(0.001, BOOK_PROFILE.raisedHingeY - BOOK_PROFILE.coverThickness);
}
function coverProfilePoints(spineWidth, coverOuterX) {
return coverProfilePointsFromFrame(spineArcHalf(spineWidth), coverOuterX);
}
function coverProfilePointsFromFrame(spineHalf, coverOuterX) {
const hingeX = spineHalf + hingeInset();
const outerTopY = BOOK_PROFILE.tableY + BOOK_PROFILE.coverThickness;
const connectionTopY = BOOK_PROFILE.raisedHingeY;
const spineTopY = BOOK_PROFILE.tableY + BOOK_PROFILE.coverThickness;
return [
{ x: -coverOuterX, y: outerTopY },
{ x: -hingeX, y: connectionTopY },
{ x: -spineHalf, y: spineTopY },
{ x: spineHalf, y: spineTopY },
{ x: hingeX, y: connectionTopY },
{ x: coverOuterX, y: outerTopY }
];
}
function calculateSpineWidth(bundleCount) {
const minimumWidth = 0.16;
if (bundleCount <= 1) return minimumWidth;
@@ -894,16 +900,19 @@ function upwardNormalAt(points, index) {
function coverTopYAtX(x) {
const ax = Math.abs(x);
const spineHalf = currentSpineHalf();
const hingeX = spineHalf + hingeInset();
const outerX = activeCoverOuterX;
if (ax <= spineHalf) return BOOK_PROFILE.coverThickness;
if (ax <= hingeX) {
const t = (ax - spineHalf) / (hingeX - spineHalf);
return THREE.MathUtils.lerp(BOOK_PROFILE.coverThickness, BOOK_PROFILE.raisedHingeY, t);
const profile = coverProfilePointsFromFrame(currentSpineHalf(), activeCoverOuterX)
.filter((point) => point.x >= 0)
.sort((a, b) => a.x - b.x);
if (ax <= profile[0].x) return profile[0].y;
for (let index = 0; index < profile.length - 1; index += 1) {
const from = profile[index];
const to = profile[index + 1];
if (ax <= to.x) {
const t = (ax - from.x) / (to.x - from.x || 1);
return THREE.MathUtils.lerp(from.y, to.y, t);
}
const t = THREE.MathUtils.clamp((ax - hingeX) / (outerX - hingeX), 0, 1);
return THREE.MathUtils.lerp(BOOK_PROFILE.raisedHingeY, BOOK_PROFILE.coverThickness, t);
}
return profile[profile.length - 1].y;
}
function currentSpineHalf() {