diff --git a/src/mode/cam/animate.js b/src/mode/cam/animate.js index f36a22d2..f6a94b09 100644 --- a/src/mode/cam/animate.js +++ b/src/mode/cam/animate.js @@ -6,19 +6,23 @@ kiri.loader.push(function() { let KIRI = self.kiri, CAM = KIRI.driver.CAM, - API, WORLD, + API, WORLD, SPACE, meshes = {}; + // ---( CLIENT FUNCTIONS )--- + if (KIRI.client) CAM.animate_clear = function(api) { - WORLD = (API = api).const.SPACE.platform.world; + SPACE = (API = api).const.SPACE; + WORLD = SPACE.platform.world; $('layer-animate').innerHTML = ''; Object.keys(meshes).forEach(id => deleteMesh(id)); } if (KIRI.client) CAM.animate = function(api) { - WORLD = (API = api).const.SPACE.platform.world; + SPACE = (API = api).const.SPACE; + WORLD = SPACE.platform.world; KIRI.client.animate_setup(API.conf.get(), data => { checkMeshCommands(data); const UC = API.uc; @@ -26,10 +30,12 @@ kiri.loader.push(function() { layer.innerHTML = ''; UC.setGroup(layer); UC.newRow([ - UC.newButton(null,play,{icon:''}), - UC.newButton(null,pause,{icon:''}) + UC.newButton(null,play,{icon:''}), + UC.newButton(null,step,{icon:''}), + UC.newButton(null,fast,{icon:''}), + UC.newButton(null,pause,{icon:''}) ]); - play(); + play({steps: 1, speed: 25}); }); }; @@ -79,6 +85,7 @@ kiri.loader.push(function() { mpos.array[pos] = val; } mpos.needsUpdate = true; + SPACE.update(); } function deleteMesh(id) { @@ -86,8 +93,19 @@ kiri.loader.push(function() { delete meshes[id]; } - function play() { - KIRI.client.animate({speed: 1}, handleGridUpdate); + function step(opts) { + const { steps, speed } = opts; + KIRI.client.animate({speed: speed || 25, steps: 1}, handleGridUpdate); + } + + function play(opts) { + const { steps, speed } = opts; + KIRI.client.animate({speed: speed || 25, steps: steps || Infinity}, handleGridUpdate); + } + + function fast(opts) { + const { steps, speed } = opts; + KIRI.client.animate({speed: speed || 10, steps: steps || Infinity}, handleGridUpdate); } function pause() { @@ -96,6 +114,9 @@ kiri.loader.push(function() { function handleGridUpdate(data) { checkMeshCommands(data); + if (data && data.done) { + console.log('done', data); + } } if (KIRI.client) @@ -108,6 +129,13 @@ kiri.loader.push(function() { send("animate", data, ondone); }; + if (KIRI.client) + KIRI.client.animate_cleanup = function(data, ondone) { + send("animate_cleanup", data, ondone); + }; + + // ---( WORKER FUNCTIONS )--- + let path, pathIndex, stock, grid, gridX, gridY, tool, tools, rez, last; if (KIRI.worker) @@ -130,6 +158,10 @@ kiri.loader.push(function() { gridX = stepsX; gridY = stepsY; + tool = null; + last = null; + animating = false; + animateClear = false; send.done({ mesh_add: { id: 0, pos, ind } }); }; @@ -140,11 +172,13 @@ kiri.loader.push(function() { const ox = size.x / 2; const oy = size.y / 2; + const b = { mx: 0, my: 0, Mx: 0, My: 0}; + // initialize grid points for (let x=0, ai=0; x 0) ind.appendAll([ (stepsY * x) + (y - 1), @@ -154,57 +188,108 @@ kiri.loader.push(function() { (stepsY * (x - 1)) + y, (stepsY * (x )) + y ]); + b.mx = Math.min(b.mx, px); + b.my = Math.min(b.my, py); + b.Mx = Math.max(b.Mx, px); + b.My = Math.max(b.My, py); } } + // console.log({stepsX, stepsY, size, step, ox, oy, bounds: b}); return { pos, ind }; } if (KIRI.worker) KIRI.worker.animate = function(data, send) { - if (data.speed) { - const next = path[pathIndex++]; - if (next.tool && (!tool || tool.getNumber() !== next.tool)) { - updateTool(next.tool, send); - } - const id = tool.getID(); - if (last) { - const lp = last.point, np = next.point; - const dx = np.x - lp.x, dy = np.y - lp.y, dz = np.z - lp.z; - const md = Math.max(Math.abs(dx), Math.abs(dy), Math.abs(dz)); - const st = Math.ceil(md / rez); - const mx = dx / st, my = dy / st, mz = dz / st; - const moves = []; - for (let i=0, x=lp.x, y=lp.y, z=lp.z; i= 0) { + renderSpeed = data.speed; + } + if (data.steps > 0) { + stepsRemain = data.steps; + } + if (animating) { + return send.done(); + } + renderPath(send); + }; + + if (KIRI.worker) + KIRI.worker.animate_cleanup = function(data, send) { + if (animating) { + animateClear = true; } }; + let animateClear = false; + let animating = false; + let renderSpeed = 25; + let stepsRemain = 0; + + function renderPath(send) { + if (animateClear) { + animateClear = false; + animating = false; + send.done(); + return; + } + if (stepsRemain <= 0 || renderSpeed === 0) { + animating = false; + send.done(); + return; + } + const next = path[pathIndex++]; + if (!next) { + animating = false; + stepsRemain = 0; + send.done(); + return; + } + animating = true; + stepsRemain--; + if (next.tool && (!tool || tool.getNumber() !== next.tool)) { + updateTool(next.tool, send); + } + const id = tool.getID(); + if (last) { + const lp = last.point, np = next.point; + const dx = np.x - lp.x, dy = np.y - lp.y, dz = np.z - lp.z; + const md = Math.max(Math.abs(dx), Math.abs(dy), Math.abs(dz)); + const st = Math.ceil(md / rez); + const mx = dx / st, my = dy / st, mz = dz / st; + const moves = []; + for (let i=0, x=lp.x, y=lp.y, z=lp.z; i { renderPath(send) }, 0); + } + last = next; + } + function renderMoves(id, moves, send) { let index = 0; function update() { - const pos = moves[index++]; - updateMesh(pos, send); - tool.pos = pos; - send.data({ mesh_move: { id, pos }}); + if (animateClear) { + return renderPath(send); + } + if (renderSpeed > 0 && index < moves.length) { + const pos = moves[index++]; + if (!pos) throw `no pos @ ${index} of ${moves.length}`; + tool.pos = pos; + updateMesh(pos, send); + send.data({ mesh_move: { id, pos }}); + } if (index < moves.length) { - setTimeout(update, 25); + setTimeout(update, renderSpeed); } else { - send.done(); + setTimeout(() => { renderPath(send) }, renderSpeed); } } update(0); @@ -215,8 +300,8 @@ kiri.loader.push(function() { const { size, pix } = tool.profileDim; const mid = Math.floor(pix/2); const mesh_update = []; - const rx = Math.floor((pos.x + stock.x / 2) / rez); - const ry = Math.floor((pos.y + stock.y / 2) / rez); + const rx = Math.floor((pos.x + stock.x / 2 - size / 2) / rez); + const ry = Math.floor((pos.y + stock.y / 2 - size / 2) / rez); // deform mesh to lowest point on tool profile for (let i=0, il=prof.length; i < il; ) { const dx = mid + prof[i++]; @@ -225,6 +310,9 @@ kiri.loader.push(function() { const gx = rx + dx; const gy = ry + dy; + + if (gx < 0|| gy < 0 || gx > gridX-1 || gy > gridY-1) continue; + const gi = gx * gridY + gy; const iz = gi * 3 + 2; diff --git a/src/mode/cam/tool.js b/src/mode/cam/tool.js index 65c03b62..97de4e17 100644 --- a/src/mode/cam/tool.js +++ b/src/mode/cam/tool.js @@ -104,7 +104,7 @@ this.profile = toolOffset; this.profileDim = { - size: shaft_pix_float, + size: flute_diameter, pix: profile_pix_iter }; return this;