Skip to content
Snippets Groups Projects
Select Git revision
  • 2b6a75538a10925a9c2fc01de469f81d00c91087
  • master default protected
  • v0.10.0
  • v0.10.0-rc2
  • v0.10.0-rc1
  • v0.9.0
  • v0.9.0-rc1
  • v0.8.0
  • v0.8.0-rc2
  • v0.8.0-rc1
  • v0.7.0
  • v0.7.0-rc2
  • v0.7.0-rc1
  • v0.6.1
  • v0.6.0
  • v0.6.0-rc2
  • v0.6.0-rc1
  • v0.5.0
  • v0.5.0-rc2
  • v0.5.0-rc1
  • v0.4.0
  • v0.4.0-rc2
22 results

flyswatter.cfg

Blame
  • lattice torus 72.89 KiB
    {"modules":{"0.12657158898021215":{"definition":"//\n// frep torus\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep torus'\n//\n// initialization\n//\nvar init = function() {\n   mod.x.value = '0'\n   mod.y.value = '0'\n   mod.z.value = '0'\n   mod.rminor.value = '1'\n   mod.rmajor.value = '2'\n   }\n//\n// inputs\n//\nvar inputs = {\n   variables:{type:'',\n      event:function(evt){\n         for (var p in evt.detail)\n            mod[p].value = evt.detail[p]\n         outputs.variables.event()\n         outputs.shape.event()\n         }}}\n//\n// outputs\n//\nvar outputs = {\n   shape:{type:'',\n      event:function(){\n         var x = parseFloat(mod.x.value)\n         var y = parseFloat(mod.y.value)\n         var z = parseFloat(mod.z.value)\n         var rminor = parseFloat(mod.rminor.value)\n         var rmajor = parseFloat(mod.rmajor.value)\n         var fn = `(${rminor}*${rminor}-(Math.pow(${rmajor}-Math.sqrt((X-(${x}))*(X-(${x}))+(Y-(${y}))*(Y-(${y}))),2)+(Z-(${z}))*(Z-(${z}))))`\n         var variables = ['X','Y','Z']\n         var limits = [[x-(rminor+rmajor),x+rminor+rmajor],[y-(rminor+rmajor),y+rminor+rmajor],[z-rminor,z+rminor]]\n         var type = 'Magnitude'\n         var shape = {function:fn,variables:variables,limits:limits,type:type}\n         mods.output(mod,'shape',shape)}\n         },\n   variables:{type:'',\n      event:function(){\n         var x = parseFloat(mod.x.value)\n         var y = parseFloat(mod.y.value)\n         var z = parseFloat(mod.z.value)\n         var rminor = parseFloat(mod.rminor.value)\n         var rmajor = parseFloat(mod.rmajor.value)\n         var vars = {x:x,y:y,z:z,rminor:rminor,rmajor:rmajor}\n         mods.output(mod,'variables',vars)}\n         }}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // x\n   //\n   div.appendChild(document.createTextNode('x: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.x = input\n   //\n   // y\n   //\n   div.appendChild(document.createTextNode(' y: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.y = input\n   div.appendChild(document.createElement('br'))\n   //\n   // z\n   //\n   div.appendChild(document.createTextNode('z: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.z = input\n   div.appendChild(document.createElement('br'))\n   //\n   // minor radius\n   //\n   div.appendChild(document.createTextNode('minor radius: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.rminor = input\n   div.appendChild(document.createElement('br'))\n   //\n   // major radius\n   //\n   div.appendChild(document.createTextNode('major radius: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.rmajor = input\n   div.appendChild(document.createElement('br'))\n   //\n   // output button\n   //\n   var btn = document.createElement('button')\n      btn.style.padding = mods.ui.padding\n      btn.style.margin = 1\n      btn.appendChild(document.createTextNode('output'))\n      btn.addEventListener('click',function(){\n         outputs.variables.event()\n         outputs.shape.event()\n         })\n      div.appendChild(btn)\n   div.appendChild(document.createElement('br'))\n   }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   })\n}())\n","top":"479","left":"931","inputs":{},"outputs":{}},"0.4470203423781617":{"definition":"//\n// frep shell\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep shell'\n//\n// initialization\n//\nvar init = function() {\n   mod.offset.value = '0.5'\n   }\n//\n// inputs\n//\nvar inputs = {\n   shape:{type:'',\n      event:function(evt){\n         mod.shape = evt.detail\n         outputs.shape.event()\n         }}}\n//\n// outputs\n//\nvar outputs = {\n   shape:{type:'',\n      event:function(){\n         var limits = []\n         for (var v = 0; v < mod.shape.limits.length; ++v) {\n            limits[v] = []\n            limits[v][0] = mod.shape.limits[v][0]\n            limits[v][1] = mod.shape.limits[v][1]\n            }\n         var variables = mod.shape.variables\n         var fn = mod.shape.function\n         var offset = parseFloat(mod.offset.value)\n         fn = `Math.min((${offset})-(${fn}),${fn})`\n         var shape = {function:fn,variables:mod.shape.variables,limits:limits,type:mod.shape.type}\n         mod.fn.value = fn\n         mods.output(mod,'shape',shape)}\n         }}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // offset\n   //\n   div.appendChild(document.createTextNode('offest: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.offset = input\n   div.appendChild(document.createElement('br'))\n   //\n   // function\n   //\n   div.appendChild(document.createTextNode('function: '))\n   div.appendChild(document.createElement('br'))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 10\n      div.appendChild(input)\n      mod.fn = input\n   div.appendChild(document.createElement('br'))\n   //\n   // output button\n   //\n   var btn = document.createElement('button')\n      btn.style.padding = mods.ui.padding\n      btn.style.margin = 1\n      btn.appendChild(document.createTextNode('output'))\n      btn.addEventListener('click',function(){\n         outputs.shape.event()\n         })\n      div.appendChild(btn)\n   }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   })\n}())\n","top":"598","left":"1216","inputs":{},"outputs":{}},"0.11959522713811777":{"definition":"//\n// frep slice\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep slice'\n//\n// initialization\n//\nvar init = function() {\n   mod.x0.value = ''\n   mod.x1.value = ''\n   mod.y0.value = '0'\n   mod.y1.value = ''\n   mod.z0.value = ''\n   mod.z1.value = ''\n   }\n//\n// inputs\n//\nvar inputs = {\n   shape:{type:'',\n      event:function(evt){\n         mod.shape = evt.detail\n         outputs.shape.event()\n         }}}\n//\n// outputs\n//\nvar outputs = {\n   shape:{type:'',\n      event:function(){\n         var limits = []\n         for (var v = 0; v < mod.shape.limits.length; ++v) {\n            limits[v] = []\n            limits[v][0] = mod.shape.limits[v][0]\n            limits[v][1] = mod.shape.limits[v][1]\n            }\n         var variables = mod.shape.variables\n         var fn = mod.shape.function\n         if (mod.x0.value != '') {\n            var x0 = parseFloat(mod.x0.value)\n            var xvar = variables[0]\n            fn = `Math.min((${xvar}-(${x0})),(${fn}))`\n            limits[0][0] = Math.max(limits[0][0],x0)\n            }\n         if (mod.x1.value != '') {\n            var x1 = parseFloat(mod.x1.value)\n            var xvar = variables[0]\n            fn = `Math.min(((${x1})-${xvar}),(${fn}))`\n            limits[0][1] = Math.min(limits[0][1],x1)\n            }\n         if (mod.y0.value != '') {\n            var y0 = parseFloat(mod.y0.value)\n            var yvar = variables[1]\n            fn = `Math.min((${yvar}-(${y0})),(${fn}))`\n            limits[1][0] = Math.max(limits[1][0],y0)\n            }\n         if (mod.y1.value != '') {\n            var y1 = parseFloat(mod.y1.value)\n            var yvar = variables[1]\n            fn = `Math.min(((${y1})-${yvar}),(${fn}))`\n            limits[1][1] = Math.min(limits[1][1],y1)\n            }\n         if (mod.z0.value != '') {\n            var z0 = parseFloat(mod.z0.value)\n            var zvar = variables[2]\n            fn = `Math.min((${zvar}-(${z0})),(${fn}))`\n            limits[2][0] = Math.max(limits[2][0],z0)\n            }\n         if (mod.z1.value != '') {\n            var z1 = parseFloat(mod.z1.value)\n            var zvar = variables[2]\n            fn = `Math.min(((${z1})-${zvar}),(${fn}))`\n            limits[2][1] = Math.min(limits[2][1],z1)\n            }\n         var shape = {function:fn,variables:mod.shape.variables,limits:limits,type:mod.shape.type}\n         mod.fn.value = fn\n         mods.output(mod,'shape',shape)}\n         }}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // x0\n   //\n   div.appendChild(document.createTextNode('x0: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.x0 = input\n   //\n   // x1\n   //\n   div.appendChild(document.createTextNode(' x1: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.x1 = input\n   div.appendChild(document.createElement('br'))\n   //\n   // y0\n   //\n   div.appendChild(document.createTextNode('y0: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.y0 = input\n   //\n   // y1\n   //\n   div.appendChild(document.createTextNode(' y1: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.y1 = input\n   div.appendChild(document.createElement('br'))\n   //\n   // z0\n   //\n   div.appendChild(document.createTextNode('z0: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.z0 = input\n   //\n   // z1\n   //\n   div.appendChild(document.createTextNode(' z1: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.z1 = input\n   div.appendChild(document.createElement('br'))\n   //\n   // function\n   //\n   div.appendChild(document.createTextNode('function: '))\n   div.appendChild(document.createElement('br'))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 10\n      div.appendChild(input)\n      mod.fn = input\n   div.appendChild(document.createElement('br'))\n   //\n   // output button\n   //\n   var btn = document.createElement('button')\n      btn.style.padding = mods.ui.padding\n      btn.style.margin = 1\n      btn.appendChild(document.createTextNode('output'))\n      btn.addEventListener('click',function(){\n         outputs.shape.event()\n         })\n      div.appendChild(btn)\n   }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   })\n}())\n","top":"495","left":"1516","inputs":{},"outputs":{}},"0.16851711510462064":{"definition":"//\n// frep lattice\n//    todo: continuous open-cell distance\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep lattice'\n//\n// initialization\n//\nvar init = function() {\n   mod.pitch.value = '.2'\n   mod.thickness.value = '.05'\n   mod.xmin.value = '-10'\n   mod.ymin.value = '-10'\n   mod.zmin.value = '-10'\n   mod.xmax.value = '10'\n   mod.ymax.value = '10'\n   mod.zmax.value = '10'\n   mod.opencell.checked = false\n   mod.closedcell.checked = true\n   }\n//\n// inputs\n//\nvar inputs = {\n   variables:{type:'',\n      event:function(evt){\n         for (var p in evt.detail)\n            mod[p].value = evt.detail[p]\n         outputs.variables.event()\n         outputs.shape.event()\n         }}}\n//\n// outputs\n//\nvar outputs = {\n   shape:{type:'',\n      event:function(){\n         var pitch = parseFloat(mod.pitch.value)\n         var thickness = parseFloat(mod.thickness.value)\n         var xmin = parseFloat(mod.xmin.value)\n         var xmax = parseFloat(mod.xmax.value)\n         var ymin = parseFloat(mod.ymin.value)\n         var ymax = parseFloat(mod.ymax.value)\n         var zmin = parseFloat(mod.zmin.value)\n         var zmax = parseFloat(mod.zmax.value)\n         var xfn = `(${thickness}-((X-(${xmin}))%${pitch}))`\n         var yfn = `(${thickness}-((Y-(${ymin}))%${pitch}))`\n         var zfn = `(${thickness}-((Z-(${zmin}))%${pitch}))`\n         if (mod.opencell.checked)\n            var fn = `(Math.sign(${xfn})+Math.sign(${yfn})+Math.sign(${zfn})-0.5)`\n         else\n            var fn = `Math.max(Math.max(${xfn},${yfn}),${zfn})`\n         var xfn = `Math.min(X-(${xmin}),(${xmax})-X)`\n         var yfn = `Math.min(Y-(${ymin}),(${ymax})-Y)`\n         var zfn = `Math.min(Z-(${zmin}),(${zmax})-Z)`\n         var fn = `Math.min(Math.min(Math.min(${xfn},${yfn}),${zfn}),${fn})`\n         var variables = ['X','Y','Z']\n         var limits = [[xmin,xmax],[ymin,ymax],[zmin,zmax]]\n         var type = 'Magnitude'\n         var shape = {function:fn,variables:variables,limits:limits,type:type}\n         mods.output(mod,'shape',shape)}\n         },\n   variables:{type:'',\n      event:function(){\n         var pitch = parseFloat(mod.pitch.value)\n         var thickness = parseFloat(mod.thickness.value)\n         var xmin = parseFloat(mod.xmin.value)\n         var xmax = parseFloat(mod.xmax.value)\n         var ymin = parseFloat(mod.ymin.value)\n         var ymax = parseFloat(mod.ymax.value)\n         var zmin = parseFloat(mod.zmin.value)\n         var zmax = parseFloat(mod.zmax.value)\n         var vars = {pitch:pitch,thickness:thickness,xmin:xmin,ymin:ymin,zmin:zmin,xmax:xmax,ymax:ymax,zmax:zmax}\n         mods.output(mod,'variables',vars)}\n         }}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // pitch\n   //\n   div.appendChild(document.createTextNode('pitch: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.pitch = input\n   //\n   // thickness\n   //\n   div.appendChild(document.createTextNode(' thickness: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.thickness = input\n   div.appendChild(document.createElement('br'))\n   //\n   // xmin\n   //\n   div.appendChild(document.createTextNode('xmin: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.xmin = input\n   //\n   // xmax\n   //\n   div.appendChild(document.createTextNode(' xmax: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.xmax = input\n   div.appendChild(document.createElement('br'))\n   //\n   // ymin\n   //\n   div.appendChild(document.createTextNode('ymin: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.ymin = input\n   //\n   // ymax\n   //\n   div.appendChild(document.createTextNode(' ymax: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.ymax = input\n   div.appendChild(document.createElement('br'))\n   //\n   // zmin\n   //\n   div.appendChild(document.createTextNode('zmin: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.zmin = input\n   //\n   // zmax\n   //\n   div.appendChild(document.createTextNode(' zmax: '))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 3\n      div.appendChild(input)\n      mod.zmax = input\n   div.appendChild(document.createElement('br'))\n   //\n   // type\n   //\n   div.appendChild(document.createTextNode('open cell'))\n   var input = document.createElement('input')\n      input.type = 'radio'\n      input.name = mod.div.id+'axis'\n      div.appendChild(input)\n      mod.opencell = input\n   div.appendChild(document.createTextNode(' closed cell'))\n   var input = document.createElement('input')\n      input.type = 'radio'\n      input.name = mod.div.id+'axis'\n      div.appendChild(input)\n      mod.closedcell = input\n   div.appendChild(document.createElement('br'))\n   //\n   // output button\n   //\n   var btn = document.createElement('button')\n      btn.style.padding = mods.ui.padding\n      btn.style.margin = 1\n      btn.appendChild(document.createTextNode('output'))\n      btn.addEventListener('click',function(){\n         outputs.variables.event()\n         outputs.shape.event()\n         })\n      div.appendChild(btn)\n   }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   })\n}())\n","top":"800","left":"928","inputs":{},"outputs":{}},"0.5368438375786873":{"definition":"//\n// frep intersect\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep intersect'\n//\n// initialization\n//\nvar init = function() {\n   mod.shape0 = null\n   mod.shape1 = null\n   mod.fn0.value = 'Math.min((0.5)-((1*1-(Math.pow(2-Math.sqrt((X-(0))*(X-(0))+(Y-(0))*(Y-(0))),2)+(Z-(0))*(Z-(0))))),(1*1-(Math.pow(2-Math.sqrt((X-(0))*(X-(0))+(Y-(0))*(Y-(0))),2)+(Z-(0))*(Z-(0)))))'\n   mod.fn1.value = 'Math.min(Math.min(Math.min(Math.min(X-(-10),(10)-X),Math.min(Y-(-10),(10)-Y)),Math.min(Z-(-10),(10)-Z)),Math.max(Math.max((0.05-((X-(-10))%0.2)),(0.05-((Y-(-10))%0.2))),(0.05-((Z-(-10))%0.2))))'\n   }\n//\n// inputs\n//\nvar inputs = {\n   shape0:{type:'',label:'shape 0',\n      event:function(evt){\n         mod.shape0 = evt.detail\n         mod.fn0.value = evt.detail.function\n         outputs.shape.event()\n         }},\n   shape1:{type:'',label:'shape 1',\n      event:function(evt){\n         mod.shape1 = evt.detail\n         mod.fn1.value = evt.detail.function\n         outputs.shape.event()\n         }},\n   clear:{type:'',\n      event:function(evt){\n         mod.shape0 = null\n         mod.shape1 = null\n         mod.fn0.value = ''\n         mod.fn1.value = ''\n         }}}\n//\n// outputs\n//\nvar outputs = {\n   shape:{type:'',\n      event:function(){\n         if ((mod.shape0 != null) && (mod.shape1 != null)) {\n            var fn = `Math.min(${mod.shape0.function},${mod.shape1.function})`\n            var variables = mod.shape0.variables\n            var type = mod.shape0.type        \n            var limits = []\n            for (var v = 0; v < mod.shape0.limits.length; ++v) {\n               limits[v] = []\n               limits[v][0] = Math.max(mod.shape0.limits[v][0],\n                  mod.shape1.limits[v][0])\n               limits[v][1] = Math.min(mod.shape0.limits[v][1],\n                  mod.shape1.limits[v][1])\n               }\n            var shape = {function:fn,variables:variables,limits:limits,type:type}\n            mods.output(mod,'shape',shape)}\n            }\n         }}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // function 0\n   //\n   div.appendChild(document.createTextNode('function 0: '))\n   div.appendChild(document.createElement('br'))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 10\n      div.appendChild(input)\n      mod.fn0 = input\n   div.appendChild(document.createElement('br'))\n   //\n   // function 1\n   //\n   div.appendChild(document.createTextNode('function 1: '))\n   div.appendChild(document.createElement('br'))\n   var input = document.createElement('input')\n      input.type = 'text'\n      input.size = 10\n      div.appendChild(input)\n      mod.fn1 = input\n   div.appendChild(document.createElement('br'))\n   }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   })\n}())\n","top":"836","left":"1472","inputs":{},"outputs":{}},"0.3914434415667569":{"definition":"//\n// construct object\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'render'\n//\n// initialization\n//\nvar init = function() {\n   mod.out0.value = '{}'\n   }\n//\n// inputs\n//\nvar inputs = {}\n//\n// outputs\n//\nvar outputs = {\n   out0:{type:'',label:'output 0',\n      event:function(arg){\n         mods.output(mod,'out0',arg)\n         }}}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // outputs\n   //\n   div.appendChild(document.createTextNode('output 0:'))\n   div.appendChild(document.createElement('br'))\n   var text = document.createElement('textarea')\n      text.setAttribute('rows',1)\n      text.setAttribute('cols',mods.ui.cols)\n      div.appendChild(text)\n      mod.out0 = text\n   div.appendChild(document.createElement('br'))\n   //\n   // output button\n   //\n   var btn = document.createElement('button')\n      btn.style.padding = mods.ui.padding\n      btn.style.margin = 1\n      btn.appendChild(document.createTextNode('output'))\n      btn.addEventListener('click',function(){\n         construct_output()\n         })\n      div.appendChild(btn)\n   }\n//\n// local functions\n//\nfunction construct_output() {\n   eval('out0 ='+mod.out0.value)\n   outputs.out0.event(out0)\n   }\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   })\n}())\n","top":"610.7831800789872","left":"528.2527233815314","inputs":{},"outputs":{}},"0.8062301007085344":{"definition":"//\n// frep GPU volume renderer\n//\n// Neil Gershenfeld and Amira Abdel-Rahman\n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {};\n//\n// name\n//\nvar name = 'render GPU';\n//\n// initialization\n//\nvar init = function() {\n   mod.steps.value=256.0;\n   mod.alphaCorrection=10.0;\n   mod.rendType=\"0\";\n   mod.windowOpen=false;\n   mod.xLimit1 =-1.0 ;\n   mod.xLimit2 =1.0 ; \n   mod.yLimit1 =-1.0 ; \n   mod.yLimit2 =1.0 ; \n   mod.zLimit1 =-1.0 ; \n   mod.zLimit2 =1.0 ;\n   mod.height=10.0;\n   mod.width=10.0;\n   mod.rendPerformance=0;\n   };\n//\n// inputs\n//\nvar inputs = {\n   shape:{type:'frep',\n   event:function(evt){\n\n      mod.shape=evt.detail;\n\n      // outputs.messageLog.event(mod.shape.limits);\n\n      //get largerst range and rescale other ones to adjust limit mapping\n      var tempIndex=0;\n      var tempMax=-1.0;\n\n      for(i=0;i<mod.shape.limits.length;i++)\n      {\n         if((mod.shape.limits[i][1]-mod.shape.limits[i][0]) >= tempMax )\n         {\n            tempIndex=i;\n            tempMax=mod.shape.limits[i][1]-mod.shape.limits[i][0];\n         }\n      }\n      for(i=0;i < mod.shape.limits.length;i++)\n      {\n         if(i!=tempIndex)\n         {\n            var tempDif = (mod.shape.limits[tempIndex][1]-mod.shape.limits[tempIndex][0])-(mod.shape.limits[i][1]-mod.shape.limits[i][0]);\n            mod.shape.limits[i][0]-=tempDif/2.0;\n            mod.shape.limits[i][1]+=tempDif/2.0;\n            \n         }\n      }\n\n      mod.xLimit1=mod.shape.limits[0][0] ;\n      mod.xLimit2=mod.shape.limits[0][1] ; \n      mod.yLimit1=mod.shape.limits[1][0] ; \n      mod.yLimit2=mod.shape.limits[1][1] ; \n      mod.zLimit1=mod.shape.limits[2][0] ; \n      mod.zLimit2=mod.shape.limits[2][1] ;\n      \n      //\n      //turn function string to glsl\n\t  //\n\t  \n\t  //remove all Math.\n      var str1 = mod.shape.function;\n\t  str1=str1.replace(/Math./g, '');\n\t  \n\t  //change atan2 functions to atan\n\t  str1=str1.replace(/atan2/g, \"atan\");\n         \n      //change all % to mod(,)\n      while(str1.indexOf(\"%\")>-1) //While '%' is there\n      {\n         //get location\n         var modLocation=str1.indexOf(\"%\");\n         //replace with ','\n         str1=str1.replace(/%/, \",\");\n         outputs.messageLog.event(\"1:\"+str1);\n\n         //parse before\n         var counterBefore=modLocation;\n         var count=0;\n         if(str1[--counterBefore]==')')\n         {\n            count++;\n            while(count>0)\n            {\n               counterBefore--;\n               if(str1[counterBefore]==')')\n               {\n                  count++;\n\n               }else if (str1[counterBefore]=='(')\n               {\n                  count--;\n               }\n            }\n         }else{\n            while(!isNaN(str1[counterBefore]) ||(str1[counterBefore]=='.')||(str1[counterBefore]=='X') ||(str1[counterBefore]=='Y')||(str1[counterBefore]=='Z'))\n            {\n               counterBefore--;\n            }\n\n         }\n         \n         \n         //parse after\n         var counterAfter=modLocation;\n         count=0;\n         if(str1[++counterAfter]=='(')\n         {\n            count++;\n            while(count>0)\n            {\n               counterAfter++;\n               if(str1[counterAfter]=='(')\n               {\n                  count++;\n\n               }else if (str1[counterAfter]==')')\n               {\n                  count--;\n               }\n            }\n         }else\n         {\n            while(!isNaN(str1[counterAfter]) ||(str1[counterAfter]=='.')||(str1[counterAfter]=='X') ||(str1[counterAfter]=='Y')||(str1[counterAfter]=='Z'))\n            {\n               counterAfter++;\n            }\n         }\n         \n         str1 = str1.substr(0, counterAfter) + \")\" + str1.substr(counterAfter);\n         str1 = str1.substr(0, counterBefore) + \"mod(\" + str1.substr(counterBefore);\n      }\n\n      //turn all ints to floatS\n      var str='';\n      for(var i=0;i<str1.length;i++)\n      {\n         //if number\n         if(!isNaN(str1[i]))\n         {\n            str+=str1[i];\n            //check next value\n            for(var j=i+1;j<str1.length;j++)\n            {\n            //if number add and continue\n            if(!isNaN(str1[j])) \n            {\n               str+=str1[j];\n               i=j;\n            }\n            //else if dot add and add numbers till NaN\n            else if(str1[j]=='.')\n            {\n               str+=str1[j];\n               i=j;\n               //add till not num\n               for(var k=j+1;k<str1.length;k++)\n               {\n                  if( ( !isNaN(str1[k]) )||str1[k]=='e')\n                  {\n                     //fix for scientific notation\n                     if(str1[k]=='e' && str1[k+1]=='-')\n                     {\n                        str+=str1[k];\n                        i=k;\n\n                        k++;\n\n                        str+=str1[k];\n                        i=k;\n\n                     }else\n                     {\n                        str+=str1[k];\n                        i=k;\n\n                     }\n                     \n                  }\n                  else\n                  {\n                     k=str1.length;\n                  }\n               }\n               j=str1.length;\n            }\n            //else add .0 and go to next number\n            else\n            {\n               str+='.';\n               str+='0';\n               j=str1.length;\n            }\n            }\n\n         }\n         else\n         {\n            str+=str1[i];\n         }\n      }\n      \n      mod.str=str;\n      outputs.messageLog.event(str);\n\n      //if window open update shader function\n      if(mod.windowOpen)\n      {\n         mod.updateShaderFunction();\n      }\n\n      }}};\n//\n// outputs\n//\nvar outputs = {\n    messageLog:{type:'string',\n      event:function(mess){\n      //show processed function\n        mods.output(mod,'messageLog',mess);\n      }\n    }\n}\n//\n// interface\n//\nvar interface = function(div){\n   mod.div = div\n   //\n   // on-screen drawing canvas\n   //\n   var canvas = document.createElement('canvas');\n      canvas.width = mods.ui.canvas;\n      canvas.height = mods.ui.canvas;\n      canvas.style.backgroundColor = 'rgb(0,0,0)';\n      div.appendChild(canvas);\n      mod.canvas = canvas;\n   div.appendChild(document.createElement('br'));\n   //\n   // resolution\n   //\n   div.appendChild(document.createTextNode('resolution: '));\n   var input = document.createElement('input');\n      input.type = 'text';\n      input.size = 3;\n      input.addEventListener('input',function(){\n         if(mod.windowOpen)\n         {\n            mod.redraw(true);\n         }\n         });\n      div.appendChild(input);\n      mod.steps = input;\n   div.appendChild(document.createElement('br'));\n   //\n   // adaptive rendering\n   //\n   div.appendChild(document.createTextNode('rendering performance: '))\n            var input = document.createElement('SELECT');\n            \n         input.setAttribute(\"id\", \"rend-adpselect\");\n         \n         //select menu for functions\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"0\");\n         var t = document.createTextNode('constant');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"1\");\n         var t = document.createTextNode('adaptive');\n         z.appendChild(t);\n         input.appendChild(z);\n         input.addEventListener('change',function(evt){\n            var temp= document.getElementById(\"rend-adpselect\");\n            mod.rendPerformance=parseInt(temp.value);\n            mod.updateShaderFunction();\n            });\n\n         div.appendChild(input);\n  \n   div.appendChild(document.createElement('br'));\n   //\n   // rendering style\n   //\n   div.appendChild(document.createTextNode('rendering style: '))\n            var input = document.createElement('SELECT');\n            \n         input.setAttribute(\"id\", \"rend-select\");\n         \n         //select menu for functions\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"0\");\n         var t = document.createTextNode('default');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"1\");\n         var t = document.createTextNode('xray');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"2\");\n         var t = document.createTextNode('height map (fixed)');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"3\");\n         var t = document.createTextNode('height map (variable)');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"4\");\n         var t = document.createTextNode('normals');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"5\");\n         var t = document.createTextNode('light');\n         z.appendChild(t);\n         input.appendChild(z);\n\n         var z = document.createElement(\"option\");\n         z.setAttribute(\"value\", \"6\");\n         var t = document.createTextNode('specular');\n         z.appendChild(t);\n         input.appendChild(z);\n       \n         input.addEventListener('change',function(evt){\n            var temp= document.getElementById(\"rend-select\");\n            mod.rendType=String(parseInt(temp.value));\n            mod.updateShaderFunction();\n            });\n\n         div.appendChild(input);\n   div.appendChild(document.createElement('br'));\n  \n   //\n   // view\n   //   \n   div.appendChild(document.createElement('br'))  ; \n   var btn = document.createElement('button');\n      btn.style.padding = mods.ui.padding;\n      btn.style.margin = 1;\n      var span = document.createElement('span');\n         var text = document.createTextNode('view');\n            span.appendChild(text);\n         btn.appendChild(span);\n      btn.addEventListener('click',function(){\n      mod.windowOpen=true; \n         open_view_window();\n         });\n      div.appendChild(btn);\n}\n\n//\n// local functions\n//\n \n//\n// open_view_window\n//\nfunction open_view_window() {\n    //\n    // globals\n    //\n    var container;\n    var camera, sceneFirstPass, sceneSecondPass, renderer;\n    var containerAxes, cameraAxes , sceneAxes, rendererAxes,axes,sphereO;\n    var rtTexture;\n    var materialSecondPass;\n    var center;\n    var meshSecondPass;\n    var boxGeometry;\n    var gridHelper;\n    var gridHelpersSize=5;\n    var clock;\n    var delta=0;\n    var interval=10;\n    var frameID;\n\n    //\n    // functions\n    //\n   \n    addShaderScripts();\n    open_window();\n   \n    //\n    // open_window\n    //\n    function open_window() \n    {\n      //\n      // open window\n      //\n      win = window.open('');\n      mod.win = win;\n\n      //\n      // load three.js\n      //\n      var script = document.createElement('script');\n      script.type = 'text/javascript';\n      script.onload = init_window;\n      script.src = 'js/three.js/three.min.js';\n      mod.div.appendChild(script);\n    }\n\n      //\n      // add shader scripts to html\n      //\n      function addShaderScripts() \n      {\n\n            /////////////////////////fragmentShaderFirstPass////////////////////////////////////\n\n            var div = document.createElement('script');\n\n            div.id = 'fragmentShaderFirstPass';\n            div.type = 'x-shader/x-fragment';\n\n            div.innerHTML =\n            `\n                  varying vec3 worldSpaceCoords;\n\n                  void main()\n                  {\n                  //The fragment's world space coordinates as fragment output.\n                  gl_FragColor = vec4( worldSpaceCoords.x , worldSpaceCoords.y, worldSpaceCoords.z, 1 );\n                  }\n                  `;\n            \n            //\n            mod.div.appendChild(div);\n            \n            /////////////////////////vertexShaderFirstPass////////////////////////////////////\n            var div = document.createElement('script');\n\n            div.id = 'vertexShaderFirstPass';\n            div.type = 'x-shader/x-vertex';\n\n            div.innerHTML =\n            `\n                  varying vec3 worldSpaceCoords;\n\n                  void main()\n                  {\n                  //Set the world space coordinates of the back faces vertices as output.\n                  worldSpaceCoords = position + vec3(0.5, 0.5, 0.5); //move it from [-0.5;0.5] to [0,1]\n                  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n                  }\n                  `;\n            \n            //\n            mod.div.appendChild(div);\n            /////////////////////////fragmentShaderSecondPass////////////////////////////////////\n            var div = document.createElement('script');\n\n            div.id = 'fragmentShaderSecondPass';\n            div.type = 'x-shader/x-fragment';\n\n            \n            div.innerHTML=fragmentShaderSecondPass();\n            mod.div.appendChild(div);\n\n            /////////////////////vertexShaderSecondPass///////////////////\n            var div = document.createElement('script');\n\n            div.id = 'vertexShaderSecondPass';\n            div.type = 'x-shader/x-vertex';\n\n            div.innerHTML =\n            `\n                  varying vec3 worldSpaceCoords;\n                  varying vec4 projectedCoords;\n\n\n                  void main()\n                  {\n                  \n                  worldSpaceCoords = (modelMatrix * vec4(position + vec3(0.5, 0.5,0.5), 1.0 )).xyz;\n                  gl_Position = projectionMatrix *  modelViewMatrix * vec4( position, 1.0 );\n                  projectedCoords =  projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n                  }\n                  `;\n            //\n            mod.div.appendChild(div);\n      }\n   \n   //\n   // fragment shader (the one that does all the work)\n   //\n   function fragmentShaderSecondPass()\n   {\n      var txt =\n         `\n            const float PI = 3.1415926535897932384626433832795;\n            #define rendType `+mod.rendType+`\n            varying vec3 worldSpaceCoords;\n            varying vec4 projectedCoords;\n            uniform sampler2D tex;\n            uniform float steps;\n            uniform float alphaCorrection;\n            // uniform float rendType;\n            uniform vec3 cameraPos;\n            // The maximum distance through our rendering volume is sqrt(3).\n            // The maximum number of steps we take to travel a distance of 1 is 512.\n            // ceil( sqrt(3) * 512 ) = 887\n            // This prevents the back of the image from getting cut off when steps=512 & viewing diagonally.\n            const int MAX_STEPS = 887;\n            uniform float xLimit1;\n            uniform float xLimit2;\n            uniform float yLimit1;\n            uniform float yLimit2;\n            uniform float zLimit1;\n            uniform float zLimit2;\n            float orgMin=0.0;\n            float orgMax=1.0;\n            vec3 viewDirection;\n            \n\n            float map(vec3 p)\n            {\n               float X= p.x;\n               float Y= p.y;\n               float Z= p.z;\n\n               return `+mod.str+`;\n            }\n            vec3 simpleLambert (vec3 normal) {\n               vec3 lightDir = vec3(0.2,-0.6,-0.4);   // Light direction\n               vec3 lightDir1 = vec3(0.4, 0.6,-0.4);  // Light direction\n               vec3 lightCol = vec3(0.5,0.5,0.5);     // Light color\n               vec3 _Color=vec3(0.2,0.5,0.8);\n               float lightIntensity = 3.0;\n               float ambient = 0.2;\n               \n               float NdotL = max(dot(normalize(normal), normalize(lightDir)),0.0) * lightIntensity;\n               float NdotL1 = max(dot(normalize(normal), normalize(lightDir1)),0.0) *lightIntensity;\n\n               vec3 c=vec3(0.0,0.0,0.0);\n\n               c.rgb = _Color * lightCol * (NdotL + NdotL1)+ ambient ;\n\n               return c;\n            }\n            vec3 specular (vec3 normal) {\n               vec3 lightDir = vec3(0.2,-0.6,-0.4);   // Light direction\n               vec3 lightDir1 = vec3(0.4, 0.6,-0.4);  // Light direction\n               vec3 lightCol = vec3(0.5,0.5,0.5);     // Light color\n               vec3 _Color=vec3(0.2,0.5,0.8);\n               float lightIntensity=3.0;\n               float ambient = 0.2;\n\n               float _SpecularPower=0.7;\n               float _Gloss=0.7;\n               \n               float NdotL = max(dot(normalize(normal ), normalize(lightDir)),0.0)*lightIntensity;\n               float NdotL1 = max(dot(normalize(normal), normalize(lightDir1)),0.0)*lightIntensity;\n               vec3 c;\n               vec3 camera= cameraPos-0.5;\n\n               float t= dot(normalize(lightDir), normalize( -camera));\n               float tt=(dot(normalize(normal), normalize(-camera)));\n               float s= ( t*_Gloss + tt*_SpecularPower)/lightIntensity;\n\n               float t1= dot(normalize(lightDir1), normalize( -camera));\n               float tt1=(dot(normalize(normal), normalize(-camera)));\n               float s1= ( t1*_Gloss * tt1*_SpecularPower)/2.0;\n\n               // float s = pow( dot(normalize(normal),h), _SpecularPower) * _Gloss;\n               // h.x= (h.x - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n               // h.y= (h.y - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n               // h.z= (h.z - orgMin) * ((1.0) - (-1.0)) / (orgMax - orgMin) + (-1.0);\n               // vec3 h1 =  (lightDir1 + camera)/2.0;\n               // float s1 = pow( dot(normalize(normal)/2.0,h1), _SpecularPower) * _Gloss;\n\n               c.rgb = _Color * lightCol * (NdotL+NdotL1)+s + s1+ ambient;\n               return c;\n            }\n            vec3 frontLight (vec3 normal) {\n               \n                  vec3 camera= cameraPos-0.5;\n                  float t=dot(normalize(normal), normalize(-camera));\n                  vec3 c;\n                  c = vec3(t,t,t);\n                  return c;\n            }\n\n            vec3 ClosestPointOnLine(vec3 start ,vec3 direction ,vec3 vPoint )\n            {\n               vec3 vVector1 = vPoint - start;\n               vec3 vVector2 = normalize(direction);\n            \n               float t = dot(vVector2, vVector1);\n               if (t <= 0.0)\n               {\n                  return start;\n               }\n                  \n               vec3 vVector3 = vVector2 * t;\n            \n               vec3 vClosestPoint = start + vVector3;\n               return vClosestPoint;\n            }\n            vec3 GetClosetPoint( vec3 A, vec3 B, vec3 P, bool segmentClamp)\n            {\n               vec3 AP = P - A;\n               vec3 AB = B - A; \n               float ab2 = AB.x*AB.x + AB.y*AB.y;\n               float apab = AP.x*AB.x + AP.y*AB.y;\n               float t = apab / ab2;\n               if (segmentClamp)\n               {\n                  if (t < 0.0) t = 0.0;\n                  else if (t > 1.0) t = 1.0;\n               }\n               vec3 Closest = A + AB * t;\n               return Closest;\n            }\n            vec3 calcNormal( in vec3 pos )\n            {\n                  // vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;\n                  // return normalize( e.xyy*map( pos + e.xyy ) + \n                  //                         e.yyx*map( pos + e.yyx ) + \n                  //                         e.yxy*map( pos + e.yxy ) + \n                  //                         e.xxx*map( pos + e.xxx ) );\n                  \n                  // vec3 eps = vec3( 0.0005, 0.0, 0.0 );\n                  // vec3 nor = vec3(\n                  //       map(pos+eps.xyy) - map(pos-eps.xyy),\n                  //       map(pos+eps.yxy) - map(pos-eps.yxy),\n                  //       map(pos+eps.yyx) - map(pos-eps.yyx) );\n                  // return normalize(nor);\n\n                  const float eps = 0.01;\n                  vec3 n;\n                  n.x=map(pos + vec3(eps, 0, 0)   ) - map(pos - vec3(eps, 0, 0));\n                  n.y=map(pos + vec3(0, eps, 0)   ) - map(pos - vec3(0, eps, 0));\n                  n.z=map(pos + vec3(0, 0, eps)   ) - map(pos - vec3(0, 0, eps));\n                  //problem with \n                  // n.x=result - map(pos - vec3(eps, 0, 0));\n                  // n.y=result - map(pos - vec3(0, eps, 0));\n                  // n.z=result - map(pos - vec3(0, 0, eps));\n                  return normalize(n);\n                  \n            }\n\n            //Acts like a texture3D using Z slices and trilinear filtering.\n            vec4 sampleAs3DTextureCustom( vec3 texCoord )\n            { \n               float X= (texCoord.x - orgMin) * (xLimit2 - xLimit1) / (orgMax - orgMin) + xLimit1;\n               float Y= (texCoord.y - orgMin) * (yLimit2 - yLimit1) / (orgMax - orgMin) + yLimit1;\n               float Z= (texCoord.z - orgMin) * (zLimit2 - zLimit1) / (orgMax - orgMin) + zLimit1;\n\n               //slice color red\n               vec4 m;\n               m=vec4(0.0,0.0,0.0,0.0);\n\n               float result=`+mod.str+`;\n               if(result>0.0)\n               {\n                  m.a=1.0;\n                  vec3 p=vec3(X,Y,Z);\n                  vec3 n=calcNormal( p );\n\n                  #if rendType==0\n                  //default\n                     {\n                        float tempConst=0.001;\n                        m.rgb=frontLight(n)+tempConst;\n                     }\n                  #elif rendType==1\n                  //xray\n                     {\n                        m=vec4(1.0,1.0,1.0,0.01);\n                     }\n                  #elif rendType==2\n                  //height map\n                     {\n                        m.r=texCoord.z;\n                        m.g=texCoord.z;\n                        m.b=texCoord.z;\n                     }\n                  #elif rendType==3\n                  //depth/height map variable\n                     {\n                        vec3 cp=ClosestPointOnLine(-cameraPos,cameraPos,texCoord);\n                        float d= (distance(cp, normalize(cameraPos)*2.0));\n                        m.r=d;\n                        m.g=d;\n                        m.b=d;\n                     }\n                  #elif rendType==4\n                  //normals\n                     {\n                        m.r= (n.r - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n                        m.g= (n.g - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n                        m.b= (n.b - (-1.0)) * (1.0 - 0.0) / (1.0 - (-1.0)) + 0.0;\n                     }\n                  #elif rendType==5\n                  //fixed lights\n                     {\n                        float tempConst=0.05;\n                        m.rgb=simpleLambert (n)+tempConst;\n                     }\n                  #elif rendType==6\n                  //fixed lights specular\n                     {\n                        float tempConst=0.00;\n                        m.rgb=specular (n)+tempConst;\n                     }\n                  #endif\n                  \n               }\n               return m ;\n            }\n            \n            void main( void ) {\n\n               //Transform the coordinates it from [-1;1] to [0;1]\n               vec2 texc = vec2(((projectedCoords.x / projectedCoords.w) + 1.0 ) / 2.0,\n                           ((projectedCoords.y / projectedCoords.w) + 1.0 ) / 2.0 );\n\n               //The back position is the world space position stored in the texture.\n               vec3 backPos = texture2D(tex, texc).xyz;\n\n               //The front position is the world space position of the second render pass.\n               vec3 frontPos = worldSpaceCoords;\n\n               //The direction from the front position to back position.\n               vec3 dir = backPos - frontPos;\n               \n               float rayLength = length(dir);\n\n               //Calculate how long to increment in each step.\n               float delta = 1.0 / steps;\n\n               //The increment in each direction for each step.\n               vec3 deltaDirection = normalize(dir) * delta;\n\n               viewDirection=normalize(dir);//amira added\n\n               float deltaDirectionLength = length(deltaDirection);\n\n               //Start the ray casting from the front position.\n               vec3 currentPosition = frontPos;\n\n               //The color accumulator.\n               vec4 accumulatedColor = vec4(0.0);\n\n               //The alpha value accumulated so far.\n               float accumulatedAlpha = 0.0;\n\n               //How long has the ray travelled so far.\n               float accumulatedLength = 0.0;\n\n               //If we have twice as many samples, we only need ~1/2 the alpha per sample.\n               //Scaling by 256/10 just happens to give a good value for the alphaCorrection slider.\n               float alphaScaleFactor = 25.6 * delta;\n\n               vec4 colorSample;\n               float alphaSample;\n\n               //Perform the ray marching iterations\n               for(int i = 0; i < MAX_STEPS; i++)\n               {\n                  //Get the voxel intensity value from the 3D texture.\n                  colorSample = sampleAs3DTextureCustom( currentPosition );\n\n                  //Allow the alpha correction customization.\n                  alphaSample = colorSample.a * alphaCorrection;\n\n                  //Applying this effect to both the color and alpha accumulation results in more realistic transparency.\n                  alphaSample *= (1.0 - accumulatedAlpha);\n\n                  //Scaling alpha by the number of steps makes the final color invariant to the step size.\n                  alphaSample *= alphaScaleFactor;\n\n                  //Perform the composition.\n                  accumulatedColor += colorSample * alphaSample;\n\n                  //Store the alpha accumulated so far.\n                  accumulatedAlpha += alphaSample;\n\n                  //Advance the ray.\n                  currentPosition += deltaDirection;\n                  accumulatedLength += deltaDirectionLength;\n\n                  //If the length traversed is more than the ray length, or if the alpha accumulated reaches 1.0 then exit.\n                  if(accumulatedLength >= rayLength || accumulatedAlpha >= 1.0 )\n                     break;\n               }\n\n               gl_FragColor  = accumulatedColor;\n\n            }\n            `;\n      return txt;\n   }\n\n    //\n    // init_window\n    //\n   function init_window() {\n      //\n      // close button\n      //\n      var btn = document.createElement('button');\n         btn.appendChild(document.createTextNode('close'));\n         btn.style.padding = mods.ui.padding;\n         btn.style.margin = 1;\n         btn.addEventListener('click',function(){\n            win.close();\n            mod.win = undefined;\n         });\n         win.document.body.appendChild(btn);\n      //\n      // label text\n      //\n      var text = win.document.createTextNode(' left: pan, right: rotate, scroll: zoom');\n         win.document.body.appendChild(text);\n      //\n      // GL container\n      //\n      win.document.body.appendChild(document.createElement('br')) ;  \n      container = win.document.createElement('div');\n      container.style.overflow = 'hidden';\n      win.document.body.appendChild(container);\n\n      ///////////////////////////////////////////axes////////////////////////////\n      //GL Axes Container\n      // win.document.body.appendChild(document.createElement('br')) ;  \n      containerAxes = win.document.createElement('div');\n      containerAxes.style.overflow = 'hidden';\n      containerAxes.style.position = 'absolute';\n      containerAxes.style.zIndex = 100;\n      containerAxes.style.left = 0;\n      containerAxes.style.bottom = 0;\n      containerAxes.style.margin = 20;\n      win.document.body.appendChild(containerAxes);\n      //\n      //cameraAxes\n      //\n      cameraAxes = new THREE.PerspectiveCamera( 50, 100 / 100, 1, 1000 );\n      cameraAxes.up = new THREE.Vector3(0, 0, 1);\n      //\n      //rendererAxes\n      //\n      rendererAxes = new THREE.WebGLRenderer({ alpha: true } );\n      rendererAxes.setClearColor( 0x000000, 0 );\n      rendererAxes.setSize( 100, 100 );\n      containerAxes.appendChild( rendererAxes.domElement );\n      //\n      //sceneAxes\n      //\n      sceneAxes=new THREE.Scene();\n      axes = new THREE.AxesHelper( 100 );\n      sceneAxes.add( axes );   \n\n      ///////////////////////////////////////////////////////////////////////////////////\n      \n      //\n      //camera\n      //\n      camera = new THREE.PerspectiveCamera( 40, win.innerWidth / win.innerHeight, 0.01, 3000.0 );\n      camera.position.z = 2.0;\n      camera.aspect = win.innerWidth / win.innerHeight;\n      camera.up = new THREE.Vector3(0, 0, 1);\n      camera.position.x = 5;\n      camera.lookAt(new THREE.Vector3(0,0,0));\n      camera.updateProjectionMatrix();\n      center= new THREE.Vector3(0,0,0);\n\n      \n      \n      //\n      //setup textures and scenes\n      //\n      var screenSize = new THREE.Vector2( win.innerWidth, win.innerHeight );\n      rtTexture = new THREE.WebGLRenderTarget( screenSize.x, screenSize.y,\n                                    {  minFilter: THREE.LinearFilter,\n                                       magFilter: THREE.LinearFilter,\n                                       wrapS:  THREE.ClampToEdgeWrapping,\n                                       wrapT:  THREE.ClampToEdgeWrapping,\n                                       format: THREE.RGBAFormat,\n                                       type: THREE.FloatType,\n                                       generateMipmaps: false} );\n\n\n      var materialFirstPass = new THREE.ShaderMaterial( {\n         vertexShader: document.getElementById( 'vertexShaderFirstPass' ).textContent,\n         fragmentShader: document.getElementById( 'fragmentShaderFirstPass' ).textContent,\n         side: THREE.BackSide\n      } );\n\n      var lookAtVector = new THREE.Vector3(0,0, -1);\n      lookAtVector.applyQuaternion(camera.quaternion);\n\n      sceneFirstPass = new THREE.Scene();\n      sceneSecondPass = new THREE.Scene();\n\n      var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n      materialSecondPass = new THREE.ShaderMaterial( {\n         vertexShader: document.getElementById( 'vertexShaderSecondPass' ).textContent,\n         fragmentShader: document.getElementById( 'fragmentShaderSecondPass' ).textContent,\n         side: THREE.FrontSide,\n         uniforms: { tex:  { type: \"t\", value: rtTexture },\n                  steps : {type: \"1f\" , value: mod.steps.value }, \n                  xLimit1 : {type: \"1f\" , value: mod.xLimit1 }, \n                  xLimit2 : {type: \"1f\" , value: mod.xLimit2 }, \n                  yLimit1 : {type: \"1f\" , value: mod.yLimit1 }, \n                  yLimit2 : {type: \"1f\" , value: mod.yLimit2 }, \n                  zLimit1 : {type: \"1f\" , value: mod.zLimit1 }, \n                  zLimit2 : {type: \"1f\" , value: mod.zLimit2 }, \n                  alphaCorrection : {type: \"1f\" , value: mod.alphaCorrection},\n                  cameraPos :{value:  tempCam.normalize()} \n               }\n      });\n\n      //HELPER GRID\n      gridHelper = new THREE.GridHelper( gridHelpersSize, 20 );//SIZE DIVISION\n      var geometry = new THREE.SphereGeometry( 0.1,32,32);\n      var material = new THREE.MeshNormalMaterial();\n      sphereO = new THREE.Mesh( geometry, material );\n\n      var materialX = new THREE.LineBasicMaterial({\n            color: 0xFF0000\n      });\n      var materialY = new THREE.LineBasicMaterial({\n            color: 0x00FF00\n      });\n      \n      var geometryX = new THREE.Geometry();\n      geometryX.vertices.push(\n            new THREE.Vector3( -5, 0, 0 ),\n            new THREE.Vector3(  5, 0, 0 )\n      );\n      var geometryY = new THREE.Geometry();\n      geometryY.vertices.push(\n            new THREE.Vector3( 0, -5, 0 ),\n            new THREE.Vector3( 0,  5, 0 )\n      );\n      \n      var lineX = new THREE.Line( geometryX, materialX );\n      var lineY = new THREE.Line( geometryY, materialY );\n\n      gridHelper.add(lineX);\n      gridHelper.add(lineY);\n      sceneSecondPass.add( gridHelper );\n      // sceneSecondPass.add( sphereO );\n      gridHelper.geometry.rotateX( Math.PI / 2 );\n      \n      updateGridHelper();\n      \n      \n      //\n      //cube renderer\n      //\n      boxGeometry = new THREE.BoxGeometry(1.0, 1.0, 1.0);\n      boxGeometry.doubleSided = true;\n\n      materialSecondPass.transparent =true;\n      var meshFirstPass = new THREE.Mesh( boxGeometry, materialFirstPass );\n      meshSecondPass = new THREE.Mesh( boxGeometry, materialSecondPass );\n\n      sceneFirstPass.add( meshFirstPass );\n      sceneSecondPass.add( meshSecondPass );\n\n      renderer = new THREE.WebGLRenderer();\n      container.appendChild( renderer.domElement );\n      renderer.setSize( win.innerWidth, win.innerHeight );\n\n\n      //\n      // mod viewer\n      //\n\n      //grab the context from your destination canvas\n      var destCtx = mod.canvas.getContext('2d');\n      destCtx.clearRect(0,0,mod.canvas.width,mod.canvas.height);\n      //call its drawImage() function passing it the source canvas directly\n      destCtx.drawImage(container.childNodes[0], 0, 0);\n\n\n      clock=new THREE.Clock();\n      //\n      //controls\n      //\n      var Controls = (function(Controls) {\n         // \"use strict\";\n      \n         // Check for double inclusion\n         if (Controls.addMouseHandler)\n            return Controls;\n      \n         Controls.addMouseHandler = function (domObject, drag, zoomIn, zoomOut) {\n            var startDragX = null,\n               startDragY = null;\n      \n            function mouseWheelHandler(e) {\n               e = window.event || e;\n               var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));\n      \n               if (delta < 0 && zoomOut) {\n                  zoomOut(delta);\n               } else if (zoomIn) {\n                  zoomIn(delta);\n               }\n      \n               e.preventDefault();\n            }\n      \n            function mouseDownHandler(e) {\n               startDragX = e.clientX;\n               startDragY = e.clientY;\n      \n               e.preventDefault();\n            }\n      \n            function mouseMoveHandler(e) {\n               if (startDragX === null || startDragY === null)\n                  return;\n      \n               if (drag)\n                  drag(e.clientX - startDragX, e.clientY - startDragY);\n      \n               startDragX = e.clientX;\n               startDragY = e.clientY;\n      \n               e.preventDefault();\n            }\n      \n            function mouseUpHandler(e) {\n               mouseMoveHandler.call(this, e);\n               startDragX = null;\n               startDragY = null;\n      \n               e.preventDefault();\n            }\n      \n            domObject.addEventListener(\"mousewheel\", mouseWheelHandler);\n            domObject.addEventListener(\"DOMMouseScroll\", mouseWheelHandler);\n            domObject.addEventListener(\"mousedown\", mouseDownHandler);\n            domObject.addEventListener(\"mousemove\", mouseMoveHandler);\n            domObject.addEventListener(\"mouseup\", mouseUpHandler);\n         };\n         return Controls;\n      }(Controls || {}));\n      Controls.addMouseHandler(renderer.domElement, drag, zoomIn, zoomOut);\n      \n\n      //\n      // event handlers\n      //\n      win.addEventListener( 'resize', onWindowResize, false );\n      win.addEventListener('contextmenu',context_menu);\n      \n      render();\n   }\n  \n   //\n   //window resize\n   //\n   function onWindowResize( event ) {\n\n      //TODO: Fix box white edge when window resize\n      renderer.setSize( win.innerWidth, win.innerHeight );\n\n      camera.aspect = win.innerWidth / win.innerHeight;\n      camera.updateProjectionMatrix();\n\n      redraw(false);\n   }\n\n   //\n   //context menu\n   //\n   function context_menu(evt) \n   {\n      evt.preventDefault();\n      evt.stopPropagation();\n      return (false);\n   }\n\n   //\n   // mouse_down\n   //\n   function mouse_down(evt) \n   { \n      evt.preventDefault();\n      evt.stopPropagation();\n      mod.button = evt.button;\n      mod.x = evt.clientX;\n      mod.y = evt.clientY;\n   }\n\n   //\n   // mouse_up\n   //\n   function mouse_up(evt) {\n      mod.button = undefined;\n      mod.x = evt.clientX;\n      mod.y = evt.clientY;\n   }\n\n   //\n   // mouse_move\n   //\n   function mouse_move(evt) \n   {\n      evt.preventDefault();\n      evt.stopPropagation();\n      var dx = evt.clientX-mod.x;\n      var dy = evt.clientY-mod.y;\n      mod.x = evt.clientX;\n      mod.y = evt.clientY;\n      if (mod.button == 0) {\n         mod.x0 += \n            Math.sin(mod.thetaz)*mod.height*dy/win.innerHeight\n            -Math.cos(mod.thetaz)*mod.width*dx/win.innerWidth;\n         mod.y0 += \n            Math.cos(mod.thetaz)*mod.height*dy/win.innerHeight\n            +Math.sin(mod.thetaz)*mod.width*dx/win.innerWidth;\n         camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n         camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n         camera.position.z = mod.r*Math.cos(mod.thetaxy);\n         camera.position.z = mod.r*Math.cos(mod.thetaxy);\n            camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0);\n            camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n         camera.updateProjectionMatrix();\n         redraw(false);\n      }\n      else if (mod.button == 2) {\n         mod.thetaxy += dy/win.innerHeight;\n         mod.thetaz += dx/win.innerWidth;\n         camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n         camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n         camera.position.z = mod.r*Math.cos(mod.thetaxy);\n            camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0);\n            camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n         camera.updateProjectionMatrix();\n            renderer.render(scene,camera);\n      }\n   }\n\n   //\n   // mouse_wheel\n   //\n   function mouse_wheel(evt) \n   {\n      evt.preventDefault();\n      evt.stopPropagation();\n      var dy = evt.deltaY/win.innerHeight;\n      mod.r += mod.height*dy;\n      camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n      camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy);\n      camera.position.z = mod.r*Math.cos(mod.thetaxy);\n      camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0));\n      camera.updateProjectionMatrix();\n      redraw(false);\n   }\n\n   //\n   //redraw\n   //\n   \n\n   function frame() \n   {\n      if (delta == 5) {\n            delta=0;\n            clearInterval(frameID);\n      } else {\n            delta++; \n            render(true,mod.steps.value*delta/5);\n      }\n   }  \n\n   function redraw(updateUniforms)\n   {\n      if(mod.rendPerformance==1)\n      {\n            if(frameID!=null)\n            {\n                  clearInterval(frameID);\n            }\n            frameID=setInterval(frame, interval);   \n      }else\n      {\n            if(frameID!=null)\n            {\n                  clearInterval(frameID);\n            }\n            render(updateUniforms,mod.steps.value);\n      }\n   }\n   mod.redraw=redraw;\n\n   function updateGridHelper()\n   {\n      //TODO: later move/rotate camera based on changes\n      //update grid helper based on limits\n      gridHelper.geometry.rotateX( - Math.PI / 2 );\n      gridHelper.scale.x=gridHelpersSize/(Math.abs(mod.xLimit2  - mod.xLimit1)*gridHelpersSize/2.0);\n      gridHelper.scale.y=gridHelpersSize/(Math.abs(mod.yLimit2  - mod.yLimit1)*gridHelpersSize/2.0);\n      gridHelper.position.x=( (0.0 - (mod.xLimit1)) * (0.5  - (-0.5)) / (mod.xLimit2 - (mod.xLimit1)) + (-0.5));\n      gridHelper.position.y=( (0.0 - (mod.yLimit1)) * (0.5  - (-0.5)) / (mod.yLimit2 - (mod.yLimit1)) + (-0.5));\n      gridHelper.position.z=( (0.0 - (mod.zLimit1)) * (0.5  - (-0.5)) / (mod.zLimit2 - (mod.zLimit1)) + (-0.5));\n      gridHelper.geometry.rotateX( Math.PI / 2 );\n      \n      sphereO.scale.x=gridHelpersSize/(Math.abs(mod.xLimit2  - mod.xLimit1)*gridHelpersSize/0.5);\n      sphereO.scale.y=gridHelpersSize/(Math.abs(mod.yLimit2  - mod.yLimit1)*gridHelpersSize/0.5);\n      sphereO.scale.z=gridHelpersSize/(Math.abs(mod.zLimit2  - mod.zLimit1)*gridHelpersSize/0.5);\n     \n      sphereO.position.x=( (0.0 - (mod.xLimit1)) * (0.5  - (-0.5)) / (mod.xLimit2 - (mod.xLimit1)) + (-0.5));\n      sphereO.position.y=( (0.0 - (mod.yLimit1)) * (0.5  - (-0.5)) / (mod.yLimit2 - (mod.yLimit1)) + (-0.5));\n      sphereO.position.z=( (0.0 - (mod.zLimit1)) * (0.5  - (-0.5)) / (mod.zLimit2 - (mod.zLimit1)) + (-0.5));\n   }\n\n   //\n   //render\n   //\n   function render(updateUniforms ,resolutionStep) {\n      if(updateUniforms)\n      {\n            \n            materialSecondPass.uniforms.steps.value = resolutionStep;\n            materialSecondPass.uniforms.alphaCorrection.value = mod.alphaCorrection;\n            materialSecondPass.uniforms.xLimit1.value =mod.xLimit1 ;\n            materialSecondPass.uniforms.xLimit2.value =mod.xLimit2 ; \n            materialSecondPass.uniforms.yLimit1.value =mod.yLimit1 ; \n            materialSecondPass.uniforms.yLimit2.value =mod.yLimit2 ; \n            materialSecondPass.uniforms.zLimit1.value =mod.zLimit1 ; \n            materialSecondPass.uniforms.zLimit2.value =mod.zLimit2 ;\n\n\n            //TODO: Find the error with xray and fix it\n            if(mod.rendType=='1')//xray\n            {\n                  materialSecondPass.transparent =false;\n            }else\n            {\n                  materialSecondPass.transparent =true;\n            }\n\n            updateGridHelper();\n      }\n\n      var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n\n      materialSecondPass.uniforms.cameraPos.value=tempCam.normalize();\n      tempCam.normalize();\n      tempCam.addScalar(0.5);\n\n      //Render first pass and store the world space coords of the back face fragments into the texture.\n      //renderer.render( sceneFirstPass, camera, rtTexture, true );\n\n      //Render the second pass and perform the volume rendering.\n      //renderer.render( sceneSecondPass, camera );\n\n      var previousRenderTarget = renderer.getRenderTarget();\n\t  renderer.setRenderTarget(rtTexture);\n\t  renderer.render( sceneFirstPass, camera );\n\t  renderer.setRenderTarget( previousRenderTarget );\n\t  renderer.render( sceneSecondPass, camera );\n\n      //render axes camera\n      cameraAxes.position.x=camera.position.x;\n      cameraAxes.position.y=camera.position.y;\n      cameraAxes.position.z=camera.position.z;\n\tcameraAxes.position.sub( center ); \n\tcameraAxes.position.setLength( 300 );\n      cameraAxes.lookAt( sceneAxes.position.clone() );  \n\n      rendererAxes.render( sceneAxes, cameraAxes );\n\n      updateModViewer();\n      \n   }\n\n   //\n   //render to small mod viewer\n   //\n   function updateModViewer()\n   {\n      var w=win.innerWidth;\n      var h=win.innerHeight;\n      if (w > h) {\n         var x0 = 0;\n         var y0 = mod.canvas.height*.5*(1-h/w);\n         var wd = mod.canvas.width;\n         var hd = mod.canvas.width*h/w;\n         }\n       else {\n         var x0 = mod.canvas.width*.5*(1-w/h);\n         var y0 = 0;\n         var wd = mod.canvas.height*w/h;\n         var hd = mod.canvas.height;\n         }\n      var destCtx = mod.canvas.getContext('2d');\n      destCtx.drawImage(container.childNodes[0],x0,y0,wd,hd);\n\n   }\n\n   //\n   //when fuction changes\n   //\n   function updateShaderFunction()\n   {\n      // outputs.messageLog.event('update shader');\n      \n      // outputs.messageLog.event(mod.xLimit1);\n\n      var div = document.getElementById('fragmentShaderSecondPass');\n\n      div.innerHTML=\"\";\n      div.innerHTML =fragmentShaderSecondPass();\n      \n      var tempCam=new THREE.Vector3(camera.position.x,camera.position.y,camera.position.z);\n      // outputs.messageLog.event('update shader1');\n      materialSecondPass = new THREE.ShaderMaterial( {\n         vertexShader: document.getElementById( 'vertexShaderSecondPass' ).textContent,\n         fragmentShader: document.getElementById( 'fragmentShaderSecondPass' ).textContent,\n         side: THREE.FrontSide,\n         uniforms: { tex:  { type: \"t\", value: rtTexture },\n                  steps : {type: \"1f\" , value: mod.steps.value }, \n                  xLimit1 : {type: \"1f\" , value: mod.xLimit1 }, \n                  xLimit2 : {type: \"1f\" , value: mod.xLimit2 }, \n                  yLimit1 : {type: \"1f\" , value: mod.yLimit1 }, \n                  yLimit2 : {type: \"1f\" , value: mod.yLimit2 }, \n                  zLimit1 : {type: \"1f\" , value: mod.zLimit1 }, \n                  zLimit2 : {type: \"1f\" , value: mod.zLimit2 }, \n                  alphaCorrection : {type: \"1f\" , value: mod.alphaCorrection},\n                  cameraPos :{value: tempCam.normalize()}\n               }\n         });\n\n      //new THREE.Vector3(20.0,-60.0,-40.0)\n      meshSecondPass.material=materialSecondPass;\n      meshSecondPass.material.needsUpdate = true;\n      meshSecondPass.material.transparent =true;\n\n      redraw(true);\n\n      //test performance\n      // mod.tend = Date.now();\n      // var dt = mod.tend-mod.tstart;\n      // outputs.messageLog.event(dt/1000);\n\n   }\n   mod.updateShaderFunction=updateShaderFunction;\n      \n      //\n      //controls\n      //\n      function drag(deltaX, deltaY) \n      {\n            var radPerPixel = (Math.PI / 450),\n            deltaPhi = radPerPixel * deltaX,\n            deltaTheta = radPerPixel * deltaY,\n            pos = camera.position.sub(center),\n            radius = pos.length(),\n            theta = Math.acos(pos.z / radius),\n            phi = Math.atan2(pos.y, pos.x);\n\n            // Subtract deltaTheta and deltaPhi\n            theta = Math.min(Math.max(theta - deltaTheta, 0), Math.PI);\n            phi -= deltaPhi;\n\n            // Turn back into Cartesian coordinates\n            pos.x = radius * Math.sin(theta) * Math.cos(phi);\n            pos.y = radius * Math.sin(theta) * Math.sin(phi);\n            pos.z = radius * Math.cos(theta);\n\n            camera.position.add(center);\n            camera.lookAt(center);\n            redraw(false);\n      }\n\n      ///\n      function zoomIn() \n      {\n            camera.position.sub(center).multiplyScalar(0.9).add(center);\n            redraw(false);\n      }\n\n      ///\n      function zoomOut() \n      {\n            camera.position.sub(center).multiplyScalar(1.1).add(center);\n            redraw(false);\n      }\n}\n\n//\n// return values\n//\nreturn ({\n   mod:mod,\n   name:name,\n   init:init,\n   inputs:inputs,\n   outputs:outputs,\n   interface:interface\n   });\n}());\n\n\n","top":"570","left":"1948","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.12657158898021215\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.4470203423781617\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.16851711510462064\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5368438375786873\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.4470203423781617\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5368438375786873\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5368438375786873\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.11959522713811777\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3914434415667569\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out0\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.12657158898021215\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3914434415667569\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out0\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.16851711510462064\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.11959522713811777\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8062301007085344\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}"]}