diff --git a/standalone/goldberg-sphere/index.html b/standalone/goldberg-sphere/index.html index 61ddaf8..307077d 100644 --- a/standalone/goldberg-sphere/index.html +++ b/standalone/goldberg-sphere/index.html @@ -90,48 +90,6 @@

Sphere Playground

-
-

Pipeline stage

-
- - - - -
-
- -
-

Palette

-
- -
-
- -
-

Mesh

-
- - - 5 -
-
- -
-

Relaxation

-
- - -
-
- - -
-
- - -
-
-

Paint

@@ -252,7 +210,6 @@
-
Ready
diff --git a/standalone/goldberg-sphere/playground_main.mjs b/standalone/goldberg-sphere/playground_main.mjs index d64d4c7..1e974a0 100644 --- a/standalone/goldberg-sphere/playground_main.mjs +++ b/standalone/goldberg-sphere/playground_main.mjs @@ -5,11 +5,11 @@ import { mat4_mul, mat4_perspective, mat4_translate_z, quat_identity, quat_from_ import { create_program, make_buffer } from './gl_utils.mjs'; import { PAINT_BG, PAINT_BG_PBR, PAINT_BG_NOISE, Paint_State } from './paint_state.mjs'; import { Spin_State } from './spin_state.mjs'; -import { shape_distortion, build_triangle_geo, build_goldberg_geo } from './render_geo.mjs'; +import { shape_distortion, build_goldberg_geo } from './render_geo.mjs'; import { build_goldberg_adjacency } from './topology.mjs'; import { Undo_State } from './undo_state.mjs'; import { Env_State } from './env_state.mjs'; -import { PALETTES, DEFAULT_PALETTE } from './palettes.mjs'; +import { DEFAULT_PALETTE } from './palettes.mjs'; // --------------------------------------------------------------------------- // Load shaders @@ -32,7 +32,6 @@ const paint = new Paint_State(); const undo_state = new Undo_State(); const env = new Env_State(); let current_geo = null; -let current_stage = 'relaxed'; let current_palette = DEFAULT_PALETTE; let building = false; let active_brush_side = 'left'; @@ -42,12 +41,7 @@ let paint_dirty = false; let debounce_timer = null; function get_params() { - return { - depth: parseInt(document.getElementById('depth').value, 10), - iters: parseInt(document.getElementById('iters').value, 10), - alpha_edge: parseFloat(document.getElementById('alpha-edge').value), - alpha_centroid: parseFloat(document.getElementById('alpha-centroid').value), - }; + return { depth: 5, iters: 500, alpha_edge: 0, alpha_centroid: 0.04 }; } @@ -106,7 +100,7 @@ function upload_geo() { function rebuild_face_colors() { if (!cache.goldberg || !face_col_buf) { return; } const goldberg = cache.goldberg; - const use_relaxed = current_stage === 'relaxed'; + const use_relaxed = true; const fcol = [], fpbr = [], fnoise = []; for (let fi = 0; fi < goldberg.faces.length; fi++) { const face = goldberg.faces[fi]; @@ -202,8 +196,6 @@ function apply_history(side) { async function build() { if (building) { return; } building = true; - const btn = document.getElementById('build-btn'); - btn.disabled = true; const p = get_params(); const t0 = Date.now(); @@ -217,14 +209,6 @@ async function build() { cache.poly = null; cache.goldberg = null; } - if (current_stage === 'ico') { - current_geo = build_triangle_geo(cache.ico, current_palette); - upload_geo(); - cache.depth = p.depth; - set_stats(current_geo, 'Icosahedron', Date.now() - t0); - set_status(''); - return; - } if (depth_changed || !cache.poly) { let poly = cache.ico; @@ -235,14 +219,6 @@ async function build() { cache.poly = poly; cache.goldberg = null; } - if (current_stage === 'subdiv') { - current_geo = build_triangle_geo(cache.poly, current_palette); - upload_geo(); - cache.depth = p.depth; - set_stats(current_geo, `Subdivided ×${p.depth}`, Date.now() - t0); - set_status(''); - return; - } if (depth_changed || !cache.goldberg) { set_status('Building Goldberg dual…'); await yield_ui(30); @@ -250,16 +226,8 @@ async function build() { cache.adj = null; undo_state.invalidate(); } - if (current_stage === 'goldberg') { - current_geo = build_goldberg_geo(cache.goldberg, false, paint, current_palette); - upload_geo(); - cache.depth = p.depth; - set_stats(current_geo, 'Goldberg (no relax)', Date.now() - t0); - set_status(''); - return; - } - set_status(`Relaxing (${p.iters} iters, edge=${p.alpha_edge}, centroid=${p.alpha_centroid})…`); + set_status(`Relaxing (${p.iters} iters)…`); await yield_ui(50); cache.goldberg.relax_sphere(p.iters, p.alpha_edge, p.alpha_centroid); current_geo = build_goldberg_geo(cache.goldberg, true, paint, current_palette); @@ -270,7 +238,6 @@ async function build() { } finally { building = false; - btn.disabled = false; snapshot_now(); } } @@ -302,7 +269,7 @@ function pick_face(px, py) { const hx = ro[0]+t*rd[0], hy = ro[1]+t*rd[1], hz = ro[2]+t*rd[2]; const goldberg = cache.goldberg; - const use_relaxed = current_stage === 'relaxed'; + const use_relaxed = true; let best_fi = -1, best_dot = -Infinity; for (let fi = 0; fi < goldberg.faces.length; fi++) { const face = goldberg.faces[fi]; @@ -409,7 +376,7 @@ function faces_at_radius(center_fi, radius) { // --------------------------------------------------------------------------- function save_paint() { - const depth = parseInt(document.getElementById('depth').value); + const depth = 5; const faces = []; for (const [fi, c] of paint.face_colors) { const h = v => Math.round(v*255).toString(16).padStart(2, '0'); @@ -432,10 +399,7 @@ function load_paint(file) { reader.onload = e => { try { const data = JSON.parse(e.target.result); - const depth = parseInt(document.getElementById('depth').value); - if (data.depth !== depth) { - document.getElementById('depth').value = data.depth; - document.getElementById('depth-val').textContent = data.depth; + if (data.depth !== 5) { cache.poly = null; cache.goldberg = null; cache.adj = null; } paint.face_colors.clear(); @@ -730,50 +694,6 @@ function render_frame(ts) { // UI wiring // --------------------------------------------------------------------------- -// Palette buttons (built dynamically from PALETTES array). -{ - const grid = document.getElementById('palette-grid'); - for (const p of PALETTES) { - const btn = document.createElement('button'); - btn.className = 'sb' + (p === DEFAULT_PALETTE ? ' active' : ''); - btn.textContent = p.name; - btn.addEventListener('click', () => { - current_palette = p; - grid.querySelectorAll('.sb').forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - rebuild_face_colors(); - // Triangle stages need a full rebuild since positions are shared. - if (current_stage === 'ico' || current_stage === 'subdiv') { build(); } - }); - grid.appendChild(btn); - } -} - -document.querySelectorAll('.sb').forEach(btn => { - btn.addEventListener('click', () => { - document.querySelectorAll('.sb').forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - current_stage = btn.dataset.stage; - build(); - }); -}); - -document.getElementById('depth').addEventListener('input', () => { - const d = parseInt(document.getElementById('depth').value); - document.getElementById('depth-val').textContent = d; - document.getElementById('iters').value = d * 8; - cache.poly = null; - cache.goldberg = null; - cache.adj = null; -}); - -document.getElementById('build-btn').addEventListener('click', () => { - if (current_stage === 'relaxed') { - cache.goldberg = null; - cache.adj = null; - } - build(); -}); document.getElementById('spin-btn').addEventListener('click', () => { @@ -802,12 +722,8 @@ const update_paint_buttons = () => { }; const make_tool_handler = tool => () => { - if (!paint.enabled || paint.tool !== tool) { - paint.enabled = true; - paint.tool = tool; - } else { - paint.enabled = false; - } + paint.enabled = true; + paint.tool = tool; update_paint_buttons(); };