diff --git a/app/assets/html/bzGraflow/nodesTest1.html b/app/assets/html/bzGraflow/nodesTest1.html new file mode 100644 index 0000000..c860cb7 --- /dev/null +++ b/app/assets/html/bzGraflow/nodesTest1.html @@ -0,0 +1,85 @@ + + + + + \ No newline at end of file diff --git a/app/assets/html/test.html b/app/assets/html/test.html index 4014541..637b615 100644 --- a/app/assets/html/test.html +++ b/app/assets/html/test.html @@ -5,236 +5,13 @@ - + + + + -
- three.js - FBXLoader
- Character and animation from Mixamo -
- - - - + diff --git a/app/assets/json/bzGraflow/testFlow1.json b/app/assets/json/bzGraflow/testFlow1.json new file mode 100644 index 0000000..f254f34 --- /dev/null +++ b/app/assets/json/bzGraflow/testFlow1.json @@ -0,0 +1,30 @@ +{ + "nodesFile": "/app/assets/html/bzGraflow/nodesTest1.html", + "flow": { + "nodes":[ + { "nodeType": "inc", + "id": "aze", + "coords": { "x": 20, "y": 10} + }, + { "nodeType": "factor", + "id": "qsd", + "coords": { "x": 270, "y": 50} + }, + { "nodeType": "inc", + "id": "wcx", + "coords": { "x": 520, "y": 50} + }, + { "nodeType": "inc", + "id": "ert", + "coords": { "x": 150, "y": 350} + } + ], + "links": [ + { "from": ["aze", "out1"], "to": ["qsd", "inp1"] }, + { "from": ["qsd", "out1"], "to": ["wcx", "inp1"] }, + { "from": ["qsd", "out1"], "to": ["ert", "inp2"] }, + { "from": ["ert", "out1"], "to": ["aze", "inp2"] } + + ] + } +} \ No newline at end of file diff --git a/app/assets/sfx/intro.js b/app/assets/sfx/intro.js index 68368f4..72abb56 100644 --- a/app/assets/sfx/intro.js +++ b/app/assets/sfx/intro.js @@ -228,7 +228,7 @@ class Intro{ this.matEE.defines = this.matEE.defines || {} this.matEE.defines.USE_UV = "" this.matEE.onBeforeCompile = shader => { - shader.uniforms.uReveal = { value: 0 } + shader.uniforms.uReveal = { value: -0.3 } shader.uniforms.uTime = { value: 0 }; shader.fragmentShader = shader.fragmentShader .replace( @@ -241,15 +241,26 @@ class Intro{ .replace( `#include `, `#include - if ((uReveal-vUv.x) < (1.0-uReveal)){ - float random = fract(sin(dot(gl_FragCoord.xy + vec2(uTime) , vec2(12.9898,78.233))) * 43758.5453); - if(random > 0.1) discard; - } + + float bandWidth = 0.20; + + if (vUv.x > uReveal) { + float d = (vUv.x - uReveal) / bandWidth; // 0 at front, grows to the right + if (d < 1.0) { // inside noisy band + float density = smoothstep(1.0, 0.0, d); + float random = fract( sin(dot(gl_FragCoord.xy + vec2(uTime), vec2(12.9898,78.233))) * 43758.5453 ); + if (random > density) discard; + } else { + // fully hidden + discard; + } + + } ` ) this.matEE.userData.shader = shader } - + this.planeEE = new THREE.Mesh(geo, this.matEE) this.planeEE.scale.set(.2, .2, 1) this.planeEE.position.set(0,-0.8,.1) @@ -269,7 +280,7 @@ class Intro{ requestAnimationFrame(this.animate.bind(this)) if (this.matEE.userData.shader) { if(this.matEE.userData.shader.uniforms.uReveal.value<1){ - this.matEE.userData.shader.uniforms.uReveal.value += 0.01 + this.matEE.userData.shader.uniforms.uReveal.value += 0.005 this.matEE.userData.shader.uniforms.uTime.value = Math.floor(performance.now() / 200) } } diff --git a/app/assets/styles/app.css b/app/assets/styles/app.css index ad0ff3c..acc992f 100755 --- a/app/assets/styles/app.css +++ b/app/assets/styles/app.css @@ -40,6 +40,7 @@ body[eicapp] { min-height: 100vh; box-sizing: border-box; background: repeating-linear-gradient( -45deg, #000, #333 10px, #000 10px, #333 20px ); + overflow: hidden; } .helperBotCanvas{ display: block; diff --git a/app/libs/HelperBot/HelperBot.module.js b/app/libs/HelperBot/HelperBot.module.js index d481a6e..ba1900d 100644 --- a/app/libs/HelperBot/HelperBot.module.js +++ b/app/libs/HelperBot/HelperBot.module.js @@ -168,27 +168,31 @@ class HelperBot{ const delay = Math.max(Math.abs(dx), Math.abs(dy), Math.abs(dz)) * moveDelay const ax = (dy>0.5) ? -10 : ((dy<-0.5) ? 10 : 0 ) const ay = (dx>0.5) ? 10 : ((dx<-0.5) ? -10 : 0 ) - - console.log( this.mecha.position.x, this.mecha.position.y) - console.log(dx,dy,ax,ay) + //TODO : fix jerks when rotation tweens overlap + // console.log( this.mecha.position.x, this.mecha.position.y) + // console.log(dx,dy,ax,ay) - const rotationDelay = Math.min(delay/4, 500) - this.rotateBot({x: ax, y: ay, z: 0}, rotationDelay) + const rotationDelay = delay/4; + if(rotationDelay>400) this.rotateBot({x: ax, y: ay, z: 0}, rotationDelay) let chkpt1 = true, chkpt2 = true, chkpt3 = true + this.animate = false; console.log('stopped!') const startTime = Date.now() - this.translateBot(position, delay, null, () => { + this.translateBot(position, delay, () => { + this.animate = true ; console.log('started!') + }, + () => { const t = (Date.now()-startTime)/delay if(chkpt1 && (t >= 0.2)){ //Time to stop accelerating - this.rotateBot({x: 0, y: 0, z: 0}, rotationDelay) + if(rotationDelay>400) this.rotateBot({x: 0, y: 0, z: 0}, rotationDelay) chkpt1 = false } if(chkpt2 && (t >= 0.7)){ //Time to brake - this.rotateBot({x: -ax, y: -ay, z: 0}, rotationDelay) + if(rotationDelay>400) this.rotateBot({x: -ax, y: -ay, z: 0}, rotationDelay) chkpt2 = false } if(chkpt3 && (t >= 0.9)){ //Time to restore - this.rotateBot({x: 0, y: 0, z: 0}, rotationDelay) + if(rotationDelay>400) this.rotateBot({x: 0, y: 0, z: 0}, rotationDelay) chkpt3 = false } }) diff --git a/app/thirdparty/buildoz/buildoz.css b/app/thirdparty/buildoz/buildoz.css index 311e0d3..84bc42d 100644 --- a/app/thirdparty/buildoz/buildoz.css +++ b/app/thirdparty/buildoz/buildoz.css @@ -186,4 +186,19 @@ bz-slidepane[side="right"] div.handle { background: repeating-linear-gradient( to right, rgba(255,255,255,1) 0, rgba(255,255,255,1) 2px, rgba(0,0,0,0.2) 3px, rgba(0,0,0,0.2) 4px ); transform: translateY(-50%); cursor: ew-resize; -} \ No newline at end of file +} +bz-graflow { + position: relative; + display: block; + width: 100vw; + height: 100vh; +} +bz-graflow .bzgf-wires-container, +bz-graflow .bzgf-nodes-container{ + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} +bz-graflow .bzgf-nodes-container{ z-index:10; } +bz-graflow .bzgf-wires-container{ z-index:9; } \ No newline at end of file diff --git a/app/thirdparty/buildoz/bzGraflow.js b/app/thirdparty/buildoz/bzGraflow.js new file mode 100644 index 0000000..0e813f5 --- /dev/null +++ b/app/thirdparty/buildoz/bzGraflow.js @@ -0,0 +1,159 @@ +class BZgraflow extends Buildoz{ + + constructor(){ + super() + this.defaultAttrs = { } + this.stagedNodes = { } + this.stagedWires = { } + } + static _loadedNodeStyles = new Set() // Allow multi instances or re-loadNodes, but avoid reinjecting same styles ! + + connectedCallback() { + super.connectedCallback() + const flowUrl = this.getBZAttribute('flow') + if(!flowUrl) { + console.warn('BZgraflow: No flow URL !?') + return + } + + this.loadFlow(flowUrl) // Let it load async while we coat + + this.nodesContainer = document.createElement('div') + this.nodesContainer.classList.add('bzgf-nodes-container') + this.wiresContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg') + this.wiresContainer.classList.add('bzgf-wires-container') + this.append(this.wiresContainer) + this.append(this.nodesContainer) + } + + async loadFlow(url){ + const res = await fetch(url+'?'+crypto.randomUUID()) + const buf = await res.text() + let flowObj + try{ + flowObj = JSON.parse(buf) + } catch(err){ + console.error('Could not parse flow JSON!?', err) + return + } + if(!flowObj.nodesFile){ + console.error('No nodesFile in JSON!?') + return + } + await this.loadNodes(flowObj.nodesFile) + this.flow = flowObj.flow + this.refresh() + } + + async loadNodes(url) { + const res = await fetch(url+'?'+crypto.randomUUID()) + const html = await res.text() + + // Get nodes + const doc = new DOMParser().parseFromString(html, 'text/html') + this.nodesRegistry = {} + for(const tpl of doc.querySelectorAll('template')){ + const rootEl = tpl.content.querySelector('.bzgf-node') + if(!rootEl) continue + this.nodesRegistry[rootEl.dataset.nodetype] = rootEl + } + + // Now load styles (once) + if(!BZgraflow._loadedNodeStyles.has(url)) { + const styles = doc.querySelectorAll('style') + styles.forEach(styleEl => { + const style = document.createElement('style') + style.textContent = styleEl.textContent + document.head.appendChild(style) + }) + BZgraflow._loadedNodeStyles.add(url) + } + } + + addNode(type, id, x, y){ + const nodeDef = this.nodesRegistry[type] + this.stagedNodes[id] = nodeDef.cloneNode(true) + this.stagedNodes[id].style.left = `${x}px` + this.stagedNodes[id].style.top = `${y}px` + this.stagedNodes[id].dataset.id = id + const portEls = this.stagedNodes[id].querySelectorAll('.port') + this.stagedNodes[id].ports = Object.fromEntries(Array.from(portEls).map(item => ([item.dataset.id, { ...item.dataset, el:item }]))) + this.nodesContainer.append(this.stagedNodes[id]) + return(this.stagedNodes[id]) + } + + addWire(idNode1, idPort1, idNode2, idPort2){ + const node1 = this.stagedNodes[idNode1] + const port1 = node1.ports[idPort1] + const node2 = this.stagedNodes[idNode2] + const port2 = node2.ports[idPort2] + const id = `${node1.dataset.id}_${node2.dataset.id}` + const bb1 = port1.el.getBoundingClientRect() + const bb2 = port2.el.getBoundingClientRect() + const x1 = Math.floor(bb1.x + (bb1.width/2)) + const y1 = Math.floor(bb1.y + (bb1.height/2)) + const x2 = Math.floor(bb2.x + (bb2.width/2)) + const y2 = Math.floor(bb2.y + (bb2.height/2)) + + console.log('====>', x1, y1, x2, y2) + this.stagedWires[id] = document.createElementNS('http://www.w3.org/2000/svg', 'path') + this.stagedWires[id].setAttribute('d', this.bezier(x1, y1, port1.direction , x2, y2, port2.direction, 60)) + this.stagedWires[id].setAttribute('fill', 'none') + this.stagedWires[id].classList.add('bzgf-wire') + this.stagedWires[id].dataset.id = id + this.wiresContainer.append(this.stagedWires[id]) + return(this.stagedWires[id]) + } + + refresh(){ + let x = 0 + let y = 0 + for(const node of this.flow.nodes){ + const nodeEl = this.addNode(node.nodeType, node.id , node.coords.x, node.coords.y) + } + for(const link of this.flow.links){ + const [nodeId1, portId1] = link.from + const [nodeId2, portId2] = link.to + this.addWire(nodeId1, portId1, nodeId2, portId2) + } + } + + + bezier(x1, y1, dir1, x2, y2, dir2, tensionMin=60) { + const dirVect = { + n: { x: 0, y: -1 }, + s: { x: 0, y: 1 }, + e: { x: 1, y: 0 }, + w: { x: -1, y: 0 }, + } + const dist = Math.abs(x2 - x1) + Math.abs(y2 - y1) + let tension = dist * 0.4 + if (tension < tensionMin) tension = tensionMin + + const c1x = x1 + (dirVect[dir1].x * tension) + const c1y = y1 + (dirVect[dir1].y * tension) + + const c2x = x2 + (dirVect[dir2].x * tension) + const c2y = y2 + (dirVect[dir2].y * tension) + return `M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}` + } + + +/* +portPosition(nodeEl, portEl) { + const nodeRect = nodeEl.getBoundingClientRect() + const portRect = portEl.getBoundingClientRect() + const canvasRect = this.canvas.getBoundingClientRect() + + return { + x: portRect.left - canvasRect.left + portRect.width / 2, + y: portRect.top - canvasRect.top + portRect.height / 2 + } +} + +*/ + +} +Buildoz.define('graflow', BZgraflow) + +