clone

an endless marble-race generator in the browser; the url is the seed, so every track can be shared

main
marbles / tools / measure_floor_path.ts
measure_floor_path.ts 2.1K
1/**2 * Extract the channel-floor ribbon of a piece (upward-facing verts near the3 * running surface) and print it ordered by descending y, with polar coords4 * around a candidate spiral center, to recover helix centerlines.5 */6import { NodeIO } from "@gltf-transform/core";7import { KHRONOS_EXTENSIONS } from "@gltf-transform/extensions";89const GLB = "/Users/dami/Developer/marbles/assets/marble-kit.glb";10const [name, cx = "0", cz = "0"] = Deno.args;11const CX = Number(cx), CZ = Number(cz);1213const io = new NodeIO().registerExtensions(KHRONOS_EXTENSIONS);14const doc = await io.read(GLB);15const root = doc.getRoot();1617type V3 = [number, number, number];18const node = root.listNodes().find((n) => n.getName() === name);19if (!node) throw new Error(`no node ${name}`);2021const floor: { p: V3; n: V3 }[] = [];22const walk = (n: typeof node) => {23 const mesh = n.getMesh();24 if (mesh) {25 for (const prim of mesh.listPrimitives()) {26 const pos = prim.getAttribute("POSITION")?.getArray();27 const nrm = prim.getAttribute("NORMAL")?.getArray();28 if (!pos || !nrm) continue;29 for (let i = 0; i < pos.length; i += 3) {30 if (nrm[i + 1] > 0.85) {31 floor.push({32 p: [pos[i], pos[i + 1], pos[i + 2]],33 n: [nrm[i], nrm[i + 1], nrm[i + 2]],34 });35 }36 }37 }38 }39 for (const c of n.listChildren()) walk(c);40};41walk(node);4243// Dedup + sort by y then angle.44const seen = new Set<string>();45const rows = floor46 .filter(({ p }) => {47 const k = p.map((v) => v.toFixed(3)).join(",");48 if (seen.has(k)) return false;49 seen.add(k);50 return true;51 })52 .map(({ p }) => {53 const dx = p[0] - CX, dz = p[2] - CZ;54 return {55 x: p[0],56 y: p[1],57 z: p[2],58 r: Math.hypot(dx, dz),59 deg: Math.atan2(dz, dx) * 180 / Math.PI,60 };61 })62 .sort((a, b) => b.y - a.y || a.deg - b.deg);6364console.log(`${name}: ${rows.length} upward verts (center ${CX},${CZ})`);65for (const r of rows) {66 console.log(67 `y=${r.y.toFixed(3)} x=${r.x.toFixed(3)} z=${r.z.toFixed(3)} r=${68 r.r.toFixed(3)69 } θ=${r.deg.toFixed(1)}`,70 );71}