Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
mods
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
mods
Commits
54bb114c
Commit
54bb114c
authored
Jun 17, 2019
by
Amira Abdel-Rahman
Browse files
Options
Downloads
Patches
Plain Diff
Update lattice torus
parent
44234045
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
programs/frep/lattice torus
+1
-1
1 addition, 1 deletion
programs/frep/lattice torus
with
1 addition
and
1 deletion
programs/frep/lattice torus
+
1
−
1
View file @
54bb114c
{"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":"203","left":"400","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":"322","left":"685","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":"219","left":"985","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":"524","left":"397","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":"560","left":"941","inputs":{},"outputs":{}},"0.6024752654100127":{"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.AxisHelper( 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 //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":"354.16705904759533","left":"1442.3402838017123","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":"334.7831800789872","left":"-2.747276618468625","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.11959522713811777\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.6024752654100127\\\",\\\"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\\\"}\"}"]}
\ No newline at end of file
{"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\\\"}\"}"]}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment