Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

blank: proper backface culling, remove hinge barrels, fix z-sorting

- Only front-facing faces render (removed both-winding hack that drew all 6 faces)
- Lid uses flipped face quads to account for hinge transform winding reversal
- Remove hinge barrel faces and edges entirely (too small, cause z-fighting)
- Wireframe edges only on base + lid

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+16 -29
+16 -29
system/public/aesthetic.computer/disks/blank.mjs
··· 231 231 const drawList = []; 232 232 233 233 // Base + lid faces 234 - let faceIdx = 0; 234 + // Only add front-facing faces (proper backface culling — no both-winding hack) 235 235 const addFaces = (proj, color, tag) => { 236 236 for (const [a, b, c, d] of faceQuads) { 237 - const fi = faceIdx++; 238 237 const e1x = proj[b][0] - proj[a][0], e1y = proj[b][1] - proj[a][1]; 239 238 const e2x = proj[d][0] - proj[a][0], e2y = proj[d][1] - proj[a][1]; 240 - const cross = e1x * e2y - e1y * e2x; 241 - if (cross < 0) { 242 - const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 243 - drawList.push({ z, type: "face", proj, verts: [a, b, c, d], color, tag, fi }); 244 - } else if (cross > 0) { 245 - const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 246 - drawList.push({ z, type: "face", proj, verts: [d, c, b, a], color, tag, fi }); 247 - } 239 + if (e1x * e2y - e1y * e2x >= 0) continue; // back-facing → skip 240 + const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 241 + drawList.push({ z, type: "face", proj, verts: [a, b, c, d], color, tag }); 248 242 } 249 243 }; 250 - addFaces(projBase, baseColor, "base"); 251 - addFaces(projLid, lidColor, "lid"); 252 - 253 - // Hinge barrels — only draw when not fully behind base+lid 254 - const hingeColor = isDark ? [32, 32, 35] : [45, 45, 48]; 255 - const baseMinZ = min(...projBase.map(v => v[2])); 256 - const lidMinZ = min(...projLid.map(v => v[2])); 257 - for (const hv of hingeVerts) { 258 - const projH = hv.map(project); 259 - const hingeMaxZ = max(...projH.map(v => v[2])); 260 - // Only add if hinge pokes out in front of at least one body 261 - if (hingeMaxZ > baseMinZ || hingeMaxZ > lidMinZ) { 262 - addFaces(projH, hingeColor, "hinge"); 244 + // Lid winding flips due to hinge transform — use reversed face quads 245 + const faceQuadsFlipped = faceQuads.map(([a, b, c, d]) => [d, c, b, a]); 246 + const addFacesFlipped = (proj, color, tag) => { 247 + for (const [a, b, c, d] of faceQuadsFlipped) { 248 + const e1x = proj[b][0] - proj[a][0], e1y = proj[b][1] - proj[a][1]; 249 + const e2x = proj[d][0] - proj[a][0], e2y = proj[d][1] - proj[a][1]; 250 + if (e1x * e2y - e1y * e2x >= 0) continue; 251 + const z = (proj[a][2] + proj[b][2] + proj[c][2] + proj[d][2]) / 4; 252 + drawList.push({ z, type: "face", proj, verts: [a, b, c, d], color, tag }); 263 253 } 264 - } 254 + }; 255 + addFaces(projBase, baseColor, "base"); 256 + addFacesFlipped(projLid, lidColor, "lid"); 265 257 266 258 // Keyboard keys (on base top face, y = -0.001 just above y=0) 267 259 const kbInset = 0.18; ··· 350 342 }; 351 343 addEdges(projBase); 352 344 addEdges(projLid); 353 - for (const hv of hingeVerts) { 354 - const projH = hv.map(project); 355 - const hingeMaxZ = max(...projH.map(v => v[2])); 356 - if (hingeMaxZ > baseMinZ || hingeMaxZ > lidMinZ) addEdges(projH); 357 - } 358 345 359 346 // Sort back-to-front (highest z = farthest = draw first) 360 347 drawList.sort((a, b) => b.z - a.z);